| .. | .. |
|---|
| 2 | 2 | /* |
|---|
| 3 | 3 | * amd5536.c -- AMD 5536 UDC high/full speed USB device controller |
|---|
| 4 | 4 | * |
|---|
| 5 | | - * Copyright (C) 2005-2007 AMD (http://www.amd.com) |
|---|
| 5 | + * Copyright (C) 2005-2007 AMD (https://www.amd.com) |
|---|
| 6 | 6 | * Author: Thomas Dahlmann |
|---|
| 7 | 7 | */ |
|---|
| 8 | 8 | |
|---|
| .. | .. |
|---|
| 36 | 36 | #include <asm/unaligned.h> |
|---|
| 37 | 37 | #include "amd5536udc.h" |
|---|
| 38 | 38 | |
|---|
| 39 | | -static void udc_tasklet_disconnect(unsigned long); |
|---|
| 40 | 39 | static void udc_setup_endpoints(struct udc *dev); |
|---|
| 41 | 40 | static void udc_soft_reset(struct udc *dev); |
|---|
| 42 | 41 | static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep); |
|---|
| .. | .. |
|---|
| 94 | 93 | static struct timer_list udc_pollstall_timer; |
|---|
| 95 | 94 | static int stop_pollstall_timer; |
|---|
| 96 | 95 | static DECLARE_COMPLETION(on_pollstall_exit); |
|---|
| 97 | | - |
|---|
| 98 | | -/* tasklet for usb disconnect */ |
|---|
| 99 | | -static DECLARE_TASKLET(disconnect_tasklet, udc_tasklet_disconnect, |
|---|
| 100 | | - (unsigned long) &udc); |
|---|
| 101 | | - |
|---|
| 102 | 96 | |
|---|
| 103 | 97 | /* endpoint names used for print */ |
|---|
| 104 | 98 | static const char ep0_string[] = "ep0in"; |
|---|
| .. | .. |
|---|
| 947 | 941 | UDC_DMA_STP_STS_BS_HOST_READY, |
|---|
| 948 | 942 | UDC_DMA_STP_STS_BS); |
|---|
| 949 | 943 | |
|---|
| 950 | | - |
|---|
| 951 | | - /* clear NAK by writing CNAK */ |
|---|
| 952 | | - if (ep->naking) { |
|---|
| 953 | | - tmp = readl(&ep->regs->ctl); |
|---|
| 954 | | - tmp |= AMD_BIT(UDC_EPCTL_CNAK); |
|---|
| 955 | | - writel(tmp, &ep->regs->ctl); |
|---|
| 956 | | - ep->naking = 0; |
|---|
| 957 | | - UDC_QUEUE_CNAK(ep, ep->num); |
|---|
| 958 | | - } |
|---|
| 944 | + /* clear NAK by writing CNAK */ |
|---|
| 945 | + if (ep->naking) { |
|---|
| 946 | + tmp = readl(&ep->regs->ctl); |
|---|
| 947 | + tmp |= AMD_BIT(UDC_EPCTL_CNAK); |
|---|
| 948 | + writel(tmp, &ep->regs->ctl); |
|---|
| 949 | + ep->naking = 0; |
|---|
| 950 | + UDC_QUEUE_CNAK(ep, ep->num); |
|---|
| 951 | + } |
|---|
| 959 | 952 | |
|---|
| 960 | 953 | } |
|---|
| 961 | 954 | |
|---|
| .. | .. |
|---|
| 1640 | 1633 | */ |
|---|
| 1641 | 1634 | static void usb_disconnect(struct udc *dev) |
|---|
| 1642 | 1635 | { |
|---|
| 1636 | + u32 tmp; |
|---|
| 1637 | + |
|---|
| 1643 | 1638 | /* Return if already disconnected */ |
|---|
| 1644 | 1639 | if (!dev->connected) |
|---|
| 1645 | 1640 | return; |
|---|
| .. | .. |
|---|
| 1651 | 1646 | /* mask interrupts */ |
|---|
| 1652 | 1647 | udc_mask_unused_interrupts(dev); |
|---|
| 1653 | 1648 | |
|---|
| 1654 | | - /* REVISIT there doesn't seem to be a point to having this |
|---|
| 1655 | | - * talk to a tasklet ... do it directly, we already hold |
|---|
| 1656 | | - * the spinlock needed to process the disconnect. |
|---|
| 1657 | | - */ |
|---|
| 1658 | | - |
|---|
| 1659 | | - tasklet_schedule(&disconnect_tasklet); |
|---|
| 1660 | | -} |
|---|
| 1661 | | - |
|---|
| 1662 | | -/* Tasklet for disconnect to be outside of interrupt context */ |
|---|
| 1663 | | -static void udc_tasklet_disconnect(unsigned long par) |
|---|
| 1664 | | -{ |
|---|
| 1665 | | - struct udc *dev = (struct udc *)(*((struct udc **) par)); |
|---|
| 1666 | | - u32 tmp; |
|---|
| 1667 | | - |
|---|
| 1668 | | - DBG(dev, "Tasklet disconnect\n"); |
|---|
| 1669 | | - spin_lock_irq(&dev->lock); |
|---|
| 1670 | | - |
|---|
| 1671 | 1649 | if (dev->driver) { |
|---|
| 1672 | 1650 | spin_unlock(&dev->lock); |
|---|
| 1673 | 1651 | dev->driver->disconnect(&dev->gadget); |
|---|
| .. | .. |
|---|
| 1676 | 1654 | /* empty queues */ |
|---|
| 1677 | 1655 | for (tmp = 0; tmp < UDC_EP_NUM; tmp++) |
|---|
| 1678 | 1656 | empty_req_queue(&dev->ep[tmp]); |
|---|
| 1679 | | - |
|---|
| 1680 | 1657 | } |
|---|
| 1681 | 1658 | |
|---|
| 1682 | 1659 | /* disable ep0 */ |
|---|
| 1683 | | - ep_init(dev->regs, |
|---|
| 1684 | | - &dev->ep[UDC_EP0IN_IX]); |
|---|
| 1685 | | - |
|---|
| 1660 | + ep_init(dev->regs, &dev->ep[UDC_EP0IN_IX]); |
|---|
| 1686 | 1661 | |
|---|
| 1687 | 1662 | if (!soft_reset_occured) { |
|---|
| 1688 | 1663 | /* init controller by soft reset */ |
|---|
| .. | .. |
|---|
| 1698 | 1673 | tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); |
|---|
| 1699 | 1674 | writel(tmp, &dev->regs->cfg); |
|---|
| 1700 | 1675 | } |
|---|
| 1701 | | - |
|---|
| 1702 | | - spin_unlock_irq(&dev->lock); |
|---|
| 1703 | 1676 | } |
|---|
| 1704 | 1677 | |
|---|
| 1705 | 1678 | /* Reset the UDC core */ |
|---|