Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp1112928ybl; Fri, 31 Jan 2020 14:23:17 -0800 (PST) X-Google-Smtp-Source: APXvYqwdcT7s5H70HxNbHHBNT9fzxHX20pWjE1scHLP4N10g0mEaNc+RoPB9HmFMiv3uO6dlB5Te X-Received: by 2002:a9d:7696:: with SMTP id j22mr9685796otl.188.1580509397539; Fri, 31 Jan 2020 14:23:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1580509397; cv=none; d=google.com; s=arc-20160816; b=euVSSC2zquLd469zj5PqIi8zfJV3lSV8z6HcnxaSAv5tlKqA7mN8Io+h557f98JA/A cHnqJpQvPxZViY5DppCnHkvexn794vfcduMc+n3E8oqqcFyF+qRWPqsAu7IoxZ9L4TiV hYE+GdPxNr8k2KEdkkKCLhmBvvvmjUQP/P/CnM3WSDu2357+SnfEWLRegiDQ47wftmq9 F0OtuU/zhSDjDfV0IxjtIKor2eDkofAPPmDhH+Eliy7PAlIEXLgvm7kvck6wwKl9IMaN +s02ovLEUrHvm0wIJtRT9TkIM4RzEDDoXlzfNoV492ac6ZdBwRgi4MiX5aoP6to7IAlo 9+NA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=zqBWCXlbWDTU80hnWTEbjXNcHsqm4LeUfrlMr8ZUWRY=; b=XVkULQCW3JIz3JoQnE9Z865HhW6S5ZAQR6bygoD8YPLyNk9hdJhrhTW6SD5JXcvSFO Xo1yt/aXKI1OmSy+o4ZO4JhU4P02M9Lrdb4lmBmMNERJ3KnFE9nCsbJyoaDk4M6p1CPm Ft4aQj1nZe9XfQLkSbMoxBZrbALzN39sXLrC0ZIrJgxsktlqXZeJNpjGgGvG2kED6QH1 FCcLhawW1KbP5zXL7cYj82vK4JQscfpemqjt27cBggXCL1emr+6T0E40RFh43OdeEDn9 n5gKMSwWaX2+fo6Wexv5oNLgTLWKK41HGJ/DJhnM3GUTSbyERQJClIF8J0R1SWbDxPnN A7pQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=hWdJXMs+; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s64si4984928oig.147.2020.01.31.14.23.05; Fri, 31 Jan 2020 14:23:17 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=hWdJXMs+; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726622AbgAaWWN (ORCPT + 99 others); Fri, 31 Jan 2020 17:22:13 -0500 Received: from mail-pg1-f194.google.com ([209.85.215.194]:45194 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726163AbgAaWWM (ORCPT ); Fri, 31 Jan 2020 17:22:12 -0500 Received: by mail-pg1-f194.google.com with SMTP id b9so4213387pgk.12; Fri, 31 Jan 2020 14:22:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zqBWCXlbWDTU80hnWTEbjXNcHsqm4LeUfrlMr8ZUWRY=; b=hWdJXMs+k7nEmSNy9Pw6kaT0IQpMMUiKQ5paDR1fF15CrGnhPfyWlRagl85sQfb/vh 5NxK8btOIxn6TjivKAJmI2dZewseF4CKWJMXPOn6Av3gOIFmuBjvIjY7rL1Rs8mDFZZP V/mhcy+IUezjYDjNuMlOpwND98Sr24Ou+Qxv505Zq911U9ygO/Ea2ku0WL9VGcDIdxC0 v5z8x9FgKsAqAeOiOBgKKAu8EE8nSsDCxjpM9/R7YQxrYY31Z/KlFQKkGDw+yP7I6KN1 kOA63tWTw9n9MfMYDCadsPoKehNKRyca5M943rWBi19nbrfB8ogmPJ/Jxx2HtwS9h9Es 3r9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=zqBWCXlbWDTU80hnWTEbjXNcHsqm4LeUfrlMr8ZUWRY=; b=Xu7fRFmQMqi9xAmu7TvmZqRctK+VJd2cjsxYQEVY4lR+m22p681/Ba77WrcjTQSrMd CMUHeVrUgKc3jQkD/HkgMfUPme7iRCrhjlM4KOm7cabBxSizu421W9GLt0APoX7rOMLP u4CP7tWNyUoApBzW6jGaYKSDfs8wWdRZWjk2noTVjUraBilRtXDN9atjK5MnXlMPi5S9 JLB9C5DAY+f9bUWCRoXLd9LPNdEGwKe6SkGo6c767E/4L3TZeE1mb30P1cXd8Hmu4PIv tLpZYxarVKkgal61W86WvvO/EsUoxbNXJfDjfgY/dB2eznX/sFQAteF776OWdw81p/gV x/Lg== X-Gm-Message-State: APjAAAUVhZ903SU3+8D7BleZmM59PEo8lkgIRB91MQzCwx6/o/BgQb2o s+VOlI2979KVaiauiF2m3ow= X-Received: by 2002:a63:f62:: with SMTP id 34mr13059089pgp.184.1580509329298; Fri, 31 Jan 2020 14:22:09 -0800 (PST) Received: from taoren-ubuntu-R90MNF91.thefacebook.com ([2620:10d:c090:200::1:a521]) by smtp.gmail.com with ESMTPSA id v8sm11201515pff.151.2020.01.31.14.22.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Jan 2020 14:22:08 -0800 (PST) From: rentao.bupt@gmail.com To: Felipe Balbi , Greg Kroah-Hartman , Joel Stanley , Andrew Jeffery , Benjamin Herrenschmidt , Chunfeng Yun , Colin Ian King , Stephen Boyd , Rob Herring , Mark Rutland , linux-usb@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, openbmc@lists.ozlabs.org Cc: Tao Ren Subject: [PATCH 1/3] usb: gadget: aspeed: read vhub config from of_device_id Date: Fri, 31 Jan 2020 14:21:55 -0800 Message-Id: <20200131222157.20849-2-rentao.bupt@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200131222157.20849-1-rentao.bupt@gmail.com> References: <20200131222157.20849-1-rentao.bupt@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Tao Ren The patch moves hardcoded vhub attributes (maximum downstream ports and generic endpoints) to "ast_vhub_config" structure which is attached to struct of_device_id. The major purpose is to add AST2600 vhub support because AST2600 vhub provides more downstream ports and endpoints. Signed-off-by: Tao Ren --- drivers/usb/gadget/udc/aspeed-vhub/core.c | 100 ++++++++++++++-------- 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 | 26 ++++-- drivers/usb/gadget/udc/aspeed-vhub/vhub.h | 23 ++--- 5 files changed, 112 insertions(+), 71 deletions(-) diff --git a/drivers/usb/gadget/udc/aspeed-vhub/core.c b/drivers/usb/gadget/udc/aspeed-vhub/core.c index 90b134d5dca9..94081cc04113 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/core.c +++ b/drivers/usb/gadget/udc/aspeed-vhub/core.c @@ -32,6 +32,29 @@ #include "vhub.h" +struct ast_vhub_config { + u32 max_ports; /* max number of downstream ports */ + u32 max_epns; /* max number of generic endpoints */ +}; + +static const struct ast_vhub_config ast2400_config = { + .max_ports = 5, + .max_epns = 15, +}; + +static const struct of_device_id ast_vhub_dt_ids[] = { + { + .compatible = "aspeed,ast2400-usb-vhub", + .data = &ast2400_config, + }, + { + .compatible = "aspeed,ast2500-usb-vhub", + .data = &ast2400_config, + }, + { } +}; +MODULE_DEVICE_TABLE(of, ast_vhub_dt_ids); + void ast_vhub_done(struct ast_vhub_ep *ep, struct ast_vhub_req *req, int status) { @@ -99,7 +122,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 +144,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 +157,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 +195,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 +235,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 +291,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 +313,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 +327,30 @@ static int ast_vhub_probe(struct platform_device *pdev) struct ast_vhub *vhub; struct resource *res; int i, rc = 0; + const struct of_device_id *ofdid; + const struct ast_vhub_config *config; vhub = devm_kzalloc(&pdev->dev, sizeof(*vhub), GFP_KERNEL); if (!vhub) return -ENOMEM; + ofdid = of_match_node(ast_vhub_dt_ids, pdev->dev.of_node); + if (!ofdid) + return -EINVAL; + config = ofdid->data; + + vhub->max_ports = config->max_ports; + vhub->ports = devm_kcalloc(&pdev->dev, vhub->max_ports, + sizeof(*vhub->ports), GFP_KERNEL); + if (!vhub->ports) + return -ENOMEM; + + vhub->max_epns = config->max_epns; + 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 +403,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 +417,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; @@ -400,17 +437,6 @@ static int ast_vhub_probe(struct platform_device *pdev) return rc; } -static const struct of_device_id ast_vhub_dt_ids[] = { - { - .compatible = "aspeed,ast2400-usb-vhub", - }, - { - .compatible = "aspeed,ast2500-usb-vhub", - }, - { } -}; -MODULE_DEVICE_TABLE(of, ast_vhub_dt_ids); - static struct platform_driver ast_vhub_driver = { .probe = ast_vhub_probe, .remove = ast_vhub_remove, 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 19b3517e04c0..9c7e57fbd8ef 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/hub.c +++ b/drivers/usb/gadget/udc/aspeed-vhub/hub.c @@ -133,10 +133,13 @@ static const struct ast_vhub_full_cdesc { #define AST_VHUB_HUB_DESC_SIZE (USB_DT_HUB_NONVAR_SIZE + 2) -static const struct usb_hub_descriptor ast_vhub_hub_desc = { +/* + * "bNbrPorts" field is updated in "ast_vhub_init_hub" function based on + * "max_ports" of the vhub. + */ +static struct usb_hub_descriptor ast_vhub_hub_desc = { .bDescLength = AST_VHUB_HUB_DESC_SIZE, .bDescriptorType = USB_DT_HUB, - .bNbrPorts = AST_VHUB_NUM_PORTS, .wHubCharacteristics = cpu_to_le16(HUB_CHAR_NO_LPSM), .bPwrOn2PwrGood = 10, .bHubContrCurrent = 0, @@ -504,7 +507,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)) @@ -587,7 +590,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]; @@ -630,7 +633,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]; @@ -676,7 +679,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--; @@ -757,7 +760,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)) @@ -780,7 +783,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)) @@ -814,7 +817,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 */ @@ -838,5 +841,10 @@ void ast_vhub_init_hub(struct ast_vhub *vhub) { vhub->speed = USB_SPEED_UNKNOWN; INIT_WORK(&vhub->wake_work, ast_vhub_wake_work); + + /* + * Fixup number of ports in hub descriptor. + */ + ast_vhub_hub_desc.bNbrPorts = vhub->max_ports; } diff --git a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h index 761919e220d3..e46980fe66f2 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h +++ b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h @@ -76,17 +76,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) @@ -210,8 +202,6 @@ * * ****************************************/ -#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 */ #define AST_VHUB_EPn_MAX_PACKET 1024 /* Generic EPs max packet size */ #define AST_VHUB_DESCS_COUNT 256 /* Use 256 descriptor mode (valid @@ -342,7 +332,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; @@ -358,7 +348,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) @@ -393,10 +384,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