From: Tao Ren <[email protected]>
The patch series aims at enabling USB Host and Gadget support on AST2600
platforms.
Patch #1 includes vhub's usb descriptors in struct "ast_vhub": all usb
descriptor changes will go to the per-vhub instance instead of touching
the global default descriptors.
Patch #2 replaces hardcoded vhub port/endpoint number with device tree
properties, so that it's more convenient to add support for ast2600-vhub
which provides more downstream ports and endpoints.
Patch #3 enables ast2600 support in aspeed-vhub usb gadget driver.
Patch #4 adds USB devices and according pin groups in aspeed-g6 dtsi.
Patch #5 and #6 add vhub port/endpoint properties into aspeed-g4 and
aspeed-g5 dtsi.
Patch #7 adds device tree binding document for aspeed usb-vhub driver.
Tao Ren (7):
usb: gadget: aspeed: support per-vhub usb descriptors
usb: gadget: aspeed: read vhub properties from device tree
usb: gadget: aspeed: add ast2600 vhub support
ARM: dts: aspeed-g6: add usb functions
ARM: dts: aspeed-g5: add vhub port and endpoint properties
ARM: dts: aspeed-g4: add vhub port and endpoint properties
dt-bindings: usb: add documentation for aspeed usb-vhub
.../bindings/usb/aspeed,usb-vhub.yaml | 71 +++++++++++++++++++
arch/arm/boot/dts/aspeed-g4.dtsi | 2 +
arch/arm/boot/dts/aspeed-g5.dtsi | 2 +
arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi | 25 +++++++
arch/arm/boot/dts/aspeed-g6.dtsi | 45 ++++++++++++
drivers/usb/gadget/udc/aspeed-vhub/Kconfig | 4 +-
drivers/usb/gadget/udc/aspeed-vhub/core.c | 71 ++++++++++++-------
drivers/usb/gadget/udc/aspeed-vhub/dev.c | 30 +++++---
drivers/usb/gadget/udc/aspeed-vhub/epn.c | 4 +-
drivers/usb/gadget/udc/aspeed-vhub/hub.c | 58 ++++++++++-----
drivers/usb/gadget/udc/aspeed-vhub/vhub.h | 43 +++++++----
11 files changed, 284 insertions(+), 71 deletions(-)
create mode 100644 Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml
--
2.17.1
From: Tao Ren <[email protected]>
This patch store vhub's standard usb descriptors in struct "ast_vhub" so
it's more convenient to customize descriptors and potentially support
multiple vhub instances in the future.
Signed-off-by: Tao Ren <[email protected]>
---
No change in v2/v3/v4:
- the patch is added to the patch series since v4.
drivers/usb/gadget/udc/aspeed-vhub/hub.c | 43 ++++++++++++++++-------
drivers/usb/gadget/udc/aspeed-vhub/vhub.h | 15 ++++++++
2 files changed, 46 insertions(+), 12 deletions(-)
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/hub.c b/drivers/usb/gadget/udc/aspeed-vhub/hub.c
index 19b3517e04c0..9c3027306b15 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/hub.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/hub.c
@@ -93,11 +93,7 @@ static void ast_vhub_patch_dev_desc_usb1(struct usb_device_descriptor *desc)
USB_DT_INTERFACE_SIZE + \
USB_DT_ENDPOINT_SIZE)
-static const struct ast_vhub_full_cdesc {
- struct usb_config_descriptor cfg;
- struct usb_interface_descriptor intf;
- struct usb_endpoint_descriptor ep;
-} __attribute__ ((packed)) ast_vhub_conf_desc = {
+static const struct ast_vhub_full_cdesc ast_vhub_conf_desc = {
.cfg = {
.bLength = USB_DT_CONFIG_SIZE,
.bDescriptorType = USB_DT_CONFIG,
@@ -266,6 +262,7 @@ static int ast_vhub_rep_desc(struct ast_vhub_ep *ep,
u8 desc_type, u16 len)
{
size_t dsize;
+ struct ast_vhub *vhub = ep->vhub;
EPDBG(ep, "GET_DESCRIPTOR(type:%d)\n", desc_type);
@@ -281,20 +278,20 @@ static int ast_vhub_rep_desc(struct ast_vhub_ep *ep,
switch(desc_type) {
case USB_DT_DEVICE:
dsize = USB_DT_DEVICE_SIZE;
- memcpy(ep->buf, &ast_vhub_dev_desc, dsize);
- BUILD_BUG_ON(dsize > sizeof(ast_vhub_dev_desc));
+ memcpy(ep->buf, &vhub->vhub_dev_desc, dsize);
+ BUILD_BUG_ON(dsize > sizeof(vhub->vhub_dev_desc));
BUILD_BUG_ON(USB_DT_DEVICE_SIZE >= AST_VHUB_EP0_MAX_PACKET);
break;
case USB_DT_CONFIG:
dsize = AST_VHUB_CONF_DESC_SIZE;
- memcpy(ep->buf, &ast_vhub_conf_desc, dsize);
- BUILD_BUG_ON(dsize > sizeof(ast_vhub_conf_desc));
+ memcpy(ep->buf, &vhub->vhub_conf_desc, dsize);
+ BUILD_BUG_ON(dsize > sizeof(vhub->vhub_conf_desc));
BUILD_BUG_ON(AST_VHUB_CONF_DESC_SIZE >= AST_VHUB_EP0_MAX_PACKET);
break;
case USB_DT_HUB:
dsize = AST_VHUB_HUB_DESC_SIZE;
- memcpy(ep->buf, &ast_vhub_hub_desc, dsize);
- BUILD_BUG_ON(dsize > sizeof(ast_vhub_hub_desc));
+ memcpy(ep->buf, &vhub->vhub_hub_desc, dsize);
+ BUILD_BUG_ON(dsize > sizeof(vhub->vhub_hub_desc));
BUILD_BUG_ON(AST_VHUB_HUB_DESC_SIZE >= AST_VHUB_EP0_MAX_PACKET);
break;
default:
@@ -317,7 +314,8 @@ static int ast_vhub_rep_string(struct ast_vhub_ep *ep,
u8 string_id, u16 lang_id,
u16 len)
{
- int rc = usb_gadget_get_string (&ast_vhub_strings, string_id, ep->buf);
+ int rc = usb_gadget_get_string(&ep->vhub->vhub_str_desc,
+ string_id, ep->buf);
/*
* This should never happen unless we put too big strings in
@@ -834,9 +832,30 @@ void ast_vhub_hub_reset(struct ast_vhub *vhub)
writel(0, vhub->regs + AST_VHUB_EP1_STS_CHG);
}
+static void ast_vhub_init_desc(struct ast_vhub *vhub)
+{
+ /* Initialize vhub Device Descriptor. */
+ memcpy(&vhub->vhub_dev_desc, &ast_vhub_dev_desc,
+ sizeof(vhub->vhub_dev_desc));
+
+ /* Initialize vhub Configuration Descriptor. */
+ memcpy(&vhub->vhub_conf_desc, &ast_vhub_conf_desc,
+ sizeof(vhub->vhub_conf_desc));
+
+ /* Initialize vhub Hub Descriptor. */
+ memcpy(&vhub->vhub_hub_desc, &ast_vhub_hub_desc,
+ sizeof(vhub->vhub_hub_desc));
+
+ /* Initialize vhub String Descriptors. */
+ memcpy(&vhub->vhub_str_desc, &ast_vhub_strings,
+ sizeof(vhub->vhub_str_desc));
+}
+
void ast_vhub_init_hub(struct ast_vhub *vhub)
{
vhub->speed = USB_SPEED_UNKNOWN;
INIT_WORK(&vhub->wake_work, ast_vhub_wake_work);
+
+ ast_vhub_init_desc(vhub);
}
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
index 761919e220d3..191f9fae7420 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
+++ b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
@@ -2,6 +2,9 @@
#ifndef __ASPEED_VHUB_H
#define __ASPEED_VHUB_H
+#include <linux/usb.h>
+#include <linux/usb/ch11.h>
+
/*****************************
* *
* VHUB register definitions *
@@ -373,6 +376,12 @@ struct ast_vhub_port {
struct ast_vhub_dev dev;
};
+struct ast_vhub_full_cdesc {
+ struct usb_config_descriptor cfg;
+ struct usb_interface_descriptor intf;
+ struct usb_endpoint_descriptor ep;
+} __packed;
+
/* Global vhub structure */
struct ast_vhub {
struct platform_device *pdev;
@@ -409,6 +418,12 @@ struct ast_vhub {
/* Upstream bus speed captured at bus reset */
unsigned int speed;
+
+ /* Standard USB Descriptors of the vhub. */
+ struct usb_device_descriptor vhub_dev_desc;
+ struct ast_vhub_full_cdesc vhub_conf_desc;
+ struct usb_hub_descriptor vhub_hub_desc;
+ struct usb_gadget_strings vhub_str_desc;
};
/* Standard request handlers result codes */
--
2.17.1
From: Tao Ren <[email protected]>
Add AST2600 support in aspeed-vhub driver. There are 3 major differences
between AST2500 and AST2600 vhub:
- AST2600 supports 7 downstream ports while AST2500 supports 5.
- AST2600 supports 21 generic endpoints while AST2500 supports 15.
- EP0 data buffer's 8-byte DMA alignment restriction is removed from
AST2600.
Signed-off-by: Tao Ren <[email protected]>
Reviewed-by: Andrew Jeffery <[email protected]>
---
No Change in v3/v4.
Changes in v2:
- removed "ast_vhub_config" related logic.
drivers/usb/gadget/udc/aspeed-vhub/Kconfig | 4 ++--
drivers/usb/gadget/udc/aspeed-vhub/core.c | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/Kconfig b/drivers/usb/gadget/udc/aspeed-vhub/Kconfig
index 83ba8a2eb6af..605500b19cf3 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/Kconfig
+++ b/drivers/usb/gadget/udc/aspeed-vhub/Kconfig
@@ -4,5 +4,5 @@ config USB_ASPEED_VHUB
depends on ARCH_ASPEED || COMPILE_TEST
depends on USB_LIBCOMPOSITE
help
- USB peripheral controller for the Aspeed AST2500 family
- SoCs supporting the "vHub" functionality and USB2.0
+ USB peripheral controller for the Aspeed AST2400, AST2500 and
+ AST2600 family SoCs supporting the "vHub" functionality and USB2.0
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/core.c b/drivers/usb/gadget/udc/aspeed-vhub/core.c
index f8ab8e012f34..f8d35dd60c34 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/core.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/core.c
@@ -423,6 +423,9 @@ static const struct of_device_id ast_vhub_dt_ids[] = {
{
.compatible = "aspeed,ast2500-usb-vhub",
},
+ {
+ .compatible = "aspeed,ast2600-usb-vhub",
+ },
{ }
};
MODULE_DEVICE_TABLE(of, ast_vhub_dt_ids);
--
2.17.1
From: Tao Ren <[email protected]>
Add "aspeed,vhub-downstream-ports" and "aspeed,vhub-generic-endpoints"
properties to describe supported number of vhub ports and endpoints.
Signed-off-by: Tao Ren <[email protected]>
---
No change in v2/v3/v4.
- It's given v4 to align with the version of the patch series.
arch/arm/boot/dts/aspeed-g4.dtsi | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi
index 807a0fc20670..8e04303e8514 100644
--- a/arch/arm/boot/dts/aspeed-g4.dtsi
+++ b/arch/arm/boot/dts/aspeed-g4.dtsi
@@ -164,6 +164,8 @@
reg = <0x1e6a0000 0x300>;
interrupts = <5>;
clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
+ aspeed,vhub-downstream-ports = <5>;
+ aspeed,vhub-generic-endpoints = <15>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb2d_default>;
status = "disabled";
--
2.17.1
From: Tao Ren <[email protected]>
Add "aspeed,vhub-downstream-ports" and "aspeed,vhub-generic-endpoints"
properties to describe supported number of vhub ports and endpoints.
Signed-off-by: Tao Ren <[email protected]>
---
No change in v2/v3/v4.
- It's given v4 to align with the version of the patch series.
arch/arm/boot/dts/aspeed-g5.dtsi | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index ebec0fa8baa7..f12ec04d3cbc 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -195,6 +195,8 @@
reg = <0x1e6a0000 0x300>;
interrupts = <5>;
clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
+ aspeed,vhub-downstream-ports = <5>;
+ aspeed,vhub-generic-endpoints = <15>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb2ad_default>;
status = "disabled";
--
2.17.1
From: Tao Ren <[email protected]>
Add device tree binding documentation for aspeed usb-vhub driver.
Signed-off-by: Tao Ren <[email protected]>
---
No change in v2/v3/v4:
- the patch is added to the patch series since v4.
.../bindings/usb/aspeed,usb-vhub.yaml | 71 +++++++++++++++++++
1 file changed, 71 insertions(+)
create mode 100644 Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml
diff --git a/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml b/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml
new file mode 100644
index 000000000000..6ebae46641e5
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2020 Facebook Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/aspeed,usb-vhub.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED USB 2.0 Virtual Hub Controller
+
+maintainers:
+ - Felipe Balbi <[email protected]>
+
+description: |+
+ The ASPEED USB 2.0 Virtual Hub Controller implements 1 set of USB Hub
+ register and several sets of Device and Endpoint registers to support
+ the Virtual Hub's downstream USB devices.
+
+ Supported number of devices and endpoints vary depending on hardware
+ revisions. AST2400 and AST2500 Virtual Hub supports 5 downstream devices
+ and 15 generic endpoints, while AST2600 Virtual Hub supports 7 downstream
+ devices and 21 generic endpoints.
+
+properties:
+ compatible:
+ enum:
+ - aspeed,ast2400-usb-vhub
+ - aspeed,ast2500-usb-vhub
+ - aspeed,ast2600-usb-vhub
+
+ reg:
+ maxItems: 1
+ description: Common configuration registers
+
+ clocks:
+ maxItems: 1
+ description: The Virtual Hub Controller clock gate
+
+ interrupts:
+ maxItems: 1
+
+ aspeed,vhub-downstream-ports:
+ description: Number of downstream ports supported by the Virtual Hub
+ allOf:
+ - $ref: /schemas/types.yaml#/definitions/uint32
+
+ aspeed,vhub-generic-endpoints:
+ description: Number of generic endpoints supported by the Virtual Hub
+ allOf:
+ - $ref: /schemas/types.yaml#/definitions/uint32
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - interrupts
+ - aspeed,vhub-downstream-ports
+ - aspeed,vhub-generic-endpoints
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/aspeed-clock.h>
+ vhub: usb-vhub@1e6a0000 {
+ compatible = "aspeed,ast2500-usb-vhub";
+ reg = <0x1e6a0000 0x300>;
+ interrupts = <5>;
+ clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb2ad_default>;
+ };
--
2.17.1
From: Tao Ren <[email protected]>
Add USB components and according pin groups in aspeed-g6 dtsi.
Signed-off-by: Tao Ren <[email protected]>
Reviewed-by: Andrew Jeffery <[email protected]>
---
No change in v3/v4.
Changes in v2:
- added port/endpoint properties for vhub dt node.
arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi | 25 +++++++++++++
arch/arm/boot/dts/aspeed-g6.dtsi | 45 ++++++++++++++++++++++++
2 files changed, 70 insertions(+)
diff --git a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
index 045ce66ca876..7028e21bdd98 100644
--- a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
@@ -1112,6 +1112,31 @@
groups = "UART9";
};
+ pinctrl_usb2ah_default: usb2ah_default {
+ function = "USB2AH";
+ groups = "USBA";
+ };
+
+ pinctrl_usb2ad_default: usb2ad_default {
+ function = "USB2AD";
+ groups = "USBA";
+ };
+
+ pinctrl_usb2bh_default: usb2bh_default {
+ function = "USB2BH";
+ groups = "USBB";
+ };
+
+ pinctrl_usb2bd_default: usb2bd_default {
+ function = "USB2BD";
+ groups = "USBB";
+ };
+
+ pinctrl_usb11bhid_default: usb11bhid_default {
+ function = "USB11BHID";
+ groups = "USBB";
+ };
+
pinctrl_vb_default: vb_default {
function = "VB";
groups = "VB";
diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
index 796976d275e1..0a29b3b57a9d 100644
--- a/arch/arm/boot/dts/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6.dtsi
@@ -245,6 +245,51 @@
status = "disabled";
};
+ ehci0: usb@1e6a1000 {
+ compatible = "aspeed,ast2600-ehci", "generic-ehci";
+ reg = <0x1e6a1000 0x100>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb2ah_default>;
+ status = "disabled";
+ };
+
+ ehci1: usb@1e6a3000 {
+ compatible = "aspeed,ast2600-ehci", "generic-ehci";
+ reg = <0x1e6a3000 0x100>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&syscon ASPEED_CLK_GATE_USBPORT2CLK>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb2bh_default>;
+ status = "disabled";
+ };
+
+ uhci: usb@1e6b0000 {
+ compatible = "aspeed,ast2600-uhci", "generic-uhci";
+ reg = <0x1e6b0000 0x100>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ #ports = <2>;
+ clocks = <&syscon ASPEED_CLK_GATE_USBUHCICLK>;
+ status = "disabled";
+ /*
+ * No default pinmux, it will follow EHCI, use an
+ * explicit pinmux override if EHCI is not enabled.
+ */
+ };
+
+ vhub: usb-vhub@1e6a0000 {
+ compatible = "aspeed,ast2600-usb-vhub";
+ reg = <0x1e6a0000 0x350>;
+ interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
+ aspeed,vhub-downstream-ports = <7>;
+ aspeed,vhub-generic-endpoints = <21>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb2ad_default>;
+ status = "disabled";
+ };
+
apb {
compatible = "simple-bus";
#address-cells = <1>;
--
2.17.1
From: Tao Ren <[email protected]>
The patch introduces 2 DT properties ("aspeed,vhub-downstream-ports" and
"aspeed,vhub-generic-endpoints") which replaces hardcoded port/endpoint
number. It is to make it more convenient to add support for newer vhub
revisions with different number of ports and endpoints.
Signed-off-by: Tao Ren <[email protected]>
Reviewed-by: Joel Stanley <[email protected]>
---
Changes in v4:
- use NUM_PORTS/NUM_GEN_EPs defined in vhub.h instead of introducing
new constants (in v3).
Changes in v3:
- fall back to "default" number of ports and endpoints to avoid
breaking existing ast2400/ast2500 platforms when according device
tree properties are not defined.
Changes in v2:
- removed ast_vhub_config structure and moved vhub port/endpoint
number into device tree.
drivers/usb/gadget/udc/aspeed-vhub/core.c | 68 ++++++++++++++---------
drivers/usb/gadget/udc/aspeed-vhub/dev.c | 30 +++++++---
drivers/usb/gadget/udc/aspeed-vhub/epn.c | 4 +-
drivers/usb/gadget/udc/aspeed-vhub/hub.c | 15 ++---
drivers/usb/gadget/udc/aspeed-vhub/vhub.h | 28 +++++-----
5 files changed, 88 insertions(+), 57 deletions(-)
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/core.c b/drivers/usb/gadget/udc/aspeed-vhub/core.c
index 90b134d5dca9..f8ab8e012f34 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/core.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/core.c
@@ -99,7 +99,7 @@ static irqreturn_t ast_vhub_irq(int irq, void *data)
{
struct ast_vhub *vhub = data;
irqreturn_t iret = IRQ_NONE;
- u32 istat;
+ u32 i, istat;
/* Stale interrupt while tearing down */
if (!vhub->ep0_bufs)
@@ -121,10 +121,10 @@ static irqreturn_t ast_vhub_irq(int irq, void *data)
/* Handle generic EPs first */
if (istat & VHUB_IRQ_EP_POOL_ACK_STALL) {
- u32 i, ep_acks = readl(vhub->regs + AST_VHUB_EP_ACK_ISR);
+ u32 ep_acks = readl(vhub->regs + AST_VHUB_EP_ACK_ISR);
writel(ep_acks, vhub->regs + AST_VHUB_EP_ACK_ISR);
- for (i = 0; ep_acks && i < AST_VHUB_NUM_GEN_EPs; i++) {
+ for (i = 0; ep_acks && i < vhub->max_epns; i++) {
u32 mask = VHUB_EP_IRQ(i);
if (ep_acks & mask) {
ast_vhub_epn_ack_irq(&vhub->epns[i]);
@@ -134,21 +134,11 @@ static irqreturn_t ast_vhub_irq(int irq, void *data)
}
/* Handle device interrupts */
- if (istat & (VHUB_IRQ_DEVICE1 |
- VHUB_IRQ_DEVICE2 |
- VHUB_IRQ_DEVICE3 |
- VHUB_IRQ_DEVICE4 |
- VHUB_IRQ_DEVICE5)) {
- if (istat & VHUB_IRQ_DEVICE1)
- ast_vhub_dev_irq(&vhub->ports[0].dev);
- if (istat & VHUB_IRQ_DEVICE2)
- ast_vhub_dev_irq(&vhub->ports[1].dev);
- if (istat & VHUB_IRQ_DEVICE3)
- ast_vhub_dev_irq(&vhub->ports[2].dev);
- if (istat & VHUB_IRQ_DEVICE4)
- ast_vhub_dev_irq(&vhub->ports[3].dev);
- if (istat & VHUB_IRQ_DEVICE5)
- ast_vhub_dev_irq(&vhub->ports[4].dev);
+ for (i = 0; i < vhub->max_ports; i++) {
+ u32 dev_mask = VHUB_IRQ_DEVICE1 << i;
+
+ if (istat & dev_mask)
+ ast_vhub_dev_irq(&vhub->ports[i].dev);
}
/* Handle top-level vHub EP0 interrupts */
@@ -182,7 +172,7 @@ static irqreturn_t ast_vhub_irq(int irq, void *data)
void ast_vhub_init_hw(struct ast_vhub *vhub)
{
- u32 ctrl;
+ u32 ctrl, port_mask, epn_mask;
UDCDBG(vhub,"(Re)Starting HW ...\n");
@@ -222,15 +212,20 @@ void ast_vhub_init_hw(struct ast_vhub *vhub)
}
/* Reset all devices */
- writel(VHUB_SW_RESET_ALL, vhub->regs + AST_VHUB_SW_RESET);
+ port_mask = GENMASK(vhub->max_ports, 1);
+ writel(VHUB_SW_RESET_ROOT_HUB |
+ VHUB_SW_RESET_DMA_CONTROLLER |
+ VHUB_SW_RESET_EP_POOL |
+ port_mask, vhub->regs + AST_VHUB_SW_RESET);
udelay(1);
writel(0, vhub->regs + AST_VHUB_SW_RESET);
/* Disable and cleanup EP ACK/NACK interrupts */
+ epn_mask = GENMASK(vhub->max_epns - 1, 0);
writel(0, vhub->regs + AST_VHUB_EP_ACK_IER);
writel(0, vhub->regs + AST_VHUB_EP_NACK_IER);
- writel(VHUB_EP_IRQ_ALL, vhub->regs + AST_VHUB_EP_ACK_ISR);
- writel(VHUB_EP_IRQ_ALL, vhub->regs + AST_VHUB_EP_NACK_ISR);
+ writel(epn_mask, vhub->regs + AST_VHUB_EP_ACK_ISR);
+ writel(epn_mask, vhub->regs + AST_VHUB_EP_NACK_ISR);
/* Default settings for EP0, enable HW hub EP1 */
writel(0, vhub->regs + AST_VHUB_EP0_CTRL);
@@ -273,7 +268,7 @@ static int ast_vhub_remove(struct platform_device *pdev)
return 0;
/* Remove devices */
- for (i = 0; i < AST_VHUB_NUM_PORTS; i++)
+ for (i = 0; i < vhub->max_ports; i++)
ast_vhub_del_dev(&vhub->ports[i].dev);
spin_lock_irqsave(&vhub->lock, flags);
@@ -295,7 +290,7 @@ static int ast_vhub_remove(struct platform_device *pdev)
if (vhub->ep0_bufs)
dma_free_coherent(&pdev->dev,
AST_VHUB_EP0_MAX_PACKET *
- (AST_VHUB_NUM_PORTS + 1),
+ (vhub->max_ports + 1),
vhub->ep0_bufs,
vhub->ep0_bufs_dma);
vhub->ep0_bufs = NULL;
@@ -309,11 +304,32 @@ static int ast_vhub_probe(struct platform_device *pdev)
struct ast_vhub *vhub;
struct resource *res;
int i, rc = 0;
+ const struct device_node *np = pdev->dev.of_node;
vhub = devm_kzalloc(&pdev->dev, sizeof(*vhub), GFP_KERNEL);
if (!vhub)
return -ENOMEM;
+ rc = of_property_read_u32(np, "aspeed,vhub-downstream-ports",
+ &vhub->max_ports);
+ if (rc < 0)
+ vhub->max_ports = AST_VHUB_NUM_PORTS;
+
+ vhub->ports = devm_kcalloc(&pdev->dev, vhub->max_ports,
+ sizeof(*vhub->ports), GFP_KERNEL);
+ if (!vhub->ports)
+ return -ENOMEM;
+
+ rc = of_property_read_u32(np, "aspeed,vhub-generic-endpoints",
+ &vhub->max_epns);
+ if (rc < 0)
+ vhub->max_epns = AST_VHUB_NUM_GEN_EPs;
+
+ vhub->epns = devm_kcalloc(&pdev->dev, vhub->max_epns,
+ sizeof(*vhub->epns), GFP_KERNEL);
+ if (!vhub->epns)
+ return -ENOMEM;
+
spin_lock_init(&vhub->lock);
vhub->pdev = pdev;
@@ -366,7 +382,7 @@ static int ast_vhub_probe(struct platform_device *pdev)
*/
vhub->ep0_bufs = dma_alloc_coherent(&pdev->dev,
AST_VHUB_EP0_MAX_PACKET *
- (AST_VHUB_NUM_PORTS + 1),
+ (vhub->max_ports + 1),
&vhub->ep0_bufs_dma, GFP_KERNEL);
if (!vhub->ep0_bufs) {
dev_err(&pdev->dev, "Failed to allocate EP0 DMA buffers\n");
@@ -380,7 +396,7 @@ static int ast_vhub_probe(struct platform_device *pdev)
ast_vhub_init_ep0(vhub, &vhub->ep0, NULL);
/* Init devices */
- for (i = 0; i < AST_VHUB_NUM_PORTS && rc == 0; i++)
+ for (i = 0; i < vhub->max_ports && rc == 0; i++)
rc = ast_vhub_init_dev(vhub, i);
if (rc)
goto err;
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/dev.c b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
index 4008e7a51188..d268306a7bfe 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/dev.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
@@ -77,7 +77,7 @@ static void ast_vhub_dev_enable(struct ast_vhub_dev *d)
writel(d->ep0.buf_dma, d->regs + AST_VHUB_DEV_EP0_DATA);
/* Clear stall on all EPs */
- for (i = 0; i < AST_VHUB_NUM_GEN_EPs; i++) {
+ for (i = 0; i < d->max_epns; i++) {
struct ast_vhub_ep *ep = d->epns[i];
if (ep && (ep->epn.stalled || ep->epn.wedged)) {
@@ -137,7 +137,7 @@ static int ast_vhub_ep_feature(struct ast_vhub_dev *d,
is_set ? "SET" : "CLEAR", ep_num, wValue);
if (ep_num == 0)
return std_req_complete;
- if (ep_num >= AST_VHUB_NUM_GEN_EPs || !d->epns[ep_num - 1])
+ if (ep_num >= d->max_epns || !d->epns[ep_num - 1])
return std_req_stall;
if (wValue != USB_ENDPOINT_HALT)
return std_req_driver;
@@ -181,7 +181,7 @@ static int ast_vhub_ep_status(struct ast_vhub_dev *d,
DDBG(d, "GET_STATUS(ep%d)\n", ep_num);
- if (ep_num >= AST_VHUB_NUM_GEN_EPs)
+ if (ep_num >= d->max_epns)
return std_req_stall;
if (ep_num != 0) {
ep = d->epns[ep_num - 1];
@@ -299,7 +299,7 @@ static void ast_vhub_dev_nuke(struct ast_vhub_dev *d)
{
unsigned int i;
- for (i = 0; i < AST_VHUB_NUM_GEN_EPs; i++) {
+ for (i = 0; i < d->max_epns; i++) {
if (!d->epns[i])
continue;
ast_vhub_nuke(d->epns[i], -ESHUTDOWN);
@@ -416,10 +416,10 @@ static struct usb_ep *ast_vhub_udc_match_ep(struct usb_gadget *gadget,
* that will allow the generic code to use our
* assigned address.
*/
- for (i = 0; i < AST_VHUB_NUM_GEN_EPs; i++)
+ for (i = 0; i < d->max_epns; i++)
if (d->epns[i] == NULL)
break;
- if (i >= AST_VHUB_NUM_GEN_EPs)
+ if (i >= d->max_epns)
return NULL;
addr = i + 1;
@@ -526,6 +526,7 @@ void ast_vhub_del_dev(struct ast_vhub_dev *d)
usb_del_gadget_udc(&d->gadget);
device_unregister(d->port_dev);
+ kfree(d->epns);
}
static void ast_vhub_dev_release(struct device *dev)
@@ -546,14 +547,25 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
ast_vhub_init_ep0(vhub, &d->ep0, d);
+ /*
+ * A USB device can have up to 30 endpoints besides control
+ * endpoint 0.
+ */
+ d->max_epns = min_t(u32, vhub->max_epns, 30);
+ d->epns = kcalloc(d->max_epns, sizeof(*d->epns), GFP_KERNEL);
+ if (!d->epns)
+ return -ENOMEM;
+
/*
* The UDC core really needs us to have separate and uniquely
* named "parent" devices for each port so we create a sub device
* here for that purpose
*/
d->port_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
- if (!d->port_dev)
- return -ENOMEM;
+ if (!d->port_dev) {
+ rc = -ENOMEM;
+ goto fail_alloc;
+ }
device_initialize(d->port_dev);
d->port_dev->release = ast_vhub_dev_release;
d->port_dev->parent = parent;
@@ -584,6 +596,8 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
device_del(d->port_dev);
fail_add:
put_device(d->port_dev);
+ fail_alloc:
+ kfree(d->epns);
return rc;
}
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/epn.c b/drivers/usb/gadget/udc/aspeed-vhub/epn.c
index 7475c74aa5c5..0bd6b20435b8 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/epn.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/epn.c
@@ -800,10 +800,10 @@ struct ast_vhub_ep *ast_vhub_alloc_epn(struct ast_vhub_dev *d, u8 addr)
/* Find a free one (no device) */
spin_lock_irqsave(&vhub->lock, flags);
- for (i = 0; i < AST_VHUB_NUM_GEN_EPs; i++)
+ for (i = 0; i < vhub->max_epns; i++)
if (vhub->epns[i].dev == NULL)
break;
- if (i >= AST_VHUB_NUM_GEN_EPs) {
+ if (i >= vhub->max_epns) {
spin_unlock_irqrestore(&vhub->lock, flags);
return NULL;
}
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/hub.c b/drivers/usb/gadget/udc/aspeed-vhub/hub.c
index 9c3027306b15..6e565c3dbb5b 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/hub.c
+++ b/drivers/usb/gadget/udc/aspeed-vhub/hub.c
@@ -502,7 +502,7 @@ static void ast_vhub_wake_work(struct work_struct *work)
* we let the normal host wake path deal with it later.
*/
spin_lock_irqsave(&vhub->lock, flags);
- for (i = 0; i < AST_VHUB_NUM_PORTS; i++) {
+ for (i = 0; i < vhub->max_ports; i++) {
struct ast_vhub_port *p = &vhub->ports[i];
if (!(p->status & USB_PORT_STAT_SUSPEND))
@@ -585,7 +585,7 @@ static enum std_req_rc ast_vhub_set_port_feature(struct ast_vhub_ep *ep,
struct ast_vhub *vhub = ep->vhub;
struct ast_vhub_port *p;
- if (port == 0 || port > AST_VHUB_NUM_PORTS)
+ if (port == 0 || port > vhub->max_ports)
return std_req_stall;
port--;
p = &vhub->ports[port];
@@ -628,7 +628,7 @@ static enum std_req_rc ast_vhub_clr_port_feature(struct ast_vhub_ep *ep,
struct ast_vhub *vhub = ep->vhub;
struct ast_vhub_port *p;
- if (port == 0 || port > AST_VHUB_NUM_PORTS)
+ if (port == 0 || port > vhub->max_ports)
return std_req_stall;
port--;
p = &vhub->ports[port];
@@ -674,7 +674,7 @@ static enum std_req_rc ast_vhub_get_port_stat(struct ast_vhub_ep *ep,
struct ast_vhub *vhub = ep->vhub;
u16 stat, chg;
- if (port == 0 || port > AST_VHUB_NUM_PORTS)
+ if (port == 0 || port > vhub->max_ports)
return std_req_stall;
port--;
@@ -755,7 +755,7 @@ void ast_vhub_hub_suspend(struct ast_vhub *vhub)
* Forward to unsuspended ports without changing
* their connection status.
*/
- for (i = 0; i < AST_VHUB_NUM_PORTS; i++) {
+ for (i = 0; i < vhub->max_ports; i++) {
struct ast_vhub_port *p = &vhub->ports[i];
if (!(p->status & USB_PORT_STAT_SUSPEND))
@@ -778,7 +778,7 @@ void ast_vhub_hub_resume(struct ast_vhub *vhub)
* Forward to unsuspended ports without changing
* their connection status.
*/
- for (i = 0; i < AST_VHUB_NUM_PORTS; i++) {
+ for (i = 0; i < vhub->max_ports; i++) {
struct ast_vhub_port *p = &vhub->ports[i];
if (!(p->status & USB_PORT_STAT_SUSPEND))
@@ -812,7 +812,7 @@ void ast_vhub_hub_reset(struct ast_vhub *vhub)
* Clear all port status, disable gadgets and "suspend"
* them. They will be woken up by a port reset.
*/
- for (i = 0; i < AST_VHUB_NUM_PORTS; i++) {
+ for (i = 0; i < vhub->max_ports; i++) {
struct ast_vhub_port *p = &vhub->ports[i];
/* Only keep the connected flag */
@@ -845,6 +845,7 @@ static void ast_vhub_init_desc(struct ast_vhub *vhub)
/* Initialize vhub Hub Descriptor. */
memcpy(&vhub->vhub_hub_desc, &ast_vhub_hub_desc,
sizeof(vhub->vhub_hub_desc));
+ vhub->vhub_hub_desc.bNbrPorts = vhub->max_ports;
/* Initialize vhub String Descriptors. */
memcpy(&vhub->vhub_str_desc, &ast_vhub_strings,
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
index 191f9fae7420..fac79ef6d669 100644
--- a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
+++ b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
@@ -79,17 +79,9 @@
#define VHUB_SW_RESET_DEVICE2 (1 << 2)
#define VHUB_SW_RESET_DEVICE1 (1 << 1)
#define VHUB_SW_RESET_ROOT_HUB (1 << 0)
-#define VHUB_SW_RESET_ALL (VHUB_SW_RESET_EP_POOL | \
- VHUB_SW_RESET_DMA_CONTROLLER | \
- VHUB_SW_RESET_DEVICE5 | \
- VHUB_SW_RESET_DEVICE4 | \
- VHUB_SW_RESET_DEVICE3 | \
- VHUB_SW_RESET_DEVICE2 | \
- VHUB_SW_RESET_DEVICE1 | \
- VHUB_SW_RESET_ROOT_HUB)
+
/* EP ACK/NACK IRQ masks */
#define VHUB_EP_IRQ(n) (1 << (n))
-#define VHUB_EP_IRQ_ALL 0x7fff /* 15 EPs */
/* USB status reg */
#define VHUB_USBSTS_HISPEED (1 << 27)
@@ -213,6 +205,11 @@
* *
****************************************/
+/*
+ * AST_VHUB_NUM_GEN_EPs and AST_VHUB_NUM_PORTS are kept to avoid breaking
+ * existing AST2400/AST2500 platforms. AST2600 and future vhub revisions
+ * should define number of downstream ports and endpoints in device tree.
+ */
#define AST_VHUB_NUM_GEN_EPs 15 /* Generic non-0 EPs */
#define AST_VHUB_NUM_PORTS 5 /* vHub ports */
#define AST_VHUB_EP0_MAX_PACKET 64 /* EP0's max packet size */
@@ -315,7 +312,7 @@ struct ast_vhub_ep {
/* Registers */
void __iomem *regs;
- /* Index in global pool (0..14) */
+ /* Index in global pool (zero-based) */
unsigned int g_idx;
/* DMA Descriptors */
@@ -345,7 +342,7 @@ struct ast_vhub_dev {
struct ast_vhub *vhub;
void __iomem *regs;
- /* Device index (0...4) and name string */
+ /* Device index (zero-based) and name string */
unsigned int index;
const char *name;
@@ -361,7 +358,8 @@ struct ast_vhub_dev {
/* Endpoint structures */
struct ast_vhub_ep ep0;
- struct ast_vhub_ep *epns[AST_VHUB_NUM_GEN_EPs];
+ struct ast_vhub_ep **epns;
+ u32 max_epns;
};
#define to_ast_dev(__g) container_of(__g, struct ast_vhub_dev, gadget)
@@ -402,10 +400,12 @@ struct ast_vhub {
bool ep1_stalled : 1;
/* Per-port info */
- struct ast_vhub_port ports[AST_VHUB_NUM_PORTS];
+ struct ast_vhub_port *ports;
+ u32 max_ports;
/* Generic EP data structures */
- struct ast_vhub_ep epns[AST_VHUB_NUM_GEN_EPs];
+ struct ast_vhub_ep *epns;
+ u32 max_epns;
/* Upstream bus is suspended ? */
bool suspended : 1;
--
2.17.1
On Wed, 2020-02-26 at 15:03 -0800, [email protected] wrote:
> From: Tao Ren <[email protected]>
>
> This patch store vhub's standard usb descriptors in struct "ast_vhub"
> so
> it's more convenient to customize descriptors and potentially support
> multiple vhub instances in the future.
>
> Signed-off-by: Tao Ren <[email protected]>
Acked-by: Benjamin Herrenschmidt <[email protected]>
---
> ---
> No change in v2/v3/v4:
> - the patch is added to the patch series since v4.
>
> drivers/usb/gadget/udc/aspeed-vhub/hub.c | 43 ++++++++++++++++-----
> --
> drivers/usb/gadget/udc/aspeed-vhub/vhub.h | 15 ++++++++
> 2 files changed, 46 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/usb/gadget/udc/aspeed-vhub/hub.c
> b/drivers/usb/gadget/udc/aspeed-vhub/hub.c
> index 19b3517e04c0..9c3027306b15 100644
> --- a/drivers/usb/gadget/udc/aspeed-vhub/hub.c
> +++ b/drivers/usb/gadget/udc/aspeed-vhub/hub.c
> @@ -93,11 +93,7 @@ static void ast_vhub_patch_dev_desc_usb1(struct
> usb_device_descriptor *desc)
> USB_DT_INTERFACE_SIZE + \
> USB_DT_ENDPOINT_SIZE)
>
> -static const struct ast_vhub_full_cdesc {
> - struct usb_config_descriptor cfg;
> - struct usb_interface_descriptor intf;
> - struct usb_endpoint_descriptor ep;
> -} __attribute__ ((packed)) ast_vhub_conf_desc = {
> +static const struct ast_vhub_full_cdesc ast_vhub_conf_desc = {
> .cfg = {
> .bLength = USB_DT_CONFIG_SIZE,
> .bDescriptorType = USB_DT_CONFIG,
> @@ -266,6 +262,7 @@ static int ast_vhub_rep_desc(struct ast_vhub_ep
> *ep,
> u8 desc_type, u16 len)
> {
> size_t dsize;
> + struct ast_vhub *vhub = ep->vhub;
>
> EPDBG(ep, "GET_DESCRIPTOR(type:%d)\n", desc_type);
>
> @@ -281,20 +278,20 @@ static int ast_vhub_rep_desc(struct ast_vhub_ep
> *ep,
> switch(desc_type) {
> case USB_DT_DEVICE:
> dsize = USB_DT_DEVICE_SIZE;
> - memcpy(ep->buf, &ast_vhub_dev_desc, dsize);
> - BUILD_BUG_ON(dsize > sizeof(ast_vhub_dev_desc));
> + memcpy(ep->buf, &vhub->vhub_dev_desc, dsize);
> + BUILD_BUG_ON(dsize > sizeof(vhub->vhub_dev_desc));
> BUILD_BUG_ON(USB_DT_DEVICE_SIZE >=
> AST_VHUB_EP0_MAX_PACKET);
> break;
> case USB_DT_CONFIG:
> dsize = AST_VHUB_CONF_DESC_SIZE;
> - memcpy(ep->buf, &ast_vhub_conf_desc, dsize);
> - BUILD_BUG_ON(dsize > sizeof(ast_vhub_conf_desc));
> + memcpy(ep->buf, &vhub->vhub_conf_desc, dsize);
> + BUILD_BUG_ON(dsize > sizeof(vhub->vhub_conf_desc));
> BUILD_BUG_ON(AST_VHUB_CONF_DESC_SIZE >=
> AST_VHUB_EP0_MAX_PACKET);
> break;
> case USB_DT_HUB:
> dsize = AST_VHUB_HUB_DESC_SIZE;
> - memcpy(ep->buf, &ast_vhub_hub_desc, dsize);
> - BUILD_BUG_ON(dsize > sizeof(ast_vhub_hub_desc));
> + memcpy(ep->buf, &vhub->vhub_hub_desc, dsize);
> + BUILD_BUG_ON(dsize > sizeof(vhub->vhub_hub_desc));
> BUILD_BUG_ON(AST_VHUB_HUB_DESC_SIZE >=
> AST_VHUB_EP0_MAX_PACKET);
> break;
> default:
> @@ -317,7 +314,8 @@ static int ast_vhub_rep_string(struct ast_vhub_ep
> *ep,
> u8 string_id, u16 lang_id,
> u16 len)
> {
> - int rc = usb_gadget_get_string (&ast_vhub_strings, string_id,
> ep->buf);
> + int rc = usb_gadget_get_string(&ep->vhub->vhub_str_desc,
> + string_id, ep->buf);
>
> /*
> * This should never happen unless we put too big strings in
> @@ -834,9 +832,30 @@ void ast_vhub_hub_reset(struct ast_vhub *vhub)
> writel(0, vhub->regs + AST_VHUB_EP1_STS_CHG);
> }
>
> +static void ast_vhub_init_desc(struct ast_vhub *vhub)
> +{
> + /* Initialize vhub Device Descriptor. */
> + memcpy(&vhub->vhub_dev_desc, &ast_vhub_dev_desc,
> + sizeof(vhub->vhub_dev_desc));
> +
> + /* Initialize vhub Configuration Descriptor. */
> + memcpy(&vhub->vhub_conf_desc, &ast_vhub_conf_desc,
> + sizeof(vhub->vhub_conf_desc));
> +
> + /* Initialize vhub Hub Descriptor. */
> + memcpy(&vhub->vhub_hub_desc, &ast_vhub_hub_desc,
> + sizeof(vhub->vhub_hub_desc));
> +
> + /* Initialize vhub String Descriptors. */
> + memcpy(&vhub->vhub_str_desc, &ast_vhub_strings,
> + sizeof(vhub->vhub_str_desc));
> +}
> +
> void ast_vhub_init_hub(struct ast_vhub *vhub)
> {
> vhub->speed = USB_SPEED_UNKNOWN;
> INIT_WORK(&vhub->wake_work, ast_vhub_wake_work);
> +
> + ast_vhub_init_desc(vhub);
> }
>
> diff --git a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
> b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
> index 761919e220d3..191f9fae7420 100644
> --- a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
> +++ b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
> @@ -2,6 +2,9 @@
> #ifndef __ASPEED_VHUB_H
> #define __ASPEED_VHUB_H
>
> +#include <linux/usb.h>
> +#include <linux/usb/ch11.h>
> +
> /*****************************
> * *
> * VHUB register definitions *
> @@ -373,6 +376,12 @@ struct ast_vhub_port {
> struct ast_vhub_dev dev;
> };
>
> +struct ast_vhub_full_cdesc {
> + struct usb_config_descriptor cfg;
> + struct usb_interface_descriptor intf;
> + struct usb_endpoint_descriptor ep;
> +} __packed;
> +
> /* Global vhub structure */
> struct ast_vhub {
> struct platform_device *pdev;
> @@ -409,6 +418,12 @@ struct ast_vhub {
>
> /* Upstream bus speed captured at bus reset */
> unsigned int speed;
> +
> + /* Standard USB Descriptors of the vhub. */
> + struct usb_device_descriptor vhub_dev_desc;
> + struct ast_vhub_full_cdesc vhub_conf_desc;
> + struct usb_hub_descriptor vhub_hub_desc;
> + struct usb_gadget_strings vhub_str_desc;
> };
>
> /* Standard request handlers result codes */
On Wed, 2020-02-26 at 15:03 -0800, [email protected] wrote:
> From: Tao Ren <[email protected]>
>
> Add device tree binding documentation for aspeed usb-vhub driver.
>
> Signed-off-by: Tao Ren <[email protected]>
> ---
> No change in v2/v3/v4:
> - the patch is added to the patch series since v4.
>
> .../bindings/usb/aspeed,usb-vhub.yaml | 71 +++++++++++++++++++
> 1 file changed, 71 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml
>
> diff --git a/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml b/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml
> new file mode 100644
> index 000000000000..6ebae46641e5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml
> @@ -0,0 +1,71 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# Copyright (c) 2020 Facebook Inc.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/usb/aspeed,usb-vhub.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ASPEED USB 2.0 Virtual Hub Controller
> +
> +maintainers:
> + - Felipe Balbi <[email protected]>
Actually I mantain that one, so make this Benjamin Herrenschmidt <
[email protected]>. Felipe is the overall maintainer of the USB
gadget subsystem afaik.
> +description: |+
> + The ASPEED USB 2.0 Virtual Hub Controller implements 1 set of USB Hub
> + register and several sets of Device and Endpoint registers to support
> + the Virtual Hub's downstream USB devices.
> +
> + Supported number of devices and endpoints vary depending on hardware
> + revisions. AST2400 and AST2500 Virtual Hub supports 5 downstream devices
> + and 15 generic endpoints, while AST2600 Virtual Hub supports 7 downstream
> + devices and 21 generic endpoints.
> +
> +properties:
> + compatible:
> + enum:
> + - aspeed,ast2400-usb-vhub
> + - aspeed,ast2500-usb-vhub
> + - aspeed,ast2600-usb-vhub
> +
> + reg:
> + maxItems: 1
> + description: Common configuration registers
> +
> + clocks:
> + maxItems: 1
> + description: The Virtual Hub Controller clock gate
> +
> + interrupts:
> + maxItems: 1
> +
> + aspeed,vhub-downstream-ports:
> + description: Number of downstream ports supported by the Virtual Hub
> + allOf:
> + - $ref: /schemas/types.yaml#/definitions/uint32
> +
> + aspeed,vhub-generic-endpoints:
> + description: Number of generic endpoints supported by the Virtual Hub
> + allOf:
> + - $ref: /schemas/types.yaml#/definitions/uint32
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> + - interrupts
> + - aspeed,vhub-downstream-ports
> + - aspeed,vhub-generic-endpoints
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/clock/aspeed-clock.h>
> + vhub: usb-vhub@1e6a0000 {
> + compatible = "aspeed,ast2500-usb-vhub";
> + reg = <0x1e6a0000 0x300>;
> + interrupts = <5>;
> + clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_usb2ad_default>;
> + };
On Wed, 2020-02-26 at 15:03 -0800, [email protected] wrote:
> From: Tao Ren <[email protected]>
>
> The patch introduces 2 DT properties ("aspeed,vhub-downstream-ports" and
> "aspeed,vhub-generic-endpoints") which replaces hardcoded port/endpoint
> number. It is to make it more convenient to add support for newer vhub
> revisions with different number of ports and endpoints.
>
> Signed-off-by: Tao Ren <[email protected]>
> Reviewed-by: Joel Stanley <[email protected]>
With one minor nit that can be addressed in a subsequent patch (see
below)
Acked-by: Benjamin Herrenschmidt <[email protected]>
> ---
> Changes in v4:
> - use NUM_PORTS/NUM_GEN_EPs defined in vhub.h instead of introducing
> new constants (in v3).
> Changes in v3:
> - fall back to "default" number of ports and endpoints to avoid
> breaking existing ast2400/ast2500 platforms when according device
> tree properties are not defined.
> Changes in v2:
> - removed ast_vhub_config structure and moved vhub port/endpoint
> number into device tree.
>
> drivers/usb/gadget/udc/aspeed-vhub/core.c | 68 ++++++++++++++---------
> drivers/usb/gadget/udc/aspeed-vhub/dev.c | 30 +++++++---
> drivers/usb/gadget/udc/aspeed-vhub/epn.c | 4 +-
> drivers/usb/gadget/udc/aspeed-vhub/hub.c | 15 ++---
> drivers/usb/gadget/udc/aspeed-vhub/vhub.h | 28 +++++-----
> 5 files changed, 88 insertions(+), 57 deletions(-)
>
> diff --git a/drivers/usb/gadget/udc/aspeed-vhub/core.c b/drivers/usb/gadget/udc/aspeed-vhub/core.c
> index 90b134d5dca9..f8ab8e012f34 100644
> --- a/drivers/usb/gadget/udc/aspeed-vhub/core.c
> +++ b/drivers/usb/gadget/udc/aspeed-vhub/core.c
> @@ -99,7 +99,7 @@ static irqreturn_t ast_vhub_irq(int irq, void *data)
> {
> struct ast_vhub *vhub = data;
> irqreturn_t iret = IRQ_NONE;
> - u32 istat;
> + u32 i, istat;
>
> /* Stale interrupt while tearing down */
> if (!vhub->ep0_bufs)
> @@ -121,10 +121,10 @@ static irqreturn_t ast_vhub_irq(int irq, void *data)
>
> /* Handle generic EPs first */
> if (istat & VHUB_IRQ_EP_POOL_ACK_STALL) {
> - u32 i, ep_acks = readl(vhub->regs + AST_VHUB_EP_ACK_ISR);
> + u32 ep_acks = readl(vhub->regs + AST_VHUB_EP_ACK_ISR);
> writel(ep_acks, vhub->regs + AST_VHUB_EP_ACK_ISR);
>
> - for (i = 0; ep_acks && i < AST_VHUB_NUM_GEN_EPs; i++) {
> + for (i = 0; ep_acks && i < vhub->max_epns; i++) {
> u32 mask = VHUB_EP_IRQ(i);
> if (ep_acks & mask) {
> ast_vhub_epn_ack_irq(&vhub->epns[i]);
> @@ -134,21 +134,11 @@ static irqreturn_t ast_vhub_irq(int irq, void *data)
> }
>
> /* Handle device interrupts */
> - if (istat & (VHUB_IRQ_DEVICE1 |
> - VHUB_IRQ_DEVICE2 |
> - VHUB_IRQ_DEVICE3 |
> - VHUB_IRQ_DEVICE4 |
> - VHUB_IRQ_DEVICE5)) {
> - if (istat & VHUB_IRQ_DEVICE1)
> - ast_vhub_dev_irq(&vhub->ports[0].dev);
> - if (istat & VHUB_IRQ_DEVICE2)
> - ast_vhub_dev_irq(&vhub->ports[1].dev);On Wed,
> 2020-02-26 at 15:03 -0800, [email protected] wrote:> From: Tao
> Ren <[email protected]>>
> > The patch introduces 2 DT properties ("aspeed,vhub-downstream-
> ports" and> "aspeed,vhub-generic-endpoints") which replaces hardcoded
> port/endpoint> number. It is to make it more convenient to add
> support for newer vhub> revisions with different number of ports and
> endpoints.>
> > Signed-off-by: Tao Ren <[email protected]>> Reviewed-by: Joel
> Stanley <[email protected]>> ---> Changes in v4:> - use
> NUM_PORTS/NUM_GEN_EPs defined in vhub.h instead of introducing>
> new constants (in v3).> Changes in v3:> - fall back to
> "default" number of ports and endpoints to avoid> breaking
> existing ast2400/ast2500 platforms when according device> tree
> properties are not defined.> Changes in v2:> - removed
> ast_vhub_config structure and moved vhub port/endpoint> number
> into device tree.>
> > drivers/usb/gadget/udc/aspeed-vhub/core.c | 68 ++++++++++++++-----
> ----> drivers/usb/gadget/udc/aspeed-vhub/dev.c | 30 +++++++--->
> drivers/usb/gadget/udc/aspeed-vhub/epn.c | 4 +->
> drivers/usb/gadget/udc/aspeed-vhub/hub.c | 15 ++--->
> drivers/usb/gadget/udc/aspeed-vhub/vhub.h | 28 +++++-----> 5 files
> changed, 88 insertions(+), 57 deletions(-)>
> > diff --git a/drivers/usb/gadget/udc/aspeed-vhub/core.c
> b/drivers/usb/gadget/udc/aspeed-vhub/core.c> index
> 90b134d5dca9..f8ab8e012f34 100644> ---
> a/drivers/usb/gadget/udc/aspeed-vhub/core.c> +++
> b/drivers/usb/gadget/udc/aspeed-vhub/core.c> @@ -99,7 +99,7 @@ static
> irqreturn_t ast_vhub_irq(int irq, void *data)> {> struct ast_vhub
> *vhub = data;> irqreturn_t iret = IRQ_NONE;> - u32 istat;> +
> u32 i, istat;> > /* Stale interrupt while tearing down
> */> if (!vhub->ep0_bufs)> @@ -121,10 +121,10 @@ static irqreturn_t
> ast_vhub_irq(int irq, void *data)> > /* Handle generic EPs
> first */> if (istat & VHUB_IRQ_EP_POOL_ACK_STALL) {> -
> u32 i, ep_acks = readl(vhub->regs + AST_VHUB_EP_ACK_ISR);> +
> u32 ep_acks = readl(vhub->regs + AST_VHUB_EP_ACK_ISR);>
> writel(ep_acks, vhub->regs + AST_VHUB_EP_ACK_ISR);> > -
> for (i = 0; ep_acks && i < AST_VHUB_NUM_GEN_EPs; i++) {> +
> for (i = 0; ep_acks && i < vhub->max_epns; i++) {>
> u32 mask = VHUB_EP_IRQ(i);> if (ep_acks & mask) {>
> ast_vhub_epn_ack_irq(&vhub->epns[i]);>
> @@ -134,21 +134,11 @@ static irqreturn_t ast_vhub_irq(int irq, void
> *data)> }> > /* Handle device interrupts */> - if
> (istat & (VHUB_IRQ_DEVICE1 |> - VHUB_IRQ_DEVICE2
> |> - VHUB_IRQ_DEVICE3 |> - VHUB_IRQ
> _DEVICE4 |> - VHUB_IRQ_DEVICE5)) {> - if
> (istat & VHUB_IRQ_DEVICE1)> - ast_vhub_dev_irq(&vhub-
> >ports[0].dev);> - if (istat & VHUB_IRQ_DEVICE2)> -
> ast_vhub_dev_irq(&vhub->ports[1].dev);> - if (istat &
> VHUB_IRQ_DEVICE3)> - ast_vhub_dev_irq(&vhub-
> >ports[2].dev);> - if (istat & VHUB_IRQ_DEVICE4)> -
> ast_vhub_dev_irq(&vhub->ports[3].dev);> - if (istat &
> VHUB_IRQ_DEVICE5)> - ast_vhub_dev_irq(&vhub-
> >ports[4].dev);> + for (i = 0; i < vhub->max_ports; i++) {> +
> u32 dev_mask = VHUB_IRQ_DEVICE1 << i;> +> + if
> (istat & dev_mask)> + ast_vhub_dev_irq(&vhub-
> >ports[i].dev);> }> > /* Handle top-level vHub EP0
> interrupts */> @@ -182,7 +172,7 @@ static irqreturn_t
> ast_vhub_irq(int irq, void *data)> > void ast_vhub_init_hw(struct
> ast_vhub *vhub)> {> - u32 ctrl;> + u32 ctrl, port_mask,
> epn_mask;> > UDCDBG(vhub,"(Re)Starting HW ...\n");> > @@
> -222,15 +212,20 @@ void ast_vhub_init_hw(struct ast_vhub *vhub)>
> }> > /* Reset all devices */> - writel(VHUB_SW_RESET_
> ALL, vhub->regs + AST_VHUB_SW_RESET);> + port_mask =
> GENMASK(vhub->max_ports, 1);> + writel(VHUB_SW_RESET_ROOT_HUB
> |> + VHUB_SW_RESET_DMA_CONTROLLER |> + VHUB_SW_RESET_
> EP_POOL |> + port_mask, vhub->regs + AST_VHUB_SW_RESET);>
> udelay(1);> writel(0, vhub->regs + AST_VHUB_SW_RESET);> > /*
> Disable and cleanup EP ACK/NACK interrupts */> + epn_mask =
> GENMASK(vhub->max_epns - 1, 0);> writel(0, vhub->regs +
> AST_VHUB_EP_ACK_IER);> writel(0, vhub->regs +
> AST_VHUB_EP_NACK_IER);> - writel(VHUB_EP_IRQ_ALL, vhub->regs +
> AST_VHUB_EP_ACK_ISR);> - writel(VHUB_EP_IRQ_ALL, vhub->regs +
> AST_VHUB_EP_NACK_ISR);> + writel(epn_mask, vhub->regs +
> AST_VHUB_EP_ACK_ISR);> + writel(epn_mask, vhub->regs +
> AST_VHUB_EP_NACK_ISR);> > /* Default settings for EP0, enable HW
> hub EP1 */> writel(0, vhub->regs + AST_VHUB_EP0_CTRL);> @@ -273,7
> +268,7 @@ static int ast_vhub_remove(struct platform_device *pdev)>
> return 0;> > /* Remove devices */> - for (i = 0; i <
> AST_VHUB_NUM_PORTS; i++)> + for (i = 0; i < vhub->max_ports; i++)>
> ast_vhub_del_dev(&vhub->ports[i].dev);> > spin_
> lock_irqsave(&vhub->lock, flags);> @@ -295,7 +290,7 @@ static int
> ast_vhub_remove(struct platform_device *pdev)> if (vhub-
> >ep0_bufs)> dma_free_coherent(&pdev->dev,>
> AST_VHUB_EP0_MAX_PACKET *> - (AS
> T_VHUB_NUM_PORTS + 1),> + (vhub-
> >max_ports + 1),> vhub->ep0_bufs,>
> vhub->ep0_bufs_dma);> vhub->ep0_bufs =
> NULL;> @@ -309,11 +304,32 @@ static int ast_vhub_probe(struct
> platform_device *pdev)> struct ast_vhub *vhub;> struct
> resource *res;> int i, rc = 0;> + const struct device_node *np
> = pdev->dev.of_node;> > vhub = devm_kzalloc(&pdev->dev,
> sizeof(*vhub), GFP_KERNEL);> if (!vhub)> retur
> n -ENOMEM;> > + rc = of_property_read_u32(np, "aspeed,vhub-
> downstream-ports",> + &vhub->max_ports);> +
> if (rc < 0)> + vhub->max_ports =
> AST_VHUB_NUM_PORTS;> +> + vhub->ports = devm_kcalloc(&pdev->dev,
> vhub->max_ports,> + sizeof(*vhub-
> >ports), GFP_KERNEL);> + if (!vhub->ports)> + retur
> n -ENOMEM;> +> + rc = of_property_read_u32(np, "aspeed,vhub-
> generic-endpoints",> + &vhub-
> >max_epns);> + if (rc < 0)> + vhub->max_epns =
> AST_VHUB_NUM_GEN_EPs;> +> + vhub->epns = devm_kcalloc(&pdev->dev,
> vhub->max_epns,> + sizeof(*vhub->epns),
> GFP_KERNEL);> + if (!vhub->epns)> + return
> -ENOMEM;> +> spin_lock_init(&vhub->lock);> vhub->pdev =
> pdev;> > @@ -366,7 +382,7 @@ static int ast_vhub_probe(struct
> platform_device *pdev)> */> vhub->ep0_bufs =
> dma_alloc_coherent(&pdev->dev,>
> AST_VHUB_EP0_MAX_PACKET *> -
> (AST_VHUB_NUM_PORTS + 1),> +
> (vhub->max_ports + 1),> &vh
> ub->ep0_bufs_dma, GFP_KERNEL);> if (!vhub->ep0_bufs) {>
> dev_err(&pdev->dev, "Failed to allocate EP0 DMA buffers\n");> @@
> -380,7 +396,7 @@ static int ast_vhub_probe(struct platform_device
> *pdev)> ast_vhub_init_ep0(vhub, &vhub->ep0, NULL);> > /*
> Init devices */> - for (i = 0; i < AST_VHUB_NUM_PORTS && rc == 0;
> i++)> + for (i = 0; i < vhub->max_ports && rc == 0; i++)>
> rc = ast_vhub_init_dev(vhub, i);> if (rc)>
> goto err;> diff --git a/drivers/usb/gadget/udc/aspeed-vhub/dev.c
> b/drivers/usb/gadget/udc/aspeed-vhub/dev.c> index
> 4008e7a51188..d268306a7bfe 100644> ---
> a/drivers/usb/gadget/udc/aspeed-vhub/dev.c> +++
> b/drivers/usb/gadget/udc/aspeed-vhub/dev.c> @@ -77,7 +77,7 @@ static
> void ast_vhub_dev_enable(struct ast_vhub_dev *d)> writel(d-
> >ep0.buf_dma, d->regs + AST_VHUB_DEV_EP0_DATA);> > /* Clear stall
> on all EPs */> - for (i = 0; i < AST_VHUB_NUM_GEN_EPs; i++) {> +
> for (i = 0; i < d->max_epns; i++) {> struct
> ast_vhub_ep *ep = d->epns[i];> > if (ep && (ep-
> >epn.stalled || ep->epn.wedged)) {> @@ -137,7 +137,7 @@ static int
> ast_vhub_ep_feature(struct ast_vhub_dev *d,> is_set ?
> "SET" : "CLEAR", ep_num, wValue);> if (ep_num == 0)>
> return std_req_complete;> - if (ep_num >= AST_VHUB_NUM_GEN_EPs ||
> !d->epns[ep_num - 1])> + if (ep_num >= d->max_epns || !d-
> >epns[ep_num - 1])> return std_req_stall;> if (wValue !=
> USB_ENDPOINT_HALT)> return std_req_driver;> @@ -181,7
> +181,7 @@ static int ast_vhub_ep_status(struct ast_vhub_dev *d,> >
> DDBG(d, "GET_STATUS(ep%d)\n", ep_num);> > - if (ep_num >=
> AST_VHUB_NUM_GEN_EPs)> + if (ep_num >= d->max_epns)>
> return std_req_stall;> if (ep_num != 0) {> ep =
> d->epns[ep_num - 1];> @@ -299,7 +299,7 @@ static void
> ast_vhub_dev_nuke(struct ast_vhub_dev *d)> {> unsigned int
> i;> > - for (i = 0; i < AST_VHUB_NUM_GEN_EPs; i++) {> + for
> (i = 0; i < d->max_epns; i++) {> if (!d->epns[i])>
> continue;> ast_vhub_nuke(d->epns[i],
> -ESHUTDOWN);> @@ -416,10 +416,10 @@ static struct usb_ep
> *ast_vhub_udc_match_ep(struct usb_gadget *gadget,> * that will
> allow the generic code to use our> * assigned address.> */>
> - for (i = 0; i < AST_VHUB_NUM_GEN_EPs; i++)> + for (i = 0; i
> < d->max_epns; i++)> if (d->epns[i] == NULL)>
> break;> - if (i >= AST_VHUB_NUM_GEN_EPs)> + if (i
> >= d->max_epns)> return NULL;> addr = i + 1;> > @@
> -526,6 +526,7 @@ void ast_vhub_del_dev(struct ast_vhub_dev *d)> >
> usb_del_gadget_udc(&d->gadget);> device_unregister(d-
> >port_dev);> + kfree(d->epns);> }> > static void
> ast_vhub_dev_release(struct device *dev)> @@ -546,14 +547,25 @@ int
> ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)> >
> ast_vhub_init_ep0(vhub, &d->ep0, d);> > + /*> + * A USB
> device can have up to 30 endpoints besides control> + * endpoint 0.>
> + */> + d->max_epns = min_t(u32, vhub->max_epns, 30);> +
> d->epns = kcalloc(d->max_epns, sizeof(*d->epns), GFP_KERNEL);> +
> if (!d->epns)> + return -ENOMEM;> +> /*> *
> The UDC core really needs us to have separate and uniquely> *
> named "parent" devices for each port so we create a sub device>
> * here for that purpose> */> d->port_dev =
> kzalloc(sizeof(struct device), GFP_KERNEL);> - if (!d-
> >port_dev)> - return -ENOMEM;> + if (!d->port_dev) {>
> + rc = -ENOMEM;> + goto fail_alloc;> + }>
> device_initialize(d->port_dev);> d->port_dev->release =
> ast_vhub_dev_release;> d->port_dev->parent = parent;> @@
> -584,6 +596,8 @@ int ast_vhub_init_dev(struct ast_vhub *vhub,
> unsigned int idx)> device_del(d->port_dev);> fail_add:> put_d
> evice(d->port_dev);> + fail_alloc:> + kfree(d->epns);> > retur
> n rc;> }> diff --git a/drivers/usb/gadget/udc/aspeed-vhub/epn.c
> b/drivers/usb/gadget/udc/aspeed-vhub/epn.c> index
> 7475c74aa5c5..0bd6b20435b8 100644> ---
> a/drivers/usb/gadget/udc/aspeed-vhub/epn.c> +++
> b/drivers/usb/gadget/udc/aspeed-vhub/epn.c> @@ -800,10 +800,10 @@
> struct ast_vhub_ep *ast_vhub_alloc_epn(struct ast_vhub_dev *d, u8
> addr)> > /* Find a free one (no device) */> spin_lock_irq
> save(&vhub->lock, flags);> - for (i = 0; i < AST_VHUB_NUM_GEN_EPs;
> i++)> + for (i = 0; i < vhub->max_epns; i++)> if
> (vhub->epns[i].dev == NULL)> break;> - if (i
> >= AST_VHUB_NUM_GEN_EPs) {> + if (i >= vhub->max_epns) {>
> spin_unlock_irqrestore(&vhub->lock, flags);> return
> NULL;> }> diff --git a/drivers/usb/gadget/udc/aspeed-
> vhub/hub.c b/drivers/usb/gadget/udc/aspeed-vhub/hub.c> index
> 9c3027306b15..6e565c3dbb5b 100644> ---
> a/drivers/usb/gadget/udc/aspeed-vhub/hub.c> +++
> b/drivers/usb/gadget/udc/aspeed-vhub/hub.c> @@ -502,7 +502,7 @@
> static void ast_vhub_wake_work(struct work_struct *work)> * we
> let the normal host wake path deal with it later.> */> spin_
> lock_irqsave(&vhub->lock, flags);> - for (i = 0; i <
> AST_VHUB_NUM_PORTS; i++) {> + for (i = 0; i < vhub->max_ports; i++)
> {> struct ast_vhub_port *p = &vhub->ports[i];> >
> if (!(p->status & USB_PORT_STAT_SUSPEND))> @@ -585,7 +585,7 @@ static
> enum std_req_rc ast_vhub_set_port_feature(struct ast_vhub_ep *ep,>
> struct ast_vhub *vhub = ep->vhub;> struct ast_vhub_port *p;> > -
> if (port == 0 || port > AST_VHUB_NUM_PORTS)> + if (port == 0
> || port > vhub->max_ports)> return std_req_stall;> port-
> -;> p = &vhub->ports[port];> @@ -628,7 +628,7 @@ static enum
> std_req_rc ast_vhub_clr_port_feature(struct ast_vhub_ep *ep,>
> struct ast_vhub *vhub = ep->vhub;> struct ast_vhub_port *p;> > -
> if (port == 0 || port > AST_VHUB_NUM_PORTS)> + if (port == 0
> || port > vhub->max_ports)> return std_req_stall;> port-
> -;> p = &vhub->ports[port];> @@ -674,7 +674,7 @@ static enum
> std_req_rc ast_vhub_get_port_stat(struct ast_vhub_ep *ep,> struct
> ast_vhub *vhub = ep->vhub;> u16 stat, chg;> > - if (port == 0
> || port > AST_VHUB_NUM_PORTS)> + if (port == 0 || port > vhub-
> >max_ports)> return std_req_stall;> port--;> >
> @@ -755,7 +755,7 @@ void ast_vhub_hub_suspend(struct ast_vhub *vhub)>
> * Forward to unsuspended ports without changing> *
> their connection status.> */> - for (i = 0; i <
> AST_VHUB_NUM_PORTS; i++) {> + for (i = 0; i < vhub->max_ports; i++)
> {> struct ast_vhub_port *p = &vhub->ports[i];> >
> if (!(p->status & USB_PORT_STAT_SUSPEND))> @@ -778,7 +778,7 @@ void
> ast_vhub_hub_resume(struct ast_vhub *vhub)> * Forward to
> unsuspended ports without changing> * their connection status.>
> */> - for (i = 0; i < AST_VHUB_NUM_PORTS; i++) {> + for
> (i = 0; i < vhub->max_ports; i++) {> struct
> ast_vhub_port *p = &vhub->ports[i];> > if (!(p->status
> & USB_PORT_STAT_SUSPEND))> @@ -812,7 +812,7 @@ void
> ast_vhub_hub_reset(struct ast_vhub *vhub)> * Clear all port
> status, disable gadgets and "suspend"> * them. They will be
> woken up by a port reset.> */> - for (i = 0; i <
> AST_VHUB_NUM_PORTS; i++) {> + for (i = 0; i < vhub->max_ports; i++)
> {> struct ast_vhub_port *p = &vhub->ports[i];> >
> /* Only keep the connected flag */> @@ -845,6 +845,7 @@ static void
> ast_vhub_init_desc(struct ast_vhub *vhub)> /* Initialize vhub Hub
> Descriptor. */> memcpy(&vhub->vhub_hub_desc,
> &ast_vhub_hub_desc,> sizeof(vhub->vhub_hub_desc));>
> + vhub->vhub_hub_desc.bNbrPorts = vhub->max_ports;> > /*
> Initialize vhub String Descriptors. */> memcpy(&vhub-
> >vhub_str_desc, &ast_vhub_strings,> diff --git
> a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
> b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h> index
> 191f9fae7420..fac79ef6d669 100644> ---
> a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h> +++
> b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h> @@ -79,17 +79,9 @@>
> #define VHUB_SW_RESET_DEVICE2 (1 << 2)>
> #define VHUB_SW_RESET_DEVICE1 (1 << 1)>
> #define VHUB_SW_RESET_ROOT_HUB (1 << 0)>
> -#define VHUB_SW_RESET_ALL (VHUB_SW_RESET_EP_POOL
> | \> - VHUB_SW_RESET_
> DMA_CONTROLLER | \> - VHUB_S
> W_RESET_DEVICE5 | \> -
> VHUB_SW_RESET_DEVICE4 | \> -
> VHUB_SW_RESET_DEVICE3 | \> -
> VHUB_SW_RESET_DEVICE2 | \> -
> VHUB_SW_RESET_DEVICE1 | \> -
> VHUB_SW_RESET_ROOT_HUB)> +> /* EP ACK/NACK IRQ masks */> #define
> VHUB_EP_IRQ(n) (1 << (n))> -#define
> VHUB_EP_IRQ_ALL 0x7fff /* 15 EPs */>
> > /* USB status reg */> #define VHUB_USBSTS_HISPEED
> (1 << 27)> @@ -213,6 +205,11 @@>
> * *>
> ****************************************/> > +/*> + *
> AST_VHUB_NUM_GEN_EPs and AST_VHUB_NUM_PORTS are kept to avoid
> breaking> + * existing AST2400/AST2500 platforms. AST2600 and future
> vhub revisions> + * should define number of downstream ports and
> endpoints in device tree.> + */> #define AST_VHUB_NUM_GEN_EPs
> 15 /* Generic non-0 EPs */> #define AST_VHUB_NUM_PORTS 5
> /* vHub ports */> #define AST_VHUB_EP0_MAX_PACKET 64 /*
> EP0's max packet size */> @@ -315,7 +312,7 @@ struct ast_vhub_ep {>
> /* Registers */> void
> __iomem *regs;> > - /* Index in
> global pool (0..14) */> + /* Index in global pool
> (zero-based) */> unsigned int g_idx
> ;> > /* DMA Descriptors */> @@ -345,7 +342,7
> @@ struct ast_vhub_dev {> struct ast_vhub *vhub
> ;> void __iomem *regs;> > - /* Device
> index (0...4) and name string */> + /* Device index (zero-based)
> and name string */> unsigned int index;>
> const char *name;> > @@ -361,7 +358,8 @@ struct
> ast_vhub_dev {> > /* Endpoint structures */> struct
> ast_vhub_ep ep0;> - struct ast_vhub_ep *epns
> [AST_VHUB_NUM_GEN_EPs];> + struct ast_vhub_ep **epn
> s;> + u32 max_epns;> > };> #define
> to_ast_dev(__g) container_of(__g, struct ast_vhub_dev, gadget)> @@
> -402,10 +400,12 @@ struct ast_vhub {> bool
> ep1_stalled : 1;> > /* Per-port info */> - struct
> ast_vhub_port ports[AST_VHUB_NUM_PORTS];> + struct
> ast_vhub_port *ports;> + u32
> max_ports;> > /* Generic EP data structures */> - struc
> t ast_vhub_ep epns[AST_VHUB_NUM_GEN_EPs];> + struct
> ast_vhub_ep *epns;> + u32 max_e
> pns;> > /* Upstream bus is suspended ? */> bool
> suspended : 1;
> - if (istat & VHUB_IRQ_DEVICE3)
> - ast_vhub_dev_irq(&vhub->ports[2].dev);
> - if (istat & VHUB_IRQ_DEVICE4)
> - ast_vhub_dev_irq(&vhub->ports[3].dev);
> - if (istat & VHUB_IRQ_DEVICE5)
> - ast_vhub_dev_irq(&vhub->ports[4].dev);
> + for (i = 0; i < vhub->max_ports; i++) {
> + u32 dev_mask = VHUB_IRQ_DEVICE1 << i;
> +
> + if (istat & dev_mask)
> + ast_vhub_dev_irq(&vhub->ports[i].dev);
> }
The 2400 and 2500 have very slow cores and every cycle counts in that
interrupt handler from my experience. I would sugggest you generate a
"mask" of all the device interrupts for enabled ports in struct vhub
and AND istat with that mask before going through the loop. Either that
or use find_next_zero_bit...
I wouldn't gate merging this patch on this, it can be a subsequent
refinement.
> /* Handle top-level vHub EP0 interrupts */
> @@ -182,7 +172,7 @@ static irqreturn_t ast_vhub_irq(int irq, void *data)
>
> void ast_vhub_init_hw(struct ast_vhub *vhub)
> {
> - u32 ctrl;
> + u32 ctrl, port_mask, epn_mask;
>
> UDCDBG(vhub,"(Re)Starting HW ...\n");
>
> @@ -222,15 +212,20 @@ void ast_vhub_init_hw(struct ast_vhub *vhub)
> }
>
> /* Reset all devices */
> - writel(VHUB_SW_RESET_ALL, vhub->regs + AST_VHUB_SW_RESET);
> + port_mask = GENMASK(vhub->max_ports, 1);
> + writel(VHUB_SW_RESET_ROOT_HUB |
> + VHUB_SW_RESET_DMA_CONTROLLER |
> + VHUB_SW_RESET_EP_POOL |
> + port_mask, vhub->regs + AST_VHUB_SW_RESET);
> udelay(1);
> writel(0, vhub->regs + AST_VHUB_SW_RESET);
>
> /* Disable and cleanup EP ACK/NACK interrupts */
> + epn_mask = GENMASK(vhub->max_epns - 1, 0);
> writel(0, vhub->regs + AST_VHUB_EP_ACK_IER);
> writel(0, vhub->regs + AST_VHUB_EP_NACK_IER);
> - writel(VHUB_EP_IRQ_ALL, vhub->regs + AST_VHUB_EP_ACK_ISR);
> - writel(VHUB_EP_IRQ_ALL, vhub->regs + AST_VHUB_EP_NACK_ISR);
> + writel(epn_mask, vhub->regs + AST_VHUB_EP_ACK_ISR);
> + writel(epn_mask, vhub->regs + AST_VHUB_EP_NACK_ISR);
>
> /* Default settings for EP0, enable HW hub EP1 */
> writel(0, vhub->regs + AST_VHUB_EP0_CTRL);
> @@ -273,7 +268,7 @@ static int ast_vhub_remove(struct platform_device *pdev)
> return 0;
>
> /* Remove devices */
> - for (i = 0; i < AST_VHUB_NUM_PORTS; i++)
> + for (i = 0; i < vhub->max_ports; i++)
> ast_vhub_del_dev(&vhub->ports[i].dev);
>
> spin_lock_irqsave(&vhub->lock, flags);
> @@ -295,7 +290,7 @@ static int ast_vhub_remove(struct platform_device *pdev)
> if (vhub->ep0_bufs)
> dma_free_coherent(&pdev->dev,
> AST_VHUB_EP0_MAX_PACKET *
> - (AST_VHUB_NUM_PORTS + 1),
> + (vhub->max_ports + 1),
> vhub->ep0_bufs,
> vhub->ep0_bufs_dma);
> vhub->ep0_bufs = NULL;
> @@ -309,11 +304,32 @@ static int ast_vhub_probe(struct platform_device *pdev)
> struct ast_vhub *vhub;
> struct resource *res;
> int i, rc = 0;
> + const struct device_node *np = pdev->dev.of_node;
>
> vhub = devm_kzalloc(&pdev->dev, sizeof(*vhub), GFP_KERNEL);
> if (!vhub)
> return -ENOMEM;
>
> + rc = of_property_read_u32(np, "aspeed,vhub-downstream-ports",
> + &vhub->max_ports);
> + if (rc < 0)
> + vhub->max_ports = AST_VHUB_NUM_PORTS;
> +
> + vhub->ports = devm_kcalloc(&pdev->dev, vhub->max_ports,
> + sizeof(*vhub->ports), GFP_KERNEL);
> + if (!vhub->ports)
> + return -ENOMEM;
> +
> + rc = of_property_read_u32(np, "aspeed,vhub-generic-endpoints",
> + &vhub->max_epns);
> + if (rc < 0)
> + vhub->max_epns = AST_VHUB_NUM_GEN_EPs;
> +
> + vhub->epns = devm_kcalloc(&pdev->dev, vhub->max_epns,
> + sizeof(*vhub->epns), GFP_KERNEL);
> + if (!vhub->epns)
> + return -ENOMEM;
> +
> spin_lock_init(&vhub->lock);
> vhub->pdev = pdev;
>
> @@ -366,7 +382,7 @@ static int ast_vhub_probe(struct platform_device *pdev)
> */
> vhub->ep0_bufs = dma_alloc_coherent(&pdev->dev,
> AST_VHUB_EP0_MAX_PACKET *
> - (AST_VHUB_NUM_PORTS + 1),
> + (vhub->max_ports + 1),
> &vhub->ep0_bufs_dma, GFP_KERNEL);
> if (!vhub->ep0_bufs) {
> dev_err(&pdev->dev, "Failed to allocate EP0 DMA buffers\n");
> @@ -380,7 +396,7 @@ static int ast_vhub_probe(struct platform_device *pdev)
> ast_vhub_init_ep0(vhub, &vhub->ep0, NULL);
>
> /* Init devices */
> - for (i = 0; i < AST_VHUB_NUM_PORTS && rc == 0; i++)
> + for (i = 0; i < vhub->max_ports && rc == 0; i++)
> rc = ast_vhub_init_dev(vhub, i);
> if (rc)
> goto err;
> diff --git a/drivers/usb/gadget/udc/aspeed-vhub/dev.c b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
> index 4008e7a51188..d268306a7bfe 100644
> --- a/drivers/usb/gadget/udc/aspeed-vhub/dev.c
> +++ b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
> @@ -77,7 +77,7 @@ static void ast_vhub_dev_enable(struct ast_vhub_dev *d)
> writel(d->ep0.buf_dma, d->regs + AST_VHUB_DEV_EP0_DATA);
>
> /* Clear stall on all EPs */
> - for (i = 0; i < AST_VHUB_NUM_GEN_EPs; i++) {
> + for (i = 0; i < d->max_epns; i++) {
> struct ast_vhub_ep *ep = d->epns[i];
>
> if (ep && (ep->epn.stalled || ep->epn.wedged)) {
> @@ -137,7 +137,7 @@ static int ast_vhub_ep_feature(struct ast_vhub_dev *d,
> is_set ? "SET" : "CLEAR", ep_num, wValue);
> if (ep_num == 0)
> return std_req_complete;
> - if (ep_num >= AST_VHUB_NUM_GEN_EPs || !d->epns[ep_num - 1])
> + if (ep_num >= d->max_epns || !d->epns[ep_num - 1])
> return std_req_stall;
> if (wValue != USB_ENDPOINT_HALT)
> return std_req_driver;
> @@ -181,7 +181,7 @@ static int ast_vhub_ep_status(struct ast_vhub_dev *d,
>
> DDBG(d, "GET_STATUS(ep%d)\n", ep_num);
>
> - if (ep_num >= AST_VHUB_NUM_GEN_EPs)
> + if (ep_num >= d->max_epns)
> return std_req_stall;
> if (ep_num != 0) {
> ep = d->epns[ep_num - 1];
> @@ -299,7 +299,7 @@ static void ast_vhub_dev_nuke(struct ast_vhub_dev *d)
> {
> unsigned int i;
>
> - for (i = 0; i < AST_VHUB_NUM_GEN_EPs; i++) {
> + for (i = 0; i < d->max_epns; i++) {
> if (!d->epns[i])
> continue;
> ast_vhub_nuke(d->epns[i], -ESHUTDOWN);
> @@ -416,10 +416,10 @@ static struct usb_ep *ast_vhub_udc_match_ep(struct usb_gadget *gadget,
> * that will allow the generic code to use our
> * assigned address.
> */
> - for (i = 0; i < AST_VHUB_NUM_GEN_EPs; i++)
> + for (i = 0; i < d->max_epns; i++)
> if (d->epns[i] == NULL)
> break;
> - if (i >= AST_VHUB_NUM_GEN_EPs)
> + if (i >= d->max_epns)
> return NULL;
> addr = i + 1;
>
> @@ -526,6 +526,7 @@ void ast_vhub_del_dev(struct ast_vhub_dev *d)
>
> usb_del_gadget_udc(&d->gadget);
> device_unregister(d->port_dev);
> + kfree(d->epns);
> }
>
> static void ast_vhub_dev_release(struct device *dev)
> @@ -546,14 +547,25 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
>
> ast_vhub_init_ep0(vhub, &d->ep0, d);
>
> + /*
> + * A USB device can have up to 30 endpoints besides control
> + * endpoint 0.
> + */
> + d->max_epns = min_t(u32, vhub->max_epns, 30);
> + d->epns = kcalloc(d->max_epns, sizeof(*d->epns), GFP_KERNEL);
> + if (!d->epns)
> + return -ENOMEM;
> +
> /*
> * The UDC core really needs us to have separate and uniquely
> * named "parent" devices for each port so we create a sub device
> * here for that purpose
> */
> d->port_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
> - if (!d->port_dev)
> - return -ENOMEM;
> + if (!d->port_dev) {
> + rc = -ENOMEM;
> + goto fail_alloc;
> + }
> device_initialize(d->port_dev);
> d->port_dev->release = ast_vhub_dev_release;
> d->port_dev->parent = parent;
> @@ -584,6 +596,8 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
> device_del(d->port_dev);
> fail_add:
> put_device(d->port_dev);
> + fail_alloc:
> + kfree(d->epns);
>
> return rc;
> }
> diff --git a/drivers/usb/gadget/udc/aspeed-vhub/epn.c b/drivers/usb/gadget/udc/aspeed-vhub/epn.c
> index 7475c74aa5c5..0bd6b20435b8 100644
> --- a/drivers/usb/gadget/udc/aspeed-vhub/epn.c
> +++ b/drivers/usb/gadget/udc/aspeed-vhub/epn.c
> @@ -800,10 +800,10 @@ struct ast_vhub_ep *ast_vhub_alloc_epn(struct ast_vhub_dev *d, u8 addr)
>
> /* Find a free one (no device) */
> spin_lock_irqsave(&vhub->lock, flags);
> - for (i = 0; i < AST_VHUB_NUM_GEN_EPs; i++)
> + for (i = 0; i < vhub->max_epns; i++)
> if (vhub->epns[i].dev == NULL)
> break;
> - if (i >= AST_VHUB_NUM_GEN_EPs) {
> + if (i >= vhub->max_epns) {
> spin_unlock_irqrestore(&vhub->lock, flags);
> return NULL;
> }
> diff --git a/drivers/usb/gadget/udc/aspeed-vhub/hub.c b/drivers/usb/gadget/udc/aspeed-vhub/hub.c
> index 9c3027306b15..6e565c3dbb5b 100644
> --- a/drivers/usb/gadget/udc/aspeed-vhub/hub.c
> +++ b/drivers/usb/gadget/udc/aspeed-vhub/hub.c
> @@ -502,7 +502,7 @@ static void ast_vhub_wake_work(struct work_struct *work)
> * we let the normal host wake path deal with it later.
> */
> spin_lock_irqsave(&vhub->lock, flags);
> - for (i = 0; i < AST_VHUB_NUM_PORTS; i++) {
> + for (i = 0; i < vhub->max_ports; i++) {
> struct ast_vhub_port *p = &vhub->ports[i];
>
> if (!(p->status & USB_PORT_STAT_SUSPEND))
> @@ -585,7 +585,7 @@ static enum std_req_rc ast_vhub_set_port_feature(struct ast_vhub_ep *ep,
> struct ast_vhub *vhub = ep->vhub;
> struct ast_vhub_port *p;
>
> - if (port == 0 || port > AST_VHUB_NUM_PORTS)
> + if (port == 0 || port > vhub->max_ports)
> return std_req_stall;
> port--;
> p = &vhub->ports[port];
> @@ -628,7 +628,7 @@ static enum std_req_rc ast_vhub_clr_port_feature(struct ast_vhub_ep *ep,
> struct ast_vhub *vhub = ep->vhub;
> struct ast_vhub_port *p;
>
> - if (port == 0 || port > AST_VHUB_NUM_PORTS)
> + if (port == 0 || port > vhub->max_ports)
> return std_req_stall;
> port--;
> p = &vhub->ports[port];
> @@ -674,7 +674,7 @@ static enum std_req_rc ast_vhub_get_port_stat(struct ast_vhub_ep *ep,
> struct ast_vhub *vhub = ep->vhub;
> u16 stat, chg;
>
> - if (port == 0 || port > AST_VHUB_NUM_PORTS)
> + if (port == 0 || port > vhub->max_ports)
> return std_req_stall;
> port--;
>
> @@ -755,7 +755,7 @@ void ast_vhub_hub_suspend(struct ast_vhub *vhub)
> * Forward to unsuspended ports without changing
> * their connection status.
> */
> - for (i = 0; i < AST_VHUB_NUM_PORTS; i++) {
> + for (i = 0; i < vhub->max_ports; i++) {
> struct ast_vhub_port *p = &vhub->ports[i];
>
> if (!(p->status & USB_PORT_STAT_SUSPEND))
> @@ -778,7 +778,7 @@ void ast_vhub_hub_resume(struct ast_vhub *vhub)
> * Forward to unsuspended ports without changing
> * their connection status.
> */
> - for (i = 0; i < AST_VHUB_NUM_PORTS; i++) {
> + for (i = 0; i < vhub->max_ports; i++) {
> struct ast_vhub_port *p = &vhub->ports[i];
>
> if (!(p->status & USB_PORT_STAT_SUSPEND))
> @@ -812,7 +812,7 @@ void ast_vhub_hub_reset(struct ast_vhub *vhub)
> * Clear all port status, disable gadgets and "suspend"
> * them. They will be woken up by a port reset.
> */
> - for (i = 0; i < AST_VHUB_NUM_PORTS; i++) {
> + for (i = 0; i < vhub->max_ports; i++) {
> struct ast_vhub_port *p = &vhub->ports[i];
>
> /* Only keep the connected flag */
> @@ -845,6 +845,7 @@ static void ast_vhub_init_desc(struct ast_vhub *vhub)
> /* Initialize vhub Hub Descriptor. */
> memcpy(&vhub->vhub_hub_desc, &ast_vhub_hub_desc,
> sizeof(vhub->vhub_hub_desc));
> + vhub->vhub_hub_desc.bNbrPorts = vhub->max_ports;
>
> /* Initialize vhub String Descriptors. */
> memcpy(&vhub->vhub_str_desc, &ast_vhub_strings,
> diff --git a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
> index 191f9fae7420..fac79ef6d669 100644
> --- a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
> +++ b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h
> @@ -79,17 +79,9 @@
> #define VHUB_SW_RESET_DEVICE2 (1 << 2)
> #define VHUB_SW_RESET_DEVICE1 (1 << 1)
> #define VHUB_SW_RESET_ROOT_HUB (1 << 0)
> -#define VHUB_SW_RESET_ALL (VHUB_SW_RESET_EP_POOL | \
> - VHUB_SW_RESET_DMA_CONTROLLER | \
> - VHUB_SW_RESET_DEVICE5 | \
> - VHUB_SW_RESET_DEVICE4 | \
> - VHUB_SW_RESET_DEVICE3 | \
> - VHUB_SW_RESET_DEVICE2 | \
> - VHUB_SW_RESET_DEVICE1 | \
> - VHUB_SW_RESET_ROOT_HUB)
> +
> /* EP ACK/NACK IRQ masks */
> #define VHUB_EP_IRQ(n) (1 << (n))
> -#define VHUB_EP_IRQ_ALL 0x7fff /* 15 EPs */
>
> /* USB status reg */
> #define VHUB_USBSTS_HISPEED (1 << 27)
> @@ -213,6 +205,11 @@
> * *
> ****************************************/
>
> +/*
> + * AST_VHUB_NUM_GEN_EPs and AST_VHUB_NUM_PORTS are kept to avoid breaking
> + * existing AST2400/AST2500 platforms. AST2600 and future vhub revisions
> + * should define number of downstream ports and endpoints in device tree.
> + */
> #define AST_VHUB_NUM_GEN_EPs 15 /* Generic non-0 EPs */
> #define AST_VHUB_NUM_PORTS 5 /* vHub ports */
> #define AST_VHUB_EP0_MAX_PACKET 64 /* EP0's max packet size */
> @@ -315,7 +312,7 @@ struct ast_vhub_ep {
> /* Registers */
> void __iomem *regs;
>
> - /* Index in global pool (0..14) */
> + /* Index in global pool (zero-based) */
> unsigned int g_idx;
>
> /* DMA Descriptors */
> @@ -345,7 +342,7 @@ struct ast_vhub_dev {
> struct ast_vhub *vhub;
> void __iomem *regs;
>
> - /* Device index (0...4) and name string */
> + /* Device index (zero-based) and name string */
> unsigned int index;
> const char *name;
>
> @@ -361,7 +358,8 @@ struct ast_vhub_dev {
>
> /* Endpoint structures */
> struct ast_vhub_ep ep0;
> - struct ast_vhub_ep *epns[AST_VHUB_NUM_GEN_EPs];
> + struct ast_vhub_ep **epns;
> + u32 max_epns;
>
> };
> #define to_ast_dev(__g) container_of(__g, struct ast_vhub_dev, gadget)
> @@ -402,10 +400,12 @@ struct ast_vhub {
> bool ep1_stalled : 1;
>
> /* Per-port info */
> - struct ast_vhub_port ports[AST_VHUB_NUM_PORTS];
> + struct ast_vhub_port *ports;
> + u32 max_ports;
>
> /* Generic EP data structures */
> - struct ast_vhub_ep epns[AST_VHUB_NUM_GEN_EPs];
> + struct ast_vhub_ep *epns;
> + u32 max_epns;
>
> /* Upstream bus is suspended ? */
> bool suspended : 1;
On Wed, 2020-02-26 at 15:03 -0800, [email protected] wrote:
> From: Tao Ren <[email protected]>
>
> Add USB components and according pin groups in aspeed-g6 dtsi.
>
> Signed-off-by: Tao Ren <[email protected]>
> Reviewed-by: Andrew Jeffery <[email protected]>
Acked-by: Benjamin Herrenschmidt <[email protected]>
> ---
> No change in v3/v4.
> Changes in v2:
> - added port/endpoint properties for vhub dt node.
>
> arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi | 25 +++++++++++++
> arch/arm/boot/dts/aspeed-g6.dtsi | 45
> ++++++++++++++++++++++++
> 2 files changed, 70 insertions(+)
>
> diff --git a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
> b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
> index 045ce66ca876..7028e21bdd98 100644
> --- a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
> +++ b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
> @@ -1112,6 +1112,31 @@
> groups = "UART9";
> };
>
> + pinctrl_usb2ah_default: usb2ah_default {
> + function = "USB2AH";
> + groups = "USBA";
> + };
> +
> + pinctrl_usb2ad_default: usb2ad_default {
> + function = "USB2AD";
> + groups = "USBA";
> + };
> +
> + pinctrl_usb2bh_default: usb2bh_default {
> + function = "USB2BH";
> + groups = "USBB";
> + };
> +
> + pinctrl_usb2bd_default: usb2bd_default {
> + function = "USB2BD";
> + groups = "USBB";
> + };
> +
> + pinctrl_usb11bhid_default: usb11bhid_default {
> + function = "USB11BHID";
> + groups = "USBB";
> + };
> +
> pinctrl_vb_default: vb_default {
> function = "VB";
> groups = "VB";
> diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi
> b/arch/arm/boot/dts/aspeed-g6.dtsi
> index 796976d275e1..0a29b3b57a9d 100644
> --- a/arch/arm/boot/dts/aspeed-g6.dtsi
> +++ b/arch/arm/boot/dts/aspeed-g6.dtsi
> @@ -245,6 +245,51 @@
> status = "disabled";
> };
>
> + ehci0: usb@1e6a1000 {
> + compatible = "aspeed,ast2600-ehci", "generic-
> ehci";
> + reg = <0x1e6a1000 0x100>;
> + interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_usb2ah_default>;
> + status = "disabled";
> + };
> +
> + ehci1: usb@1e6a3000 {
> + compatible = "aspeed,ast2600-ehci", "generic-
> ehci";
> + reg = <0x1e6a3000 0x100>;
> + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&syscon ASPEED_CLK_GATE_USBPORT2CLK>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_usb2bh_default>;
> + status = "disabled";
> + };
> +
> + uhci: usb@1e6b0000 {
> + compatible = "aspeed,ast2600-uhci", "generic-
> uhci";
> + reg = <0x1e6b0000 0x100>;
> + interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
> + #ports = <2>;
> + clocks = <&syscon ASPEED_CLK_GATE_USBUHCICLK>;
> + status = "disabled";
> + /*
> + * No default pinmux, it will follow EHCI, use
> an
> + * explicit pinmux override if EHCI is not
> enabled.
> + */
> + };
> +
> + vhub: usb-vhub@1e6a0000 {
> + compatible = "aspeed,ast2600-usb-vhub";
> + reg = <0x1e6a0000 0x350>;
> + interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
> + aspeed,vhub-downstream-ports = <7>;
> + aspeed,vhub-generic-endpoints = <21>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_usb2ad_default>;
> + status = "disabled";
> + };
> +
> apb {
> compatible = "simple-bus";
> #address-cells = <1>;
On Wed, 2020-02-26 at 15:03 -0800, [email protected] wrote:
> From: Tao Ren <[email protected]>
>
> Add AST2600 support in aspeed-vhub driver. There are 3 major
> differences
> between AST2500 and AST2600 vhub:
> - AST2600 supports 7 downstream ports while AST2500 supports 5.
> - AST2600 supports 21 generic endpoints while AST2500 supports 15.
> - EP0 data buffer's 8-byte DMA alignment restriction is removed
> from
> AST2600.
>
> Signed-off-by: Tao Ren <[email protected]>
> Reviewed-by: Andrew Jeffery <[email protected]>
Acked-by: Benjamin Herrenschmidt <[email protected]>
> ---
> No Change in v3/v4.
> Changes in v2:
> - removed "ast_vhub_config" related logic.
>
> drivers/usb/gadget/udc/aspeed-vhub/Kconfig | 4 ++--
> drivers/usb/gadget/udc/aspeed-vhub/core.c | 3 +++
> 2 files changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/usb/gadget/udc/aspeed-vhub/Kconfig
> b/drivers/usb/gadget/udc/aspeed-vhub/Kconfig
> index 83ba8a2eb6af..605500b19cf3 100644
> --- a/drivers/usb/gadget/udc/aspeed-vhub/Kconfig
> +++ b/drivers/usb/gadget/udc/aspeed-vhub/Kconfig
> @@ -4,5 +4,5 @@ config USB_ASPEED_VHUB
> depends on ARCH_ASPEED || COMPILE_TEST
> depends on USB_LIBCOMPOSITE
> help
> - USB peripheral controller for the Aspeed AST2500 family
> - SoCs supporting the "vHub" functionality and USB2.0
> + USB peripheral controller for the Aspeed AST2400, AST2500 and
> + AST2600 family SoCs supporting the "vHub" functionality and
> USB2.0
> diff --git a/drivers/usb/gadget/udc/aspeed-vhub/core.c
> b/drivers/usb/gadget/udc/aspeed-vhub/core.c
> index f8ab8e012f34..f8d35dd60c34 100644
> --- a/drivers/usb/gadget/udc/aspeed-vhub/core.c
> +++ b/drivers/usb/gadget/udc/aspeed-vhub/core.c
> @@ -423,6 +423,9 @@ static const struct of_device_id
> ast_vhub_dt_ids[] = {
> {
> .compatible = "aspeed,ast2500-usb-vhub",
> },
> + {
> + .compatible = "aspeed,ast2600-usb-vhub",
> + },
> { }
> };
> MODULE_DEVICE_TABLE(of, ast_vhub_dt_ids);
On Wed, 2020-02-26 at 15:03 -0800, [email protected] wrote:
> From: Tao Ren <[email protected]>
>
> Add "aspeed,vhub-downstream-ports" and "aspeed,vhub-generic-
> endpoints"
> properties to describe supported number of vhub ports and endpoints.
>
> Signed-off-by: Tao Ren <[email protected]>
Acked-by: Benjamin Herrenschmidt <[email protected]>
> ---
> No change in v2/v3/v4.
> - It's given v4 to align with the version of the patch series.
>
> arch/arm/boot/dts/aspeed-g4.dtsi | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi
> b/arch/arm/boot/dts/aspeed-g4.dtsi
> index 807a0fc20670..8e04303e8514 100644
> --- a/arch/arm/boot/dts/aspeed-g4.dtsi
> +++ b/arch/arm/boot/dts/aspeed-g4.dtsi
> @@ -164,6 +164,8 @@
> reg = <0x1e6a0000 0x300>;
> interrupts = <5>;
> clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
> + aspeed,vhub-downstream-ports = <5>;
> + aspeed,vhub-generic-endpoints = <15>;
> pinctrl-names = "default";
> pinctrl-0 = <&pinctrl_usb2d_default>;
> status = "disabled";
On Wed, 2020-02-26 at 15:03 -0800, [email protected] wrote:
> From: Tao Ren <[email protected]>
>
> Add "aspeed,vhub-downstream-ports" and "aspeed,vhub-generic-
> endpoints"
> properties to describe supported number of vhub ports and endpoints.
>
> Signed-off-by: Tao Ren <[email protected]>
Acked-by: Benjamin Herrenschmidt <[email protected]>
> ---
> No change in v2/v3/v4.
> - It's given v4 to align with the version of the patch series.
>
> arch/arm/boot/dts/aspeed-g5.dtsi | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi
> b/arch/arm/boot/dts/aspeed-g5.dtsi
> index ebec0fa8baa7..f12ec04d3cbc 100644
> --- a/arch/arm/boot/dts/aspeed-g5.dtsi
> +++ b/arch/arm/boot/dts/aspeed-g5.dtsi
> @@ -195,6 +195,8 @@
> reg = <0x1e6a0000 0x300>;
> interrupts = <5>;
> clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
> + aspeed,vhub-downstream-ports = <5>;
> + aspeed,vhub-generic-endpoints = <15>;
> pinctrl-names = "default";
> pinctrl-0 = <&pinctrl_usb2ad_default>;
> status = "disabled";
On Wed, 26 Feb 2020 at 23:04, <[email protected]> wrote:
>
> From: Tao Ren <[email protected]>
>
> Add device tree binding documentation for aspeed usb-vhub driver.
A nitpick: the bindings are supposed to describe hardware, so we would
say this patch adds documentation for the hardware
>
> Signed-off-by: Tao Ren <[email protected]>
Reviewed-by: Joel Stanley <[email protected]>
> ---
> No change in v2/v3/v4:
> - the patch is added to the patch series since v4.
>
> .../bindings/usb/aspeed,usb-vhub.yaml | 71 +++++++++++++++++++
> 1 file changed, 71 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml
>
> diff --git a/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml b/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml
> new file mode 100644
> index 000000000000..6ebae46641e5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml
> @@ -0,0 +1,71 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# Copyright (c) 2020 Facebook Inc.
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/usb/aspeed,usb-vhub.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ASPEED USB 2.0 Virtual Hub Controller
> +
> +maintainers:
> + - Felipe Balbi <[email protected]>
> +
> +description: |+
> + The ASPEED USB 2.0 Virtual Hub Controller implements 1 set of USB Hub
> + register and several sets of Device and Endpoint registers to support
> + the Virtual Hub's downstream USB devices.
> +
> + Supported number of devices and endpoints vary depending on hardware
> + revisions. AST2400 and AST2500 Virtual Hub supports 5 downstream devices
> + and 15 generic endpoints, while AST2600 Virtual Hub supports 7 downstream
> + devices and 21 generic endpoints.
> +
> +properties:
> + compatible:
> + enum:
> + - aspeed,ast2400-usb-vhub
> + - aspeed,ast2500-usb-vhub
> + - aspeed,ast2600-usb-vhub
> +
> + reg:
> + maxItems: 1
> + description: Common configuration registers
> +
> + clocks:
> + maxItems: 1
> + description: The Virtual Hub Controller clock gate
> +
> + interrupts:
> + maxItems: 1
> +
> + aspeed,vhub-downstream-ports:
> + description: Number of downstream ports supported by the Virtual Hub
> + allOf:
> + - $ref: /schemas/types.yaml#/definitions/uint32
> +
> + aspeed,vhub-generic-endpoints:
> + description: Number of generic endpoints supported by the Virtual Hub
> + allOf:
> + - $ref: /schemas/types.yaml#/definitions/uint32
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> + - interrupts
> + - aspeed,vhub-downstream-ports
> + - aspeed,vhub-generic-endpoints
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/clock/aspeed-clock.h>
> + vhub: usb-vhub@1e6a0000 {
> + compatible = "aspeed,ast2500-usb-vhub";
> + reg = <0x1e6a0000 0x300>;
> + interrupts = <5>;
> + clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_usb2ad_default>;
> + };
> --
> 2.17.1
>
On Thu, 27 Feb 2020 at 04:10, Benjamin Herrenschmidt
<[email protected]> wrote:
>
> On Wed, 2020-02-26 at 15:03 -0800, [email protected] wrote:
> > From: Tao Ren <[email protected]>
> >
> > Add USB components and according pin groups in aspeed-g6 dtsi.
> >
> > Signed-off-by: Tao Ren <[email protected]>
> > Reviewed-by: Andrew Jeffery <[email protected]>
>
> Acked-by: Benjamin Herrenschmidt <[email protected]>
Reviewed-by: Joel Stanley <[email protected]>
I will take this patch through the aspeed tree for 5.7.
Cheers,
Joel
>
> > ---
> > No change in v3/v4.
> > Changes in v2:
> > - added port/endpoint properties for vhub dt node.
> >
> > arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi | 25 +++++++++++++
> > arch/arm/boot/dts/aspeed-g6.dtsi | 45
> > ++++++++++++++++++++++++
> > 2 files changed, 70 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
> > b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
> > index 045ce66ca876..7028e21bdd98 100644
> > --- a/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
> > +++ b/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi
> > @@ -1112,6 +1112,31 @@
> > groups = "UART9";
> > };
> >
> > + pinctrl_usb2ah_default: usb2ah_default {
> > + function = "USB2AH";
> > + groups = "USBA";
> > + };
> > +
> > + pinctrl_usb2ad_default: usb2ad_default {
> > + function = "USB2AD";
> > + groups = "USBA";
> > + };
> > +
> > + pinctrl_usb2bh_default: usb2bh_default {
> > + function = "USB2BH";
> > + groups = "USBB";
> > + };
> > +
> > + pinctrl_usb2bd_default: usb2bd_default {
> > + function = "USB2BD";
> > + groups = "USBB";
> > + };
> > +
> > + pinctrl_usb11bhid_default: usb11bhid_default {
> > + function = "USB11BHID";
> > + groups = "USBB";
> > + };
> > +
> > pinctrl_vb_default: vb_default {
> > function = "VB";
> > groups = "VB";
> > diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi
> > b/arch/arm/boot/dts/aspeed-g6.dtsi
> > index 796976d275e1..0a29b3b57a9d 100644
> > --- a/arch/arm/boot/dts/aspeed-g6.dtsi
> > +++ b/arch/arm/boot/dts/aspeed-g6.dtsi
> > @@ -245,6 +245,51 @@
> > status = "disabled";
> > };
> >
> > + ehci0: usb@1e6a1000 {
> > + compatible = "aspeed,ast2600-ehci", "generic-
> > ehci";
> > + reg = <0x1e6a1000 0x100>;
> > + interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pinctrl_usb2ah_default>;
> > + status = "disabled";
> > + };
> > +
> > + ehci1: usb@1e6a3000 {
> > + compatible = "aspeed,ast2600-ehci", "generic-
> > ehci";
> > + reg = <0x1e6a3000 0x100>;
> > + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&syscon ASPEED_CLK_GATE_USBPORT2CLK>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pinctrl_usb2bh_default>;
> > + status = "disabled";
> > + };
> > +
> > + uhci: usb@1e6b0000 {
> > + compatible = "aspeed,ast2600-uhci", "generic-
> > uhci";
> > + reg = <0x1e6b0000 0x100>;
> > + interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
> > + #ports = <2>;
> > + clocks = <&syscon ASPEED_CLK_GATE_USBUHCICLK>;
> > + status = "disabled";
> > + /*
> > + * No default pinmux, it will follow EHCI, use
> > an
> > + * explicit pinmux override if EHCI is not
> > enabled.
> > + */
> > + };
> > +
> > + vhub: usb-vhub@1e6a0000 {
> > + compatible = "aspeed,ast2600-usb-vhub";
> > + reg = <0x1e6a0000 0x350>;
> > + interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
> > + aspeed,vhub-downstream-ports = <7>;
> > + aspeed,vhub-generic-endpoints = <21>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&pinctrl_usb2ad_default>;
> > + status = "disabled";
> > + };
> > +
> > apb {
> > compatible = "simple-bus";
> > #address-cells = <1>;
>
On Thu, 27 Feb 2020 at 04:11, Benjamin Herrenschmidt
<[email protected]> wrote:
>
> On Wed, 2020-02-26 at 15:03 -0800, [email protected] wrote:
> > From: Tao Ren <[email protected]>
> >
> > Add "aspeed,vhub-downstream-ports" and "aspeed,vhub-generic-
> > endpoints"
> > properties to describe supported number of vhub ports and endpoints.
> >
> > Signed-off-by: Tao Ren <[email protected]>
>
> Acked-by: Benjamin Herrenschmidt <[email protected]>
Reviewed-by: Joel Stanley <[email protected]>
I will take this patch through the aspeed tree for 5.7.
Cheers,
Joel
>
> > ---
> > No change in v2/v3/v4.
> > - It's given v4 to align with the version of the patch series.
> >
> > arch/arm/boot/dts/aspeed-g5.dtsi | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi
> > b/arch/arm/boot/dts/aspeed-g5.dtsi
> > index ebec0fa8baa7..f12ec04d3cbc 100644
> > --- a/arch/arm/boot/dts/aspeed-g5.dtsi
> > +++ b/arch/arm/boot/dts/aspeed-g5.dtsi
> > @@ -195,6 +195,8 @@
> > reg = <0x1e6a0000 0x300>;
> > interrupts = <5>;
> > clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
> > + aspeed,vhub-downstream-ports = <5>;
> > + aspeed,vhub-generic-endpoints = <15>;
> > pinctrl-names = "default";
> > pinctrl-0 = <&pinctrl_usb2ad_default>;
> > status = "disabled";
>
On Thu, 27 Feb 2020 at 04:11, Benjamin Herrenschmidt
<[email protected]> wrote:
>
> On Wed, 2020-02-26 at 15:03 -0800, [email protected] wrote:
> > From: Tao Ren <[email protected]>
> >
> > Add "aspeed,vhub-downstream-ports" and "aspeed,vhub-generic-
> > endpoints"
> > properties to describe supported number of vhub ports and endpoints.
> >
> > Signed-off-by: Tao Ren <[email protected]>
>
> Acked-by: Benjamin Herrenschmidt <[email protected]>
Reviewed-by: Joel Stanley <[email protected]>
I will take this patch through the aspeed tree for 5.7.
Cheers,
Joel
>
>
> > ---
> > No change in v2/v3/v4.
> > - It's given v4 to align with the version of the patch series.
> >
> > arch/arm/boot/dts/aspeed-g4.dtsi | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi
> > b/arch/arm/boot/dts/aspeed-g4.dtsi
> > index 807a0fc20670..8e04303e8514 100644
> > --- a/arch/arm/boot/dts/aspeed-g4.dtsi
> > +++ b/arch/arm/boot/dts/aspeed-g4.dtsi
> > @@ -164,6 +164,8 @@
> > reg = <0x1e6a0000 0x300>;
> > interrupts = <5>;
> > clocks = <&syscon ASPEED_CLK_GATE_USBPORT1CLK>;
> > + aspeed,vhub-downstream-ports = <5>;
> > + aspeed,vhub-generic-endpoints = <15>;
> > pinctrl-names = "default";
> > pinctrl-0 = <&pinctrl_usb2d_default>;
> > status = "disabled";
>
On Wed, 26 Feb 2020 15:03:46 -0800, [email protected] wrote:
> From: Tao Ren <[email protected]>
>
> Add device tree binding documentation for aspeed usb-vhub driver.
>
> Signed-off-by: Tao Ren <[email protected]>
> ---
> No change in v2/v3/v4:
> - the patch is added to the patch series since v4.
>
> .../bindings/usb/aspeed,usb-vhub.yaml | 71 +++++++++++++++++++
> 1 file changed, 71 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml
>
My bot found errors running 'make dt_binding_check' on your patch:
Documentation/devicetree/bindings/display/simple-framebuffer.example.dts:21.16-37.11: Warning (chosen_node_is_root): /example-0/chosen: chosen node must be at root node
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.example.dt.yaml: usb-vhub@1e6a0000: 'aspeed,vhub-downstream-ports' is a required property
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.example.dt.yaml: usb-vhub@1e6a0000: 'aspeed,vhub-generic-endpoints' is a required property
See https://patchwork.ozlabs.org/patch/1245388
Please check and re-submit.
Hi Ben,
On Thu, Feb 27, 2020 at 03:09:01PM +1100, Benjamin Herrenschmidt wrote:
> On Wed, 2020-02-26 at 15:03 -0800, [email protected] wrote:
> > From: Tao Ren <[email protected]>
> >
> > The patch introduces 2 DT properties ("aspeed,vhub-downstream-ports" and
> > "aspeed,vhub-generic-endpoints") which replaces hardcoded port/endpoint
> > number. It is to make it more convenient to add support for newer vhub
> > revisions with different number of ports and endpoints.
> >
> > Signed-off-by: Tao Ren <[email protected]>
> > Reviewed-by: Joel Stanley <[email protected]>
>
> With one minor nit that can be addressed in a subsequent patch (see
> below)
>
> Acked-by: Benjamin Herrenschmidt <[email protected]>
Thanks for the help on the patch series.
> > - if (istat & VHUB_IRQ_DEVICE3)
> > - ast_vhub_dev_irq(&vhub->ports[2].dev);
> > - if (istat & VHUB_IRQ_DEVICE4)
> > - ast_vhub_dev_irq(&vhub->ports[3].dev);
> > - if (istat & VHUB_IRQ_DEVICE5)
> > - ast_vhub_dev_irq(&vhub->ports[4].dev);
> > + for (i = 0; i < vhub->max_ports; i++) {
> > + u32 dev_mask = VHUB_IRQ_DEVICE1 << i;
> > +
> > + if (istat & dev_mask)
> > + ast_vhub_dev_irq(&vhub->ports[i].dev);
> > }
>
> The 2400 and 2500 have very slow cores and every cycle counts in that
> interrupt handler from my experience. I would sugggest you generate a
> "mask" of all the device interrupts for enabled ports in struct vhub
> and AND istat with that mask before going through the loop. Either that
> or use find_next_zero_bit...
>
> I wouldn't gate merging this patch on this, it can be a subsequent
> refinement.
Got it. I will take care of the improvement in a follow-up patch.
Cheers,
Tao
On Thu, Feb 27, 2020 at 05:54:34AM +0000, Joel Stanley wrote:
> On Thu, 27 Feb 2020 at 04:11, Benjamin Herrenschmidt
> <[email protected]> wrote:
> >
> > On Wed, 2020-02-26 at 15:03 -0800, [email protected] wrote:
> > > From: Tao Ren <[email protected]>
> > >
> > > Add "aspeed,vhub-downstream-ports" and "aspeed,vhub-generic-
> > > endpoints"
> > > properties to describe supported number of vhub ports and endpoints.
> > >
> > > Signed-off-by: Tao Ren <[email protected]>
> >
> > Acked-by: Benjamin Herrenschmidt <[email protected]>
>
> Reviewed-by: Joel Stanley <[email protected]>
>
> I will take this patch through the aspeed tree for 5.7.
>
> Cheers,
>
> Joel
Thanks Joel for the continued support!
Cheers,
Tao
Hi Rob,
On Thu, Feb 27, 2020 at 10:55:04AM -0600, Rob Herring wrote:
> On Wed, 26 Feb 2020 15:03:46 -0800, [email protected] wrote:
> > From: Tao Ren <[email protected]>
> >
> > Add device tree binding documentation for aspeed usb-vhub driver.
> >
> > Signed-off-by: Tao Ren <[email protected]>
> > ---
> > No change in v2/v3/v4:
> > - the patch is added to the patch series since v4.
> >
> > .../bindings/usb/aspeed,usb-vhub.yaml | 71 +++++++++++++++++++
> > 1 file changed, 71 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml
> >
>
> My bot found errors running 'make dt_binding_check' on your patch:
>
> Documentation/devicetree/bindings/display/simple-framebuffer.example.dts:21.16-37.11: Warning (chosen_node_is_root): /example-0/chosen: chosen node must be at root node
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.example.dt.yaml: usb-vhub@1e6a0000: 'aspeed,vhub-downstream-ports' is a required property
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.example.dt.yaml: usb-vhub@1e6a0000: 'aspeed,vhub-generic-endpoints' is a required property
>
> See https://patchwork.ozlabs.org/patch/1245388
> Please check and re-submit.
I ran "make dt_binding_check" in my local environment and don't see the
failures. The 2 properties are introduced in this patch set and I add
the properties in aspeed-g4/5/6 dtsi files (patch #4, #5 and #6): am I
missing something?
Sorry I forgot to add you when including the dt-binding document to the
series v4: will add you and all dt binding maintainers in v5 soon.
Cheers,
Tao
Hi Rob,
On Thu, Feb 27, 2020 at 02:42:51PM -0800, Tao Ren wrote:
> Sorry I forgot to add you when including the dt-binding document to the
> series v4: will add you and all dt binding maintainers in v5 soon.
Just realized I already added you for the previous patch versions. Sorry
about the noise.
Cheers,
Tao
Hi Rob,
On Thu, Feb 27, 2020 at 02:42:51PM -0800, Tao Ren wrote:
> > My bot found errors running 'make dt_binding_check' on your patch:
> >
> > Documentation/devicetree/bindings/display/simple-framebuffer.example.dts:21.16-37.11: Warning (chosen_node_is_root): /example-0/chosen: chosen node must be at root node
> > /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.example.dt.yaml: usb-vhub@1e6a0000: 'aspeed,vhub-downstream-ports' is a required property
> > /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.example.dt.yaml: usb-vhub@1e6a0000: 'aspeed,vhub-generic-endpoints' is a required property
> >
> > See https://patchwork.ozlabs.org/patch/1245388
> > Please check and re-submit.
>
> I ran "make dt_binding_check" in my local environment and don't see the
> failures. The 2 properties are introduced in this patch set and I add
> the properties in aspeed-g4/5/6 dtsi files (patch #4, #5 and #6): am I
> missing something?
I think I missed "libyaml-dev" package. I've reproduced the error in my
environment and added the 2 required properties in patch v6.
Cheers,
Tao