OSDN Git Service

usb: gadget: aspeed: improve vhub port irq handling
authorTao Ren <rentao.bupt@gmail.com>
Sun, 15 Mar 2020 19:14:30 +0000 (12:14 -0700)
committerFelipe Balbi <balbi@kernel.org>
Tue, 5 May 2020 07:58:50 +0000 (10:58 +0300)
This patch evaluates vhub ports' irq mask before going through per-port
irq handling one by one, which helps to speed up irq handling in case
there is no port interrupt.

Signed-off-by: Tao Ren <rentao.bupt@gmail.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
drivers/usb/gadget/udc/aspeed-vhub/core.c
drivers/usb/gadget/udc/aspeed-vhub/vhub.h

index f8d35dd..555e864 100644 (file)
@@ -134,11 +134,15 @@ static irqreturn_t ast_vhub_irq(int irq, void *data)
        }
 
        /* Handle device interrupts */
-       for (i = 0; i < vhub->max_ports; i++) {
-               u32 dev_mask = VHUB_IRQ_DEVICE1 << i;
+       if (istat & vhub->port_irq_mask) {
+               unsigned long bitmap = istat;
+               int offset = VHUB_IRQ_DEV1_BIT;
+               int size = VHUB_IRQ_DEV1_BIT + vhub->max_ports;
 
-               if (istat & dev_mask)
+               for_each_set_bit_from(offset, &bitmap, size) {
+                       i = offset - VHUB_IRQ_DEV1_BIT;
                        ast_vhub_dev_irq(&vhub->ports[i].dev);
+               }
        }
 
        /* Handle top-level vHub EP0 interrupts */
@@ -332,6 +336,8 @@ static int ast_vhub_probe(struct platform_device *pdev)
 
        spin_lock_init(&vhub->lock);
        vhub->pdev = pdev;
+       vhub->port_irq_mask = GENMASK(VHUB_IRQ_DEV1_BIT + vhub->max_ports - 1,
+                                     VHUB_IRQ_DEV1_BIT);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        vhub->regs = devm_ioremap_resource(&pdev->dev, res);
index fac79ef..23a1ac9 100644 (file)
 #define VHUB_CTRL_UPSTREAM_CONNECT             (1 << 0)
 
 /* IER & ISR */
+#define VHUB_IRQ_DEV1_BIT                      9
 #define VHUB_IRQ_USB_CMD_DEADLOCK              (1 << 18)
 #define VHUB_IRQ_EP_POOL_NAK                   (1 << 17)
 #define VHUB_IRQ_EP_POOL_ACK_STALL             (1 << 16)
-#define VHUB_IRQ_DEVICE5                       (1 << 13)
-#define VHUB_IRQ_DEVICE4                       (1 << 12)
-#define VHUB_IRQ_DEVICE3                       (1 << 11)
-#define VHUB_IRQ_DEVICE2                       (1 << 10)
-#define VHUB_IRQ_DEVICE1                       (1 << 9)
+#define VHUB_IRQ_DEVICE1                       (1 << (VHUB_IRQ_DEV1_BIT))
 #define VHUB_IRQ_BUS_RESUME                    (1 << 8)
 #define VHUB_IRQ_BUS_SUSPEND                   (1 << 7)
 #define VHUB_IRQ_BUS_RESET                     (1 << 6)
@@ -402,6 +399,7 @@ struct ast_vhub {
        /* Per-port info */
        struct ast_vhub_port            *ports;
        u32                             max_ports;
+       u32                             port_irq_mask;
 
        /* Generic EP data structures */
        struct ast_vhub_ep              *epns;