diff options
author | Boris Brezillon <boris.brezillon@free-electrons.com> | 2015-01-06 08:47:02 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2015-01-12 13:13:29 -0500 |
commit | e3a912a124c380db61eff762faa0547ea4c90eb4 (patch) | |
tree | e5f07058d777a5cfe1de9be66a5b24c4c3fc6cad | |
parent | 9870d895ad87efae130b2990db9ba265271f113b (diff) |
usb: gadget: atmel_usba: Cache INT_ENB register value
Cache INT_ENB register value in order to avoid uncached iomem access, and
thus improve access time to INT_ENB value.
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r-- | drivers/usb/gadget/udc/atmel_usba_udc.c | 52 | ||||
-rw-r--r-- | drivers/usb/gadget/udc/atmel_usba_udc.h | 2 |
2 files changed, 30 insertions, 24 deletions
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index bc3a53264c43..6dfe17b583fb 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c | |||
@@ -316,6 +316,17 @@ static inline void usba_cleanup_debugfs(struct usba_udc *udc) | |||
316 | } | 316 | } |
317 | #endif | 317 | #endif |
318 | 318 | ||
319 | static inline u32 usba_int_enb_get(struct usba_udc *udc) | ||
320 | { | ||
321 | return udc->int_enb_cache; | ||
322 | } | ||
323 | |||
324 | static inline void usba_int_enb_set(struct usba_udc *udc, u32 val) | ||
325 | { | ||
326 | usba_writel(udc, INT_ENB, val); | ||
327 | udc->int_enb_cache = val; | ||
328 | } | ||
329 | |||
319 | static int vbus_is_present(struct usba_udc *udc) | 330 | static int vbus_is_present(struct usba_udc *udc) |
320 | { | 331 | { |
321 | if (gpio_is_valid(udc->vbus_pin)) | 332 | if (gpio_is_valid(udc->vbus_pin)) |
@@ -597,16 +608,14 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
597 | if (ep->can_dma) { | 608 | if (ep->can_dma) { |
598 | u32 ctrl; | 609 | u32 ctrl; |
599 | 610 | ||
600 | usba_writel(udc, INT_ENB, | 611 | usba_int_enb_set(udc, usba_int_enb_get(udc) | |
601 | (usba_readl(udc, INT_ENB) | 612 | USBA_BF(EPT_INT, 1 << ep->index) | |
602 | | USBA_BF(EPT_INT, 1 << ep->index) | 613 | USBA_BF(DMA_INT, 1 << ep->index)); |
603 | | USBA_BF(DMA_INT, 1 << ep->index))); | ||
604 | ctrl = USBA_AUTO_VALID | USBA_INTDIS_DMA; | 614 | ctrl = USBA_AUTO_VALID | USBA_INTDIS_DMA; |
605 | usba_ep_writel(ep, CTL_ENB, ctrl); | 615 | usba_ep_writel(ep, CTL_ENB, ctrl); |
606 | } else { | 616 | } else { |
607 | usba_writel(udc, INT_ENB, | 617 | usba_int_enb_set(udc, usba_int_enb_get(udc) | |
608 | (usba_readl(udc, INT_ENB) | 618 | USBA_BF(EPT_INT, 1 << ep->index)); |
609 | | USBA_BF(EPT_INT, 1 << ep->index))); | ||
610 | } | 619 | } |
611 | 620 | ||
612 | spin_unlock_irqrestore(&udc->lock, flags); | 621 | spin_unlock_irqrestore(&udc->lock, flags); |
@@ -614,7 +623,7 @@ usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | |||
614 | DBG(DBG_HW, "EPT_CFG%d after init: %#08lx\n", ep->index, | 623 | DBG(DBG_HW, "EPT_CFG%d after init: %#08lx\n", ep->index, |
615 | (unsigned long)usba_ep_readl(ep, CFG)); | 624 | (unsigned long)usba_ep_readl(ep, CFG)); |
616 | DBG(DBG_HW, "INT_ENB after init: %#08lx\n", | 625 | DBG(DBG_HW, "INT_ENB after init: %#08lx\n", |
617 | (unsigned long)usba_readl(udc, INT_ENB)); | 626 | (unsigned long)usba_int_enb_get(udc)); |
618 | 627 | ||
619 | return 0; | 628 | return 0; |
620 | } | 629 | } |
@@ -650,9 +659,8 @@ static int usba_ep_disable(struct usb_ep *_ep) | |||
650 | usba_dma_readl(ep, STATUS); | 659 | usba_dma_readl(ep, STATUS); |
651 | } | 660 | } |
652 | usba_ep_writel(ep, CTL_DIS, USBA_EPT_ENABLE); | 661 | usba_ep_writel(ep, CTL_DIS, USBA_EPT_ENABLE); |
653 | usba_writel(udc, INT_ENB, | 662 | usba_int_enb_set(udc, usba_int_enb_get(udc) & |
654 | usba_readl(udc, INT_ENB) | 663 | ~USBA_BF(EPT_INT, 1 << ep->index)); |
655 | & ~USBA_BF(EPT_INT, 1 << ep->index)); | ||
656 | 664 | ||
657 | request_complete_list(ep, &req_list, -ESHUTDOWN); | 665 | request_complete_list(ep, &req_list, -ESHUTDOWN); |
658 | 666 | ||
@@ -1606,20 +1614,20 @@ static void usba_dma_irq(struct usba_udc *udc, struct usba_ep *ep) | |||
1606 | static irqreturn_t usba_udc_irq(int irq, void *devid) | 1614 | static irqreturn_t usba_udc_irq(int irq, void *devid) |
1607 | { | 1615 | { |
1608 | struct usba_udc *udc = devid; | 1616 | struct usba_udc *udc = devid; |
1609 | u32 status; | 1617 | u32 status, int_enb; |
1610 | u32 dma_status; | 1618 | u32 dma_status; |
1611 | u32 ep_status; | 1619 | u32 ep_status; |
1612 | 1620 | ||
1613 | spin_lock(&udc->lock); | 1621 | spin_lock(&udc->lock); |
1614 | 1622 | ||
1615 | status = usba_readl(udc, INT_STA) & usba_readl(udc, INT_ENB); | 1623 | int_enb = usba_int_enb_get(udc); |
1624 | status = usba_readl(udc, INT_STA) & int_enb; | ||
1616 | DBG(DBG_INT, "irq, status=%#08x\n", status); | 1625 | DBG(DBG_INT, "irq, status=%#08x\n", status); |
1617 | 1626 | ||
1618 | if (status & USBA_DET_SUSPEND) { | 1627 | if (status & USBA_DET_SUSPEND) { |
1619 | toggle_bias(udc, 0); | 1628 | toggle_bias(udc, 0); |
1620 | usba_writel(udc, INT_CLR, USBA_DET_SUSPEND); | 1629 | usba_writel(udc, INT_CLR, USBA_DET_SUSPEND); |
1621 | usba_writel(udc, INT_ENB, | 1630 | usba_int_enb_set(udc, int_enb | USBA_WAKE_UP); |
1622 | usba_readl(udc, INT_ENB) | USBA_WAKE_UP); | ||
1623 | udc->bias_pulse_needed = true; | 1631 | udc->bias_pulse_needed = true; |
1624 | DBG(DBG_BUS, "Suspend detected\n"); | 1632 | DBG(DBG_BUS, "Suspend detected\n"); |
1625 | if (udc->gadget.speed != USB_SPEED_UNKNOWN | 1633 | if (udc->gadget.speed != USB_SPEED_UNKNOWN |
@@ -1633,8 +1641,7 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
1633 | if (status & USBA_WAKE_UP) { | 1641 | if (status & USBA_WAKE_UP) { |
1634 | toggle_bias(udc, 1); | 1642 | toggle_bias(udc, 1); |
1635 | usba_writel(udc, INT_CLR, USBA_WAKE_UP); | 1643 | usba_writel(udc, INT_CLR, USBA_WAKE_UP); |
1636 | usba_writel(udc, INT_ENB, | 1644 | usba_int_enb_set(udc, int_enb & ~USBA_WAKE_UP); |
1637 | usba_readl(udc, INT_ENB) & ~USBA_WAKE_UP); | ||
1638 | DBG(DBG_BUS, "Wake Up CPU detected\n"); | 1645 | DBG(DBG_BUS, "Wake Up CPU detected\n"); |
1639 | } | 1646 | } |
1640 | 1647 | ||
@@ -1702,11 +1709,8 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
1702 | | USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE))); | 1709 | | USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE))); |
1703 | usba_ep_writel(ep0, CTL_ENB, | 1710 | usba_ep_writel(ep0, CTL_ENB, |
1704 | USBA_EPT_ENABLE | USBA_RX_SETUP); | 1711 | USBA_EPT_ENABLE | USBA_RX_SETUP); |
1705 | usba_writel(udc, INT_ENB, | 1712 | usba_int_enb_set(udc, int_enb | USBA_BF(EPT_INT, 1) | |
1706 | (usba_readl(udc, INT_ENB) | 1713 | USBA_DET_SUSPEND | USBA_END_OF_RESUME); |
1707 | | USBA_BF(EPT_INT, 1) | ||
1708 | | USBA_DET_SUSPEND | ||
1709 | | USBA_END_OF_RESUME)); | ||
1710 | 1714 | ||
1711 | /* | 1715 | /* |
1712 | * Unclear why we hit this irregularly, e.g. in usbtest, | 1716 | * Unclear why we hit this irregularly, e.g. in usbtest, |
@@ -1741,7 +1745,7 @@ static irqreturn_t usba_vbus_irq(int irq, void *devid) | |||
1741 | if (vbus) { | 1745 | if (vbus) { |
1742 | toggle_bias(udc, 1); | 1746 | toggle_bias(udc, 1); |
1743 | usba_writel(udc, CTRL, USBA_ENABLE_MASK); | 1747 | usba_writel(udc, CTRL, USBA_ENABLE_MASK); |
1744 | usba_writel(udc, INT_ENB, USBA_END_OF_RESET); | 1748 | usba_int_enb_set(udc, USBA_END_OF_RESET); |
1745 | } else { | 1749 | } else { |
1746 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 1750 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
1747 | reset_all_endpoints(udc); | 1751 | reset_all_endpoints(udc); |
@@ -1793,7 +1797,7 @@ static int atmel_usba_start(struct usb_gadget *gadget, | |||
1793 | if (vbus_is_present(udc) && udc->vbus_prev == 0) { | 1797 | if (vbus_is_present(udc) && udc->vbus_prev == 0) { |
1794 | toggle_bias(udc, 1); | 1798 | toggle_bias(udc, 1); |
1795 | usba_writel(udc, CTRL, USBA_ENABLE_MASK); | 1799 | usba_writel(udc, CTRL, USBA_ENABLE_MASK); |
1796 | usba_writel(udc, INT_ENB, USBA_END_OF_RESET); | 1800 | usba_int_enb_set(udc, USBA_END_OF_RESET); |
1797 | } | 1801 | } |
1798 | spin_unlock_irqrestore(&udc->lock, flags); | 1802 | spin_unlock_irqrestore(&udc->lock, flags); |
1799 | 1803 | ||
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.h b/drivers/usb/gadget/udc/atmel_usba_udc.h index 72b3537f56ce..497cd18836f3 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.h +++ b/drivers/usb/gadget/udc/atmel_usba_udc.h | |||
@@ -334,6 +334,8 @@ struct usba_udc { | |||
334 | u16 test_mode; | 334 | u16 test_mode; |
335 | int vbus_prev; | 335 | int vbus_prev; |
336 | 336 | ||
337 | u32 int_enb_cache; | ||
338 | |||
337 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | 339 | #ifdef CONFIG_USB_GADGET_DEBUG_FS |
338 | struct dentry *debugfs_root; | 340 | struct dentry *debugfs_root; |
339 | struct dentry *debugfs_regs; | 341 | struct dentry *debugfs_regs; |