Commit 487bc828 authored by Tao Ren's avatar Tao Ren Committed by Felipe Balbi

usb: gadget: aspeed: read vhub properties from device tree

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: default avatarTao Ren <rentao.bupt@gmail.com>
Reviewed-by: default avatarJoel Stanley <joel@jms.id.au>
Acked-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarFelipe Balbi <balbi@kernel.org>
parent 6dbf05fc
...@@ -99,7 +99,7 @@ static irqreturn_t ast_vhub_irq(int irq, void *data) ...@@ -99,7 +99,7 @@ static irqreturn_t ast_vhub_irq(int irq, void *data)
{ {
struct ast_vhub *vhub = data; struct ast_vhub *vhub = data;
irqreturn_t iret = IRQ_NONE; irqreturn_t iret = IRQ_NONE;
u32 istat; u32 i, istat;
/* Stale interrupt while tearing down */ /* Stale interrupt while tearing down */
if (!vhub->ep0_bufs) if (!vhub->ep0_bufs)
...@@ -121,10 +121,10 @@ static irqreturn_t ast_vhub_irq(int irq, void *data) ...@@ -121,10 +121,10 @@ static irqreturn_t ast_vhub_irq(int irq, void *data)
/* Handle generic EPs first */ /* Handle generic EPs first */
if (istat & VHUB_IRQ_EP_POOL_ACK_STALL) { 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); 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); u32 mask = VHUB_EP_IRQ(i);
if (ep_acks & mask) { if (ep_acks & mask) {
ast_vhub_epn_ack_irq(&vhub->epns[i]); ast_vhub_epn_ack_irq(&vhub->epns[i]);
...@@ -134,21 +134,11 @@ static irqreturn_t ast_vhub_irq(int irq, void *data) ...@@ -134,21 +134,11 @@ static irqreturn_t ast_vhub_irq(int irq, void *data)
} }
/* Handle device interrupts */ /* Handle device interrupts */
if (istat & (VHUB_IRQ_DEVICE1 | for (i = 0; i < vhub->max_ports; i++) {
VHUB_IRQ_DEVICE2 | u32 dev_mask = VHUB_IRQ_DEVICE1 << i;
VHUB_IRQ_DEVICE3 |
VHUB_IRQ_DEVICE4 | if (istat & dev_mask)
VHUB_IRQ_DEVICE5)) { ast_vhub_dev_irq(&vhub->ports[i].dev);
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);
} }
/* Handle top-level vHub EP0 interrupts */ /* Handle top-level vHub EP0 interrupts */
...@@ -182,7 +172,7 @@ static irqreturn_t ast_vhub_irq(int irq, void *data) ...@@ -182,7 +172,7 @@ static irqreturn_t ast_vhub_irq(int irq, void *data)
void ast_vhub_init_hw(struct ast_vhub *vhub) void ast_vhub_init_hw(struct ast_vhub *vhub)
{ {
u32 ctrl; u32 ctrl, port_mask, epn_mask;
UDCDBG(vhub,"(Re)Starting HW ...\n"); UDCDBG(vhub,"(Re)Starting HW ...\n");
...@@ -222,15 +212,20 @@ void ast_vhub_init_hw(struct ast_vhub *vhub) ...@@ -222,15 +212,20 @@ void ast_vhub_init_hw(struct ast_vhub *vhub)
} }
/* Reset all devices */ /* 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); udelay(1);
writel(0, vhub->regs + AST_VHUB_SW_RESET); writel(0, vhub->regs + AST_VHUB_SW_RESET);
/* Disable and cleanup EP ACK/NACK interrupts */ /* 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_ACK_IER);
writel(0, vhub->regs + AST_VHUB_EP_NACK_IER); writel(0, vhub->regs + AST_VHUB_EP_NACK_IER);
writel(VHUB_EP_IRQ_ALL, vhub->regs + AST_VHUB_EP_ACK_ISR); writel(epn_mask, 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_NACK_ISR);
/* Default settings for EP0, enable HW hub EP1 */ /* Default settings for EP0, enable HW hub EP1 */
writel(0, vhub->regs + AST_VHUB_EP0_CTRL); writel(0, vhub->regs + AST_VHUB_EP0_CTRL);
...@@ -273,7 +268,7 @@ static int ast_vhub_remove(struct platform_device *pdev) ...@@ -273,7 +268,7 @@ static int ast_vhub_remove(struct platform_device *pdev)
return 0; return 0;
/* Remove devices */ /* 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); ast_vhub_del_dev(&vhub->ports[i].dev);
spin_lock_irqsave(&vhub->lock, flags); spin_lock_irqsave(&vhub->lock, flags);
...@@ -295,7 +290,7 @@ static int ast_vhub_remove(struct platform_device *pdev) ...@@ -295,7 +290,7 @@ static int ast_vhub_remove(struct platform_device *pdev)
if (vhub->ep0_bufs) if (vhub->ep0_bufs)
dma_free_coherent(&pdev->dev, dma_free_coherent(&pdev->dev,
AST_VHUB_EP0_MAX_PACKET * AST_VHUB_EP0_MAX_PACKET *
(AST_VHUB_NUM_PORTS + 1), (vhub->max_ports + 1),
vhub->ep0_bufs, vhub->ep0_bufs,
vhub->ep0_bufs_dma); vhub->ep0_bufs_dma);
vhub->ep0_bufs = NULL; vhub->ep0_bufs = NULL;
...@@ -309,11 +304,32 @@ static int ast_vhub_probe(struct platform_device *pdev) ...@@ -309,11 +304,32 @@ static int ast_vhub_probe(struct platform_device *pdev)
struct ast_vhub *vhub; struct ast_vhub *vhub;
struct resource *res; struct resource *res;
int i, rc = 0; int i, rc = 0;
const struct device_node *np = pdev->dev.of_node;
vhub = devm_kzalloc(&pdev->dev, sizeof(*vhub), GFP_KERNEL); vhub = devm_kzalloc(&pdev->dev, sizeof(*vhub), GFP_KERNEL);
if (!vhub) if (!vhub)
return -ENOMEM; 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); spin_lock_init(&vhub->lock);
vhub->pdev = pdev; vhub->pdev = pdev;
...@@ -366,7 +382,7 @@ static int ast_vhub_probe(struct platform_device *pdev) ...@@ -366,7 +382,7 @@ static int ast_vhub_probe(struct platform_device *pdev)
*/ */
vhub->ep0_bufs = dma_alloc_coherent(&pdev->dev, vhub->ep0_bufs = dma_alloc_coherent(&pdev->dev,
AST_VHUB_EP0_MAX_PACKET * AST_VHUB_EP0_MAX_PACKET *
(AST_VHUB_NUM_PORTS + 1), (vhub->max_ports + 1),
&vhub->ep0_bufs_dma, GFP_KERNEL); &vhub->ep0_bufs_dma, GFP_KERNEL);
if (!vhub->ep0_bufs) { if (!vhub->ep0_bufs) {
dev_err(&pdev->dev, "Failed to allocate EP0 DMA buffers\n"); dev_err(&pdev->dev, "Failed to allocate EP0 DMA buffers\n");
...@@ -380,7 +396,7 @@ static int ast_vhub_probe(struct platform_device *pdev) ...@@ -380,7 +396,7 @@ static int ast_vhub_probe(struct platform_device *pdev)
ast_vhub_init_ep0(vhub, &vhub->ep0, NULL); ast_vhub_init_ep0(vhub, &vhub->ep0, NULL);
/* Init devices */ /* 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); rc = ast_vhub_init_dev(vhub, i);
if (rc) if (rc)
goto err; goto err;
......
...@@ -77,7 +77,7 @@ static void ast_vhub_dev_enable(struct ast_vhub_dev *d) ...@@ -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); writel(d->ep0.buf_dma, d->regs + AST_VHUB_DEV_EP0_DATA);
/* Clear stall on all EPs */ /* 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]; struct ast_vhub_ep *ep = d->epns[i];
if (ep && (ep->epn.stalled || ep->epn.wedged)) { if (ep && (ep->epn.stalled || ep->epn.wedged)) {
...@@ -137,7 +137,7 @@ static int ast_vhub_ep_feature(struct ast_vhub_dev *d, ...@@ -137,7 +137,7 @@ static int ast_vhub_ep_feature(struct ast_vhub_dev *d,
is_set ? "SET" : "CLEAR", ep_num, wValue); is_set ? "SET" : "CLEAR", ep_num, wValue);
if (ep_num == 0) if (ep_num == 0)
return std_req_complete; 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; return std_req_stall;
if (wValue != USB_ENDPOINT_HALT) if (wValue != USB_ENDPOINT_HALT)
return std_req_driver; return std_req_driver;
...@@ -181,7 +181,7 @@ static int ast_vhub_ep_status(struct ast_vhub_dev *d, ...@@ -181,7 +181,7 @@ static int ast_vhub_ep_status(struct ast_vhub_dev *d,
DDBG(d, "GET_STATUS(ep%d)\n", ep_num); 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; return std_req_stall;
if (ep_num != 0) { if (ep_num != 0) {
ep = d->epns[ep_num - 1]; ep = d->epns[ep_num - 1];
...@@ -299,7 +299,7 @@ static void ast_vhub_dev_nuke(struct ast_vhub_dev *d) ...@@ -299,7 +299,7 @@ static void ast_vhub_dev_nuke(struct ast_vhub_dev *d)
{ {
unsigned int i; 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]) if (!d->epns[i])
continue; continue;
ast_vhub_nuke(d->epns[i], -ESHUTDOWN); ast_vhub_nuke(d->epns[i], -ESHUTDOWN);
...@@ -416,10 +416,10 @@ static struct usb_ep *ast_vhub_udc_match_ep(struct usb_gadget *gadget, ...@@ -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 * that will allow the generic code to use our
* assigned address. * 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) if (d->epns[i] == NULL)
break; break;
if (i >= AST_VHUB_NUM_GEN_EPs) if (i >= d->max_epns)
return NULL; return NULL;
addr = i + 1; addr = i + 1;
...@@ -526,6 +526,7 @@ void ast_vhub_del_dev(struct ast_vhub_dev *d) ...@@ -526,6 +526,7 @@ void ast_vhub_del_dev(struct ast_vhub_dev *d)
usb_del_gadget_udc(&d->gadget); usb_del_gadget_udc(&d->gadget);
device_unregister(d->port_dev); device_unregister(d->port_dev);
kfree(d->epns);
} }
static void ast_vhub_dev_release(struct device *dev) 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) ...@@ -546,14 +547,25 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
ast_vhub_init_ep0(vhub, &d->ep0, d); 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 * The UDC core really needs us to have separate and uniquely
* named "parent" devices for each port so we create a sub device * named "parent" devices for each port so we create a sub device
* here for that purpose * here for that purpose
*/ */
d->port_dev = kzalloc(sizeof(struct device), GFP_KERNEL); d->port_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
if (!d->port_dev) if (!d->port_dev) {
return -ENOMEM; rc = -ENOMEM;
goto fail_alloc;
}
device_initialize(d->port_dev); device_initialize(d->port_dev);
d->port_dev->release = ast_vhub_dev_release; d->port_dev->release = ast_vhub_dev_release;
d->port_dev->parent = parent; d->port_dev->parent = parent;
...@@ -584,6 +596,8 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx) ...@@ -584,6 +596,8 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
device_del(d->port_dev); device_del(d->port_dev);
fail_add: fail_add:
put_device(d->port_dev); put_device(d->port_dev);
fail_alloc:
kfree(d->epns);
return rc; return rc;
} }
...@@ -800,10 +800,10 @@ struct ast_vhub_ep *ast_vhub_alloc_epn(struct ast_vhub_dev *d, u8 addr) ...@@ -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) */ /* Find a free one (no device) */
spin_lock_irqsave(&vhub->lock, flags); 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) if (vhub->epns[i].dev == NULL)
break; break;
if (i >= AST_VHUB_NUM_GEN_EPs) { if (i >= vhub->max_epns) {
spin_unlock_irqrestore(&vhub->lock, flags); spin_unlock_irqrestore(&vhub->lock, flags);
return NULL; return NULL;
} }
......
...@@ -502,7 +502,7 @@ static void ast_vhub_wake_work(struct work_struct *work) ...@@ -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. * we let the normal host wake path deal with it later.
*/ */
spin_lock_irqsave(&vhub->lock, flags); 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]; struct ast_vhub_port *p = &vhub->ports[i];
if (!(p->status & USB_PORT_STAT_SUSPEND)) 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, ...@@ -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 *vhub = ep->vhub;
struct ast_vhub_port *p; struct ast_vhub_port *p;
if (port == 0 || port > AST_VHUB_NUM_PORTS) if (port == 0 || port > vhub->max_ports)
return std_req_stall; return std_req_stall;
port--; port--;
p = &vhub->ports[port]; p = &vhub->ports[port];
...@@ -628,7 +628,7 @@ static enum std_req_rc ast_vhub_clr_port_feature(struct ast_vhub_ep *ep, ...@@ -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 *vhub = ep->vhub;
struct ast_vhub_port *p; struct ast_vhub_port *p;
if (port == 0 || port > AST_VHUB_NUM_PORTS) if (port == 0 || port > vhub->max_ports)
return std_req_stall; return std_req_stall;
port--; port--;
p = &vhub->ports[port]; p = &vhub->ports[port];
...@@ -674,7 +674,7 @@ static enum std_req_rc ast_vhub_get_port_stat(struct ast_vhub_ep *ep, ...@@ -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; struct ast_vhub *vhub = ep->vhub;
u16 stat, chg; u16 stat, chg;
if (port == 0 || port > AST_VHUB_NUM_PORTS) if (port == 0 || port > vhub->max_ports)
return std_req_stall; return std_req_stall;
port--; port--;
...@@ -755,7 +755,7 @@ void ast_vhub_hub_suspend(struct ast_vhub *vhub) ...@@ -755,7 +755,7 @@ void ast_vhub_hub_suspend(struct ast_vhub *vhub)
* Forward to unsuspended ports without changing * Forward to unsuspended ports without changing
* their connection status. * 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]; struct ast_vhub_port *p = &vhub->ports[i];
if (!(p->status & USB_PORT_STAT_SUSPEND)) if (!(p->status & USB_PORT_STAT_SUSPEND))
...@@ -778,7 +778,7 @@ void ast_vhub_hub_resume(struct ast_vhub *vhub) ...@@ -778,7 +778,7 @@ void ast_vhub_hub_resume(struct ast_vhub *vhub)
* Forward to unsuspended ports without changing * Forward to unsuspended ports without changing
* their connection status. * 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]; struct ast_vhub_port *p = &vhub->ports[i];
if (!(p->status & USB_PORT_STAT_SUSPEND)) if (!(p->status & USB_PORT_STAT_SUSPEND))
...@@ -812,7 +812,7 @@ void ast_vhub_hub_reset(struct ast_vhub *vhub) ...@@ -812,7 +812,7 @@ void ast_vhub_hub_reset(struct ast_vhub *vhub)
* Clear all port status, disable gadgets and "suspend" * Clear all port status, disable gadgets and "suspend"
* them. They will be woken up by a port reset. * 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]; struct ast_vhub_port *p = &vhub->ports[i];
/* Only keep the connected flag */ /* Only keep the connected flag */
...@@ -845,6 +845,7 @@ static void ast_vhub_init_desc(struct ast_vhub *vhub) ...@@ -845,6 +845,7 @@ static void ast_vhub_init_desc(struct ast_vhub *vhub)
/* Initialize vhub Hub Descriptor. */ /* Initialize vhub Hub Descriptor. */
memcpy(&vhub->vhub_hub_desc, &ast_vhub_hub_desc, memcpy(&vhub->vhub_hub_desc, &ast_vhub_hub_desc,
sizeof(vhub->vhub_hub_desc)); sizeof(vhub->vhub_hub_desc));
vhub->vhub_hub_desc.bNbrPorts = vhub->max_ports;
/* Initialize vhub String Descriptors. */ /* Initialize vhub String Descriptors. */
memcpy(&vhub->vhub_str_desc, &ast_vhub_strings, memcpy(&vhub->vhub_str_desc, &ast_vhub_strings,
......
...@@ -79,17 +79,9 @@ ...@@ -79,17 +79,9 @@
#define VHUB_SW_RESET_DEVICE2 (1 << 2) #define VHUB_SW_RESET_DEVICE2 (1 << 2)
#define VHUB_SW_RESET_DEVICE1 (1 << 1) #define VHUB_SW_RESET_DEVICE1 (1 << 1)
#define VHUB_SW_RESET_ROOT_HUB (1 << 0) #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 */ /* EP ACK/NACK IRQ masks */
#define VHUB_EP_IRQ(n) (1 << (n)) #define VHUB_EP_IRQ(n) (1 << (n))
#define VHUB_EP_IRQ_ALL 0x7fff /* 15 EPs */
/* USB status reg */ /* USB status reg */
#define VHUB_USBSTS_HISPEED (1 << 27) #define VHUB_USBSTS_HISPEED (1 << 27)
...@@ -213,6 +205,11 @@ ...@@ -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_GEN_EPs 15 /* Generic non-0 EPs */
#define AST_VHUB_NUM_PORTS 5 /* vHub ports */ #define AST_VHUB_NUM_PORTS 5 /* vHub ports */
#define AST_VHUB_EP0_MAX_PACKET 64 /* EP0's max packet size */ #define AST_VHUB_EP0_MAX_PACKET 64 /* EP0's max packet size */
...@@ -315,7 +312,7 @@ struct ast_vhub_ep { ...@@ -315,7 +312,7 @@ struct ast_vhub_ep {
/* Registers */ /* Registers */
void __iomem *regs; void __iomem *regs;
/* Index in global pool (0..14) */ /* Index in global pool (zero-based) */
unsigned int g_idx; unsigned int g_idx;
/* DMA Descriptors */ /* DMA Descriptors */
...@@ -345,7 +342,7 @@ struct ast_vhub_dev { ...@@ -345,7 +342,7 @@ struct ast_vhub_dev {
struct ast_vhub *vhub; struct ast_vhub *vhub;
void __iomem *regs; void __iomem *regs;
/* Device index (0...4) and name string */ /* Device index (zero-based) and name string */
unsigned int index; unsigned int index;
const char *name; const char *name;
...@@ -361,7 +358,8 @@ struct ast_vhub_dev { ...@@ -361,7 +358,8 @@ struct ast_vhub_dev {
/* Endpoint structures */ /* Endpoint structures */
struct ast_vhub_ep ep0; 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) #define to_ast_dev(__g) container_of(__g, struct ast_vhub_dev, gadget)
...@@ -402,10 +400,12 @@ struct ast_vhub { ...@@ -402,10 +400,12 @@ struct ast_vhub {
bool ep1_stalled : 1; bool ep1_stalled : 1;
/* Per-port info */ /* Per-port info */
struct ast_vhub_port ports[AST_VHUB_NUM_PORTS]; struct ast_vhub_port *ports;
u32 max_ports;
/* Generic EP data structures */ /* 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 ? */ /* Upstream bus is suspended ? */
bool suspended : 1; bool suspended : 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment