diff options
Diffstat (limited to 'drivers/usb/chipidea/udc.c')
-rw-r--r-- | drivers/usb/chipidea/udc.c | 798 |
1 files changed, 453 insertions, 345 deletions
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 519ead2443c5..e475fcda1d68 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -61,7 +61,7 @@ static inline int hw_ep_bit(int num, int dir) return num + (dir ? 16 : 0); } -static inline int ep_to_bit(struct ci13xxx *ci, int n) +static inline int ep_to_bit(struct ci_hdrc *ci, int n) { int fill = 16 - ci->hw_ep_max / 2; @@ -77,7 +77,7 @@ static inline int ep_to_bit(struct ci13xxx *ci, int n) * * This function returns an error code */ -static int hw_device_state(struct ci13xxx *ci, u32 dma) +static int hw_device_state(struct ci_hdrc *ci, u32 dma) { if (dma) { hw_write(ci, OP_ENDPTLISTADDR, ~0, dma); @@ -97,7 +97,7 @@ static int hw_device_state(struct ci13xxx *ci, u32 dma) * * This function returns an error code */ -static int hw_ep_flush(struct ci13xxx *ci, int num, int dir) +static int hw_ep_flush(struct ci_hdrc *ci, int num, int dir) { int n = hw_ep_bit(num, dir); @@ -118,7 +118,7 @@ static int hw_ep_flush(struct ci13xxx *ci, int num, int dir) * * This function returns an error code */ -static int hw_ep_disable(struct ci13xxx *ci, int num, int dir) +static int hw_ep_disable(struct ci_hdrc *ci, int num, int dir) { hw_ep_flush(ci, num, dir); hw_write(ci, OP_ENDPTCTRL + num, @@ -134,7 +134,7 @@ static int hw_ep_disable(struct ci13xxx *ci, int num, int dir) * * This function returns an error code */ -static int hw_ep_enable(struct ci13xxx *ci, int num, int dir, int type) +static int hw_ep_enable(struct ci_hdrc *ci, int num, int dir, int type) { u32 mask, data; @@ -168,7 +168,7 @@ static int hw_ep_enable(struct ci13xxx *ci, int num, int dir, int type) * * This function returns 1 if endpoint halted */ -static int hw_ep_get_halt(struct ci13xxx *ci, int num, int dir) +static int hw_ep_get_halt(struct ci_hdrc *ci, int num, int dir) { u32 mask = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS; @@ -182,7 +182,7 @@ static int hw_ep_get_halt(struct ci13xxx *ci, int num, int dir) * * This function returns setup status */ -static int hw_test_and_clear_setup_status(struct ci13xxx *ci, int n) +static int hw_test_and_clear_setup_status(struct ci_hdrc *ci, int n) { n = ep_to_bit(ci, n); return hw_test_and_clear(ci, OP_ENDPTSETUPSTAT, BIT(n)); @@ -196,7 +196,7 @@ static int hw_test_and_clear_setup_status(struct ci13xxx *ci, int n) * * This function returns an error code */ -static int hw_ep_prime(struct ci13xxx *ci, int num, int dir, int is_ctrl) +static int hw_ep_prime(struct ci_hdrc *ci, int num, int dir, int is_ctrl) { int n = hw_ep_bit(num, dir); @@ -223,13 +223,13 @@ static int hw_ep_prime(struct ci13xxx *ci, int num, int dir, int is_ctrl) * * This function returns an error code */ -static int hw_ep_set_halt(struct ci13xxx *ci, int num, int dir, int value) +static int hw_ep_set_halt(struct ci_hdrc *ci, int num, int dir, int value) { if (value != 0 && value != 1) return -EINVAL; do { - enum ci13xxx_regs reg = OP_ENDPTCTRL + num; + enum ci_hw_regs reg = OP_ENDPTCTRL + num; u32 mask_xs = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS; u32 mask_xr = dir ? ENDPTCTRL_TXR : ENDPTCTRL_RXR; @@ -246,7 +246,7 @@ static int hw_ep_set_halt(struct ci13xxx *ci, int num, int dir, int value) * * This function returns true if high speed port */ -static int hw_port_is_high_speed(struct ci13xxx *ci) +static int hw_port_is_high_speed(struct ci_hdrc *ci) { return ci->hw_bank.lpm ? hw_read(ci, OP_DEVLC, DEVLC_PSPD) : hw_read(ci, OP_PORTSC, PORTSC_HSP); @@ -257,7 +257,7 @@ static int hw_port_is_high_speed(struct ci13xxx *ci) * * This function returns register data */ -static u32 hw_read_intr_enable(struct ci13xxx *ci) +static u32 hw_read_intr_enable(struct ci_hdrc *ci) { return hw_read(ci, OP_USBINTR, ~0); } @@ -267,7 +267,7 @@ static u32 hw_read_intr_enable(struct ci13xxx *ci) * * This function returns register data */ -static u32 hw_read_intr_status(struct ci13xxx *ci) +static u32 hw_read_intr_status(struct ci_hdrc *ci) { return hw_read(ci, OP_USBSTS, ~0); } @@ -279,7 +279,7 @@ static u32 hw_read_intr_status(struct ci13xxx *ci) * * This function returns complete status */ -static int hw_test_and_clear_complete(struct ci13xxx *ci, int n) +static int hw_test_and_clear_complete(struct ci_hdrc *ci, int n) { n = ep_to_bit(ci, n); return hw_test_and_clear(ci, OP_ENDPTCOMPLETE, BIT(n)); @@ -291,7 +291,7 @@ static int hw_test_and_clear_complete(struct ci13xxx *ci, int n) * * This function returns active interrutps */ -static u32 hw_test_and_clear_intr_active(struct ci13xxx *ci) +static u32 hw_test_and_clear_intr_active(struct ci_hdrc *ci) { u32 reg = hw_read_intr_status(ci) & hw_read_intr_enable(ci); @@ -305,7 +305,7 @@ static u32 hw_test_and_clear_intr_active(struct ci13xxx *ci) * * This function returns guard value */ -static int hw_test_and_clear_setup_guard(struct ci13xxx *ci) +static int hw_test_and_clear_setup_guard(struct ci_hdrc *ci) { return hw_test_and_write(ci, OP_USBCMD, USBCMD_SUTW, 0); } @@ -316,7 +316,7 @@ static int hw_test_and_clear_setup_guard(struct ci13xxx *ci) * * This function returns guard value */ -static int hw_test_and_set_setup_guard(struct ci13xxx *ci) +static int hw_test_and_set_setup_guard(struct ci_hdrc *ci) { return hw_test_and_write(ci, OP_USBCMD, USBCMD_SUTW, USBCMD_SUTW); } @@ -328,7 +328,7 @@ static int hw_test_and_set_setup_guard(struct ci13xxx *ci) * This function explicitly sets the address, without the "USBADRA" (advance) * feature, which is not supported by older versions of the controller. */ -static void hw_usb_set_address(struct ci13xxx *ci, u8 value) +static void hw_usb_set_address(struct ci_hdrc *ci, u8 value) { hw_write(ci, OP_DEVICEADDR, DEVICEADDR_USBADR, value << __ffs(DEVICEADDR_USBADR)); @@ -340,7 +340,7 @@ static void hw_usb_set_address(struct ci13xxx *ci, u8 value) * * This function returns an error code */ -static int hw_usb_reset(struct ci13xxx *ci) +static int hw_usb_reset(struct ci_hdrc *ci) { hw_usb_set_address(ci, 0); @@ -368,11 +368,60 @@ static int hw_usb_reset(struct ci13xxx *ci) /****************************************************************************** * UTIL block *****************************************************************************/ + +static int add_td_to_list(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq, + unsigned length) +{ + int i; + u32 temp; + struct td_node *lastnode, *node = kzalloc(sizeof(struct td_node), + GFP_ATOMIC); + + if (node == NULL) + return -ENOMEM; + + node->ptr = dma_pool_alloc(hwep->td_pool, GFP_ATOMIC, + &node->dma); + if (node->ptr == NULL) { + kfree(node); + return -ENOMEM; + } + + memset(node->ptr, 0, sizeof(struct ci_hw_td)); + node->ptr->token = cpu_to_le32(length << __ffs(TD_TOTAL_BYTES)); + node->ptr->token &= cpu_to_le32(TD_TOTAL_BYTES); + node->ptr->token |= cpu_to_le32(TD_STATUS_ACTIVE); + + temp = (u32) (hwreq->req.dma + hwreq->req.actual); + if (length) { + node->ptr->page[0] = cpu_to_le32(temp); + for (i = 1; i < TD_PAGE_COUNT; i++) { + u32 page = temp + i * CI_HDRC_PAGE_SIZE; + page &= ~TD_RESERVED_MASK; + node->ptr->page[i] = cpu_to_le32(page); + } + } + + hwreq->req.actual += length; + + if (!list_empty(&hwreq->tds)) { + /* get the last entry */ + lastnode = list_entry(hwreq->tds.prev, + struct td_node, td); + lastnode->ptr->next = cpu_to_le32(node->dma); + } + + INIT_LIST_HEAD(&node->td); + list_add_tail(&node->td, &hwreq->tds); + + return 0; +} + /** * _usb_addr: calculates endpoint address from direction & number * @ep: endpoint */ -static inline u8 _usb_addr(struct ci13xxx_ep *ep) +static inline u8 _usb_addr(struct ci_hw_ep *ep) { return ((ep->dir == TX) ? USB_ENDPOINT_DIR_MASK : 0) | ep->num; } @@ -380,75 +429,73 @@ static inline u8 _usb_addr(struct ci13xxx_ep *ep) /** * _hardware_queue: configures a request at hardware level * @gadget: gadget - * @mEp: endpoint + * @hwep: endpoint * * This function returns an error code */ -static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) +static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) { - struct ci13xxx *ci = mEp->ci; - unsigned i; + struct ci_hdrc *ci = hwep->ci; int ret = 0; - unsigned length = mReq->req.length; + unsigned rest = hwreq->req.length; + int pages = TD_PAGE_COUNT; + struct td_node *firstnode, *lastnode; /* don't queue twice */ - if (mReq->req.status == -EALREADY) + if (hwreq->req.status == -EALREADY) return -EALREADY; - mReq->req.status = -EALREADY; - - if (mReq->req.zero && length && (length % mEp->ep.maxpacket == 0)) { - mReq->zptr = dma_pool_alloc(mEp->td_pool, GFP_ATOMIC, - &mReq->zdma); - if (mReq->zptr == NULL) - return -ENOMEM; + hwreq->req.status = -EALREADY; - memset(mReq->zptr, 0, sizeof(*mReq->zptr)); - mReq->zptr->next = cpu_to_le32(TD_TERMINATE); - mReq->zptr->token = cpu_to_le32(TD_STATUS_ACTIVE); - if (!mReq->req.no_interrupt) - mReq->zptr->token |= cpu_to_le32(TD_IOC); - } - ret = usb_gadget_map_request(&ci->gadget, &mReq->req, mEp->dir); + ret = usb_gadget_map_request(&ci->gadget, &hwreq->req, hwep->dir); if (ret) return ret; /* - * TD configuration - * TODO - handle requests which spawns into several TDs + * The first buffer could be not page aligned. + * In that case we have to span into one extra td. */ - memset(mReq->ptr, 0, sizeof(*mReq->ptr)); - mReq->ptr->token = cpu_to_le32(length << __ffs(TD_TOTAL_BYTES)); - mReq->ptr->token &= cpu_to_le32(TD_TOTAL_BYTES); - mReq->ptr->token |= cpu_to_le32(TD_STATUS_ACTIVE); - if (mReq->zptr) { - mReq->ptr->next = cpu_to_le32(mReq->zdma); - } else { - mReq->ptr->next = cpu_to_le32(TD_TERMINATE); - if (!mReq->req.no_interrupt) - mReq->ptr->token |= cpu_to_le32(TD_IOC); - } - mReq->ptr->page[0] = cpu_to_le32(mReq->req.dma); - for (i = 1; i < TD_PAGE_COUNT; i++) { - u32 page = mReq->req.dma + i * CI13XXX_PAGE_SIZE; - page &= ~TD_RESERVED_MASK; - mReq->ptr->page[i] = cpu_to_le32(page); + if (hwreq->req.dma % PAGE_SIZE) + pages--; + + if (rest == 0) + add_td_to_list(hwep, hwreq, 0); + + while (rest > 0) { + unsigned count = min(hwreq->req.length - hwreq->req.actual, + (unsigned)(pages * CI_HDRC_PAGE_SIZE)); + add_td_to_list(hwep, hwreq, count); + rest -= count; } + if (hwreq->req.zero && hwreq->req.length + && (hwreq->req.length % hwep->ep.maxpacket == 0)) + add_td_to_list(hwep, hwreq, 0); + + firstnode = list_first_entry(&hwreq->tds, struct td_node, td); + + lastnode = list_entry(hwreq->tds.prev, + struct td_node, td); + + lastnode->ptr->next = cpu_to_le32(TD_TERMINATE); + if (!hwreq->req.no_interrupt) + lastnode->ptr->token |= cpu_to_le32(TD_IOC); wmb(); - if (!list_empty(&mEp->qh.queue)) { - struct ci13xxx_req *mReqPrev; - int n = hw_ep_bit(mEp->num, mEp->dir); + hwreq->req.actual = 0; + if (!list_empty(&hwep->qh.queue)) { + struct ci_hw_req *hwreqprev; + int n = hw_ep_bit(hwep->num, hwep->dir); int tmp_stat; - u32 next = mReq->dma & TD_ADDR_MASK; - - mReqPrev = list_entry(mEp->qh.queue.prev, - struct ci13xxx_req, queue); - if (mReqPrev->zptr) - mReqPrev->zptr->next = cpu_to_le32(next); - else - mReqPrev->ptr->next = cpu_to_le32(next); + struct td_node *prevlastnode; + u32 next = firstnode->dma & TD_ADDR_MASK; + + hwreqprev = list_entry(hwep->qh.queue.prev, + struct ci_hw_req, queue); + prevlastnode = list_entry(hwreqprev->tds.prev, + struct td_node, td); + + prevlastnode->ptr->next = cpu_to_le32(next); wmb(); if (hw_read(ci, OP_ENDPTPRIME, BIT(n))) goto done; @@ -462,99 +509,152 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) } /* QH configuration */ - mEp->qh.ptr->td.next = cpu_to_le32(mReq->dma); /* TERMINATE = 0 */ - mEp->qh.ptr->td.token &= + hwep->qh.ptr->td.next = cpu_to_le32(firstnode->dma); + hwep->qh.ptr->td.token &= cpu_to_le32(~(TD_STATUS_HALTED|TD_STATUS_ACTIVE)); + if (hwep->type == USB_ENDPOINT_XFER_ISOC) { + u32 mul = hwreq->req.length / hwep->ep.maxpacket; + + if (hwreq->req.length % hwep->ep.maxpacket) + mul++; + hwep->qh.ptr->cap |= mul << __ffs(QH_MULT); + } + wmb(); /* synchronize before ep prime */ - ret = hw_ep_prime(ci, mEp->num, mEp->dir, - mEp->type == USB_ENDPOINT_XFER_CONTROL); + ret = hw_ep_prime(ci, hwep->num, hwep->dir, + hwep->type == USB_ENDPOINT_XFER_CONTROL); done: return ret; } +/* + * free_pending_td: remove a pending request for the endpoint + * @hwep: endpoint + */ +static void free_pending_td(struct ci_hw_ep *hwep) +{ + struct td_node *pending = hwep->pending_td; + + dma_pool_free(hwep->td_pool, pending->ptr, pending->dma); + hwep->pending_td = NULL; + kfree(pending); +} + /** * _hardware_dequeue: handles a request at hardware level * @gadget: gadget - * @mEp: endpoint + * @hwep: endpoint * * This function returns an error code */ -static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) +static int _hardware_dequeue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq) { - u32 tmptoken = le32_to_cpu(mReq->ptr->token); + u32 tmptoken; + struct td_node *node, *tmpnode; + unsigned remaining_length; + unsigned actual = hwreq->req.length; - if (mReq->req.status != -EALREADY) + if (hwreq->req.status != -EALREADY) return -EINVAL; - if ((TD_STATUS_ACTIVE & tmptoken) != 0) - return -EBUSY; + hwreq->req.status = 0; - if (mReq->zptr) { - if ((cpu_to_le32(TD_STATUS_ACTIVE) & mReq->zptr->token) != 0) + list_for_each_entry_safe(node, tmpnode, &hwreq->tds, td) { + tmptoken = le32_to_cpu(node->ptr->token); + if ((TD_STATUS_ACTIVE & tmptoken) != 0) { + hwreq->req.status = -EALREADY; return -EBUSY; - dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma); - mReq->zptr = NULL; - } + } + + remaining_length = (tmptoken & TD_TOTAL_BYTES); + remaining_length >>= __ffs(TD_TOTAL_BYTES); + actual -= remaining_length; + + hwreq->req.status = tmptoken & TD_STATUS; + if ((TD_STATUS_HALTED & hwreq->req.status)) { + hwreq->req.status = -EPIPE; + break; + } else if ((TD_STATUS_DT_ERR & hwreq->req.status)) { + hwreq->req.status = -EPROTO; + break; + } else if ((TD_STATUS_TR_ERR & hwreq->req.status)) { + hwreq->req.status = -EILSEQ; + break; + } + + if (remaining_length) { + if (hwep->dir) { + hwreq->req.status = -EPROTO; + break; + } + } + /* + * As the hardware could still address the freed td + * which will run the udc unusable, the cleanup of the + * td has to be delayed by one. + */ + if (hwep->pending_td) + free_pending_td(hwep); - mReq->req.status = 0; + hwep->pending_td = node; + list_del_init(&node->td); + } - usb_gadget_unmap_request(&mEp->ci->gadget, &mReq->req, mEp->dir); + usb_gadget_unmap_request(&hwep->ci->gadget, &hwreq->req, hwep->dir); - mReq->req.status = tmptoken & TD_STATUS; - if ((TD_STATUS_HALTED & mReq->req.status) != 0) - mReq->req.status = -1; - else if ((TD_STATUS_DT_ERR & mReq->req.status) != 0) - mReq->req.status = -1; - else if ((TD_STATUS_TR_ERR & mReq->req.status) != 0) - mReq->req.status = -1; + hwreq->req.actual += actual; - mReq->req.actual = tmptoken & TD_TOTAL_BYTES; - mReq->req.actual >>= __ffs(TD_TOTAL_BYTES); - mReq->req.actual = mReq->req.length - mReq->req.actual; - mReq->req.actual = mReq->req.status ? 0 : mReq->req.actual; + if (hwreq->req.status) + return hwreq->req.status; - return mReq->req.actual; + return hwreq->req.actual; } /** * _ep_nuke: dequeues all endpoint requests - * @mEp: endpoint + * @hwep: endpoint * * This function returns an error code * Caller must hold lock */ -static int _ep_nuke(struct ci13xxx_ep *mEp) -__releases(mEp->lock) -__acquires(mEp->lock) +static int _ep_nuke(struct ci_hw_ep *hwep) +__releases(hwep->lock) +__acquires(hwep->lock) { - if (mEp == NULL) + struct td_node *node, *tmpnode; + if (hwep == NULL) return -EINVAL; - hw_ep_flush(mEp->ci, mEp->num, mEp->dir); + hw_ep_flush(hwep->ci, hwep->num, hwep->dir); - while (!list_empty(&mEp->qh.queue)) { + while (!list_empty(&hwep->qh.queue)) { /* pop oldest request */ - struct ci13xxx_req *mReq = \ - list_entry(mEp->qh.queue.next, - struct ci13xxx_req, queue); - - if (mReq->zptr) { - dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma); - mReq->zptr = NULL; + struct ci_hw_req *hwreq = list_entry(hwep->qh.queue.next, + struct ci_hw_req, queue); + + list_for_each_entry_safe(node, tmpnode, &hwreq->tds, td) { + dma_pool_free(hwep->td_pool, node->ptr, node->dma); + list_del_init(&node->td); + node->ptr = NULL; + kfree(node); } - list_del_init(&mReq->queue); - mReq->req.status = -ESHUTDOWN; + list_del_init(&hwreq->queue); + hwreq->req.status = -ESHUTDOWN; - if (mReq->req.complete != NULL) { - spin_unlock(mEp->lock); - mReq->req.complete(&mEp->ep, &mReq->req); - spin_lock(mEp->lock); + if (hwreq->req.complete != NULL) { + spin_unlock(hwep->lock); + hwreq->req.complete(&hwep->ep, &hwreq->req); + spin_lock(hwep->lock); } } + + if (hwep->pending_td) + free_pending_td(hwep); + return 0; } @@ -567,7 +667,7 @@ __acquires(mEp->lock) static int _gadget_stop_activity(struct usb_gadget *gadget) { struct usb_ep *ep; - struct ci13xxx *ci = container_of(gadget, struct ci13xxx, gadget); + struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget); unsigned long flags; spin_lock_irqsave(&ci->lock, flags); @@ -608,7 +708,7 @@ static int _gadget_stop_activity(struct usb_gadget *gadget) * * This function resets USB engine after a bus reset occurred */ -static void isr_reset_handler(struct ci13xxx *ci) +static void isr_reset_handler(struct ci_hdrc *ci) __releases(ci->lock) __acquires(ci->lock) { @@ -658,47 +758,48 @@ static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req) static int _ep_queue(struct usb_ep *ep, struct usb_request *req, gfp_t __maybe_unused gfp_flags) { - struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); - struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req); - struct ci13xxx *ci = mEp->ci; + struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep); + struct ci_hw_req *hwreq = container_of(req, struct ci_hw_req, req); + struct ci_hdrc *ci = hwep->ci; int retval = 0; - if (ep == NULL || req == NULL || mEp->ep.desc == NULL) + if (ep == NULL || req == NULL || hwep->ep.desc == NULL) return -EINVAL; - if (mEp->type == USB_ENDPOINT_XFER_CONTROL) { + if (hwep->type == USB_ENDPOINT_XFER_CONTROL) { if (req->length) - mEp = (ci->ep0_dir == RX) ? + hwep = (ci->ep0_dir == RX) ? ci->ep0out : ci->ep0in; - if (!list_empty(&mEp->qh.queue)) { - _ep_nuke(mEp); + if (!list_empty(&hwep->qh.queue)) { + _ep_nuke(hwep); retval = -EOVERFLOW; - dev_warn(mEp->ci->dev, "endpoint ctrl %X nuked\n", - _usb_addr(mEp)); + dev_warn(hwep->ci->dev, "endpoint ctrl %X nuked\n", + _usb_addr(hwep)); } } - /* first nuke then test link, e.g. previous status has not sent */ - if (!list_empty(&mReq->queue)) { - dev_err(mEp->ci->dev, "request already in queue\n"); - return -EBUSY; + if (usb_endpoint_xfer_isoc(hwep->ep.desc) && + hwreq->req.length > (1 + hwep->ep.mult) * hwep->ep.maxpacket) { + dev_err(hwep->ci->dev, "request length too big for isochronous\n"); + return -EMSGSIZE; } - if (req->length > (TD_PAGE_COUNT - 1) * CI13XXX_PAGE_SIZE) { - dev_err(mEp->ci->dev, "request bigger than one td\n"); - return -EMSGSIZE; + /* first nuke then test link, e.g. previous status has not sent */ + if (!list_empty(&hwreq->queue)) { + dev_err(hwep->ci->dev, "request already in queue\n"); + return -EBUSY; } /* push request */ - mReq->req.status = -EINPROGRESS; - mReq->req.actual = 0; + hwreq->req.status = -EINPROGRESS; + hwreq->req.actual = 0; - retval = _hardware_enqueue(mEp, mReq); + retval = _hardware_enqueue(hwep, hwreq); if (retval == -EALREADY) retval = 0; if (!retval) - list_add_tail(&mReq->queue, &mEp->qh.queue); + list_add_tail(&hwreq->queue, &hwep->qh.queue); return retval; } @@ -710,22 +811,22 @@ static int _ep_queue(struct usb_ep *ep, struct usb_request *req, * * This function returns an error code */ -static int isr_get_status_response(struct ci13xxx *ci, +static int isr_get_status_response(struct ci_hdrc *ci, struct usb_ctrlrequest *setup) -__releases(mEp->lock) -__acquires(mEp->lock) +__releases(hwep->lock) +__acquires(hwep->lock) { - struct ci13xxx_ep *mEp = ci->ep0in; + struct ci_hw_ep *hwep = ci->ep0in; struct usb_request *req = NULL; gfp_t gfp_flags = GFP_ATOMIC; int dir, num, retval; - if (mEp == NULL || setup == NULL) + if (hwep == NULL || setup == NULL) return -EINVAL; - spin_unlock(mEp->lock); - req = usb_ep_alloc_request(&mEp->ep, gfp_flags); - spin_lock(mEp->lock); + spin_unlock(hwep->lock); + req = usb_ep_alloc_request(&hwep->ep, gfp_flags); + spin_lock(hwep->lock); if (req == NULL) return -ENOMEM; @@ -750,7 +851,7 @@ __acquires(mEp->lock) } /* else do nothing; reserved for future use */ - retval = _ep_queue(&mEp->ep, req, gfp_flags); + retval = _ep_queue(&hwep->ep, req, gfp_flags); if (retval) goto err_free_buf; @@ -759,9 +860,9 @@ __acquires(mEp->lock) err_free_buf: kfree(req->buf); err_free_req: - spin_unlock(mEp->lock); - usb_ep_free_request(&mEp->ep, req); - spin_lock(mEp->lock); + spin_unlock(hwep->lock); + usb_ep_free_request(&hwep->ep, req); + spin_lock(hwep->lock); return retval; } @@ -776,7 +877,7 @@ __acquires(mEp->lock) static void isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req) { - struct ci13xxx *ci = req->context; + struct ci_hdrc *ci = req->context; unsigned long flags; if (ci->setaddr) { @@ -796,48 +897,48 @@ isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req) * * This function returns an error code */ -static int isr_setup_status_phase(struct ci13xxx *ci) +static int isr_setup_status_phase(struct ci_hdrc *ci) { int retval; - struct ci13xxx_ep *mEp; + struct ci_hw_ep *hwep; - mEp = (ci->ep0_dir == TX) ? ci->ep0out : ci->ep0in; + hwep = (ci->ep0_dir == TX) ? ci->ep0out : ci->ep0in; ci->status->context = ci; ci->status->complete = isr_setup_status_complete; - retval = _ep_queue(&mEp->ep, ci->status, GFP_ATOMIC); + retval = _ep_queue(&hwep->ep, ci->status, GFP_ATOMIC); return retval; } /** * isr_tr_complete_low: transaction complete low level handler - * @mEp: endpoint + * @hwep: endpoint * * This function returns an error code * Caller must hold lock */ -static int isr_tr_complete_low(struct ci13xxx_ep *mEp) -__releases(mEp->lock) -__acquires(mEp->lock) +static int isr_tr_complete_low(struct ci_hw_ep *hwep) +__releases(hwep->lock) +__acquires(hwep->lock) { - struct ci13xxx_req *mReq, *mReqTemp; - struct ci13xxx_ep *mEpTemp = mEp; + struct ci_hw_req *hwreq, *hwreqtemp; + struct ci_hw_ep *hweptemp = hwep; int retval = 0; - list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue, + list_for_each_entry_safe(hwreq, hwreqtemp, &hwep->qh.queue, queue) { - retval = _hardware_dequeue(mEp, mReq); + retval = _hardware_dequeue(hwep, hwreq); if (retval < 0) break; - list_del_init(&mReq->queue); - if (mReq->req.complete != NULL) { - spin_unlock(mEp->lock); - if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) && - mReq->req.length) - mEpTemp = mEp->ci->ep0in; - mReq->req.complete(&mEpTemp->ep, &mReq->req); - spin_lock(mEp->lock); + list_del_init(&hwreq->queue); + if (hwreq->req.complete != NULL) { + spin_unlock(hwep->lock); + if ((hwep->type == USB_ENDPOINT_XFER_CONTROL) && + hwreq->req.length) + hweptemp = hwep->ci->ep0in; + hwreq->req.complete(&hweptemp->ep, &hwreq->req); + spin_lock(hwep->lock); } } @@ -853,7 +954,7 @@ __acquires(mEp->lock) * * This function handles traffic events */ -static void isr_tr_complete_handler(struct ci13xxx *ci) +static void isr_tr_complete_handler(struct ci_hdrc *ci) __releases(ci->lock) __acquires(ci->lock) { @@ -861,21 +962,21 @@ __acquires(ci->lock) u8 tmode = 0; for (i = 0; i < ci->hw_ep_max; i++) { - struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i]; + struct ci_hw_ep *hwep = &ci->ci_hw_ep[i]; int type, num, dir, err = -EINVAL; struct usb_ctrlrequest req; - if (mEp->ep.desc == NULL) + if (hwep->ep.desc == NULL) continue; /* not configured */ if (hw_test_and_clear_complete(ci, i)) { - err = isr_tr_complete_low(mEp); - if (mEp->type == USB_ENDPOINT_XFER_CONTROL) { + err = isr_tr_complete_low(hwep); + if (hwep->type == USB_ENDPOINT_XFER_CONTROL) { if (err > 0) /* needs status phase */ err = isr_setup_status_phase(ci); if (err < 0) { spin_unlock(&ci->lock); - if (usb_ep_set_halt(&mEp->ep)) + if (usb_ep_set_halt(&hwep->ep)) dev_err(ci->dev, "error: ep_set_halt\n"); spin_lock(&ci->lock); @@ -883,7 +984,7 @@ __acquires(ci->lock) } } - if (mEp->type != USB_ENDPOINT_XFER_CONTROL || + if (hwep->type != USB_ENDPOINT_XFER_CONTROL || !hw_test_and_clear_setup_status(ci, i)) continue; @@ -902,7 +1003,7 @@ __acquires(ci->lock) /* read_setup_packet */ do { hw_test_and_set_setup_guard(ci); - memcpy(&req, &mEp->qh.ptr->setup, sizeof(req)); + memcpy(&req, &hwep->qh.ptr->setup, sizeof(req)); } while (!hw_test_and_clear_setup_guard(ci)); type = req.bRequestType; @@ -921,10 +1022,10 @@ __acquires(ci->lock) num &= USB_ENDPOINT_NUMBER_MASK; if (dir) /* TX */ num += ci->hw_ep_max/2; - if (!ci->ci13xxx_ep[num].wedge) { + if (!ci->ci_hw_ep[num].wedge) { spin_unlock(&ci->lock); err = usb_ep_clear_halt( - &ci->ci13xxx_ep[num].ep); + &ci->ci_hw_ep[num].ep); spin_lock(&ci->lock); if (err) break; @@ -974,7 +1075,7 @@ __acquires(ci->lock) num += ci->hw_ep_max/2; spin_unlock(&ci->lock); - err = usb_ep_set_halt(&ci->ci13xxx_ep[num].ep); + err = usb_ep_set_halt(&ci->ci_hw_ep[num].ep); spin_lock(&ci->lock); if (!err) isr_setup_status_phase(ci); @@ -1021,7 +1122,7 @@ delegate: if (err < 0) { spin_unlock(&ci->lock); - if (usb_ep_set_halt(&mEp->ep)) + if (usb_ep_set_halt(&hwep->ep)) dev_err(ci->dev, "error: ep_set_halt\n"); spin_lock(&ci->lock); } @@ -1039,7 +1140,7 @@ delegate: static int ep_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) { - struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); + struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep); int retval = 0; unsigned long flags; u32 cap = 0; @@ -1047,39 +1148,41 @@ static int ep_enable(struct usb_ep *ep, if (ep == NULL || desc == NULL) return -EINVAL; - spin_lock_irqsave(mEp->lock, flags); + spin_lock_irqsave(hwep->lock, flags); /* only internal SW should enable ctrl endpts */ - mEp->ep.desc = desc; + hwep->ep.desc = desc; - if (!list_empty(&mEp->qh.queue)) - dev_warn(mEp->ci->dev, "enabling a non-empty endpoint!\n"); + if (!list_empty(&hwep->qh.queue)) + dev_warn(hwep->ci->dev, "enabling a non-empty endpoint!\n"); - mEp->dir = usb_endpoint_dir_in(desc) ? TX : RX; - mEp->num = usb_endpoint_num(desc); - mEp->type = usb_endpoint_type(desc); + hwep->dir = usb_endpoint_dir_in(desc) ? TX : RX; + hwep->num = usb_endpoint_num(desc); + hwep->type = usb_endpoint_type(desc); - mEp->ep.maxpacket = usb_endpoint_maxp(desc); + hwep->ep.maxpacket = usb_endpoint_maxp(desc) & 0x07ff; + hwep->ep.mult = QH_ISO_MULT(usb_endpoint_maxp(desc)); - if (mEp->type == USB_ENDPOINT_XFER_CONTROL) + if (hwep->type == USB_ENDPOINT_XFER_CONTROL) cap |= QH_IOS; - if (mEp->num) + if (hwep->num) cap |= QH_ZLT; - cap |= (mEp->ep.maxpacket << __ffs(QH_MAX_PKT)) & QH_MAX_PKT; + cap |= (hwep->ep.maxpacket << __ffs(QH_MAX_PKT)) & QH_MAX_PKT; - mEp->qh.ptr->cap = cpu_to_le32(cap); + hwep->qh.ptr->cap = cpu_to_le32(cap); - mEp->qh.ptr->td.next |= cpu_to_le32(TD_TERMINATE); /* needed? */ + hwep->qh.ptr->td.next |= cpu_to_le32(TD_TERMINATE); /* needed? */ /* * Enable endpoints in the HW other than ep0 as ep0 * is always enabled */ - if (mEp->num) - retval |= hw_ep_enable(mEp->ci, mEp->num, mEp->dir, mEp->type); + if (hwep->num) + retval |= hw_ep_enable(hwep->ci, hwep->num, hwep->dir, + hwep->type); - spin_unlock_irqrestore(mEp->lock, flags); + spin_unlock_irqrestore(hwep->lock, flags); return retval; } @@ -1090,32 +1193,32 @@ static int ep_enable(struct usb_ep *ep, */ static int ep_disable(struct usb_ep *ep) { - struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); + struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep); int direction, retval = 0; unsigned long flags; if (ep == NULL) return -EINVAL; - else if (mEp->ep.desc == NULL) + else if (hwep->ep.desc == NULL) return -EBUSY; - spin_lock_irqsave(mEp->lock, flags); + spin_lock_irqsave(hwep->lock, flags); /* only internal SW should disable ctrl endpts */ - direction = mEp->dir; + direction = hwep->dir; do { - retval |= _ep_nuke(mEp); - retval |= hw_ep_disable(mEp->ci, mEp->num, mEp->dir); + retval |= _ep_nuke(hwep); + retval |= hw_ep_disable(hwep->ci, hwep->num, hwep->dir); - if (mEp->type == USB_ENDPOINT_XFER_CONTROL) - mEp->dir = (mEp->dir == TX) ? RX : TX; + if (hwep->type == USB_ENDPOINT_XFER_CONTROL) + hwep->dir = (hwep->dir == TX) ? RX : TX; - } while (mEp->dir != direction); + } while (hwep->dir != direction); - mEp->ep.desc = NULL; + hwep->ep.desc = NULL; - spin_unlock_irqrestore(mEp->lock, flags); + spin_unlock_irqrestore(hwep->lock, flags); return retval; } @@ -1126,25 +1229,18 @@ static int ep_disable(struct usb_ep *ep) */ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) { - struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); - struct ci13xxx_req *mReq = NULL; + struct ci_hw_req *hwreq = NULL; if (ep == NULL) return NULL; - mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags); - if (mReq != NULL) { - INIT_LIST_HEAD(&mReq->queue); - - mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags, - &mReq->dma); - if (mReq->ptr == NULL) { - kfree(mReq); - mReq = NULL; - } + hwreq = kzalloc(sizeof(struct ci_hw_req), gfp_flags); + if (hwreq != NULL) { + INIT_LIST_HEAD(&hwreq->queue); + INIT_LIST_HEAD(&hwreq->tds); } - return (mReq == NULL) ? NULL : &mReq->req; + return (hwreq == NULL) ? NULL : &hwreq->req; } /** @@ -1154,24 +1250,30 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) */ static void ep_free_request(struct usb_ep *ep, struct usb_request *req) { - struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); - struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req); + struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep); + struct ci_hw_req *hwreq = container_of(req, struct ci_hw_req, req); + struct td_node *node, *tmpnode; unsigned long flags; if (ep == NULL || req == NULL) { return; - } else if (!list_empty(&mReq->queue)) { - dev_err(mEp->ci->dev, "freeing queued request\n"); + } else if (!list_empty(&hwreq->queue)) { + dev_err(hwep->ci->dev, "freeing queued request\n"); return; } - spin_lock_irqsave(mEp->lock, flags); + spin_lock_irqsave(hwep->lock, flags); - if (mReq->ptr) - dma_pool_free(mEp->td_pool, mReq->ptr, mReq->dma); - kfree(mReq); + list_for_each_entry_safe(node, tmpnode, &hwreq->tds, td) { + dma_pool_free(hwep->td_pool, node->ptr, node->dma); + list_del_init(&node->td); + node->ptr = NULL; + kfree(node); + } - spin_unlock_irqrestore(mEp->lock, flags); + kfree(hwreq); + + spin_unlock_irqrestore(hwep->lock, flags); } /** @@ -1182,16 +1284,16 @@ static void ep_free_request(struct usb_ep *ep, struct usb_request *req) static int ep_queue(struct usb_ep *ep, struct usb_request *req, gfp_t __maybe_unused gfp_flags) { - struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); + struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep); int retval = 0; unsigned long flags; - if (ep == NULL || req == NULL || mEp->ep.desc == NULL) + if (ep == NULL || req == NULL || hwep->ep.desc == NULL) return -EINVAL; - spin_lock_irqsave(mEp->lock, flags); + spin_lock_irqsave(hwep->lock, flags); retval = _ep_queue(ep, req, gfp_flags); - spin_unlock_irqrestore(mEp->lock, flags); + spin_unlock_irqrestore(hwep->lock, flags); return retval; } @@ -1202,33 +1304,33 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req, */ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req) { - struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); - struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req); + struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep); + struct ci_hw_req *hwreq = container_of(req, struct ci_hw_req, req); unsigned long flags; - if (ep == NULL || req == NULL || mReq->req.status != -EALREADY || - mEp->ep.desc == NULL || list_empty(&mReq->queue) || - list_empty(&mEp->qh.queue)) + if (ep == NULL || req == NULL || hwreq->req.status != -EALREADY || + hwep->ep.desc == NULL || list_empty(&hwreq->queue) || + list_empty(&hwep->qh.queue)) return -EINVAL; - spin_lock_irqsave(mEp->lock, flags); + spin_lock_irqsave(hwep->lock, flags); - hw_ep_flush(mEp->ci, mEp->num, mEp->dir); + hw_ep_flush(hwep->ci, hwep->num, hwep->dir); /* pop request */ - list_del_init(&mReq->queue); + list_del_init(&hwreq->queue); - usb_gadget_unmap_request(&mEp->ci->gadget, req, mEp->dir); + usb_gadget_unmap_request(&hwep->ci->gadget, req, hwep->dir); req->status = -ECONNRESET; - if (mReq->req.complete != NULL) { - spin_unlock(mEp->lock); - mReq->req.complete(&mEp->ep, &mReq->req); - spin_lock(mEp->lock); + if (hwreq->req.complete != NULL) { + spin_unlock(hwep->lock); + hwreq->req.complete(&hwep->ep, &hwreq->req); + spin_lock(hwep->lock); } - spin_unlock_irqrestore(mEp->lock, flags); + spin_unlock_irqrestore(hwep->lock, flags); return 0; } @@ -1239,37 +1341,40 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req) */ static int ep_set_halt(struct usb_ep *ep, int value) { - struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); + struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep); int direction, retval = 0; unsigned long flags; - if (ep == NULL || mEp->ep.desc == NULL) + if (ep == NULL || hwep->ep.desc == NULL) return -EINVAL; - spin_lock_irqsave(mEp->lock, flags); + if (usb_endpoint_xfer_isoc(hwep->ep.desc)) + return -EOPNOTSUPP; + + spin_lock_irqsave(hwep->lock, flags); #ifndef STALL_IN /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */ - if (value && mEp->type == USB_ENDPOINT_XFER_BULK && mEp->dir == TX && - !list_empty(&mEp->qh.queue)) { - spin_unlock_irqrestore(mEp->lock, flags); + if (value && hwep->type == USB_ENDPOINT_XFER_BULK && hwep->dir == TX && + !list_empty(&hwep->qh.queue)) { + spin_unlock_irqrestore(hwep->lock, flags); return -EAGAIN; } #endif - direction = mEp->dir; + direction = hwep->dir; do { - retval |= hw_ep_set_halt(mEp->ci, mEp->num, mEp->dir, value); + retval |= hw_ep_set_halt(hwep->ci, hwep->num, hwep->dir, value); if (!value) - mEp->wedge = 0; + hwep->wedge = 0; - if (mEp->type == USB_ENDPOINT_XFER_CONTROL) - mEp->dir = (mEp->dir == TX) ? RX : TX; + if (hwep->type == USB_ENDPOINT_XFER_CONTROL) + hwep->dir = (hwep->dir == TX) ? RX : TX; - } while (mEp->dir != direction); + } while (hwep->dir != direction); - spin_unlock_irqrestore(mEp->lock, flags); + spin_unlock_irqrestore(hwep->lock, flags); return retval; } @@ -1280,15 +1385,15 @@ static int ep_set_halt(struct usb_ep *ep, int value) */ static int ep_set_wedge(struct usb_ep *ep) { - struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); + struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep); unsigned long flags; - if (ep == NULL || mEp->ep.desc == NULL) + if (ep == NULL || hwep->ep.desc == NULL) return -EINVAL; - spin_lock_irqsave(mEp->lock, flags); - mEp->wedge = 1; - spin_unlock_irqrestore(mEp->lock, flags); + spin_lock_irqsave(hwep->lock, flags); + hwep->wedge = 1; + spin_unlock_irqrestore(hwep->lock, flags); return usb_ep_set_halt(ep); } @@ -1300,19 +1405,19 @@ static int ep_set_wedge(struct usb_ep *ep) */ static void ep_fifo_flush(struct usb_ep *ep) { - struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); + struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep); unsigned long flags; if (ep == NULL) { - dev_err(mEp->ci->dev, "%02X: -EINVAL\n", _usb_addr(mEp)); + dev_err(hwep->ci->dev, "%02X: -EINVAL\n", _usb_addr(hwep)); return; } - spin_lock_irqsave(mEp->lock, flags); + spin_lock_irqsave(hwep->lock, flags); - hw_ep_flush(mEp->ci, mEp->num, mEp->dir); + hw_ep_flush(hwep->ci, hwep->num, hwep->dir); - spin_unlock_irqrestore(mEp->lock, flags); + spin_unlock_irqrestore(hwep->lock, flags); } /** @@ -1334,13 +1439,13 @@ static const struct usb_ep_ops usb_ep_ops = { /****************************************************************************** * GADGET block *****************************************************************************/ -static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active) +static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active) { - struct ci13xxx *ci = container_of(_gadget, struct ci13xxx, gadget); + struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); unsigned long flags; int gadget_ready = 0; - if (!(ci->platdata->flags & CI13XXX_PULLUP_ON_VBUS)) + if (!(ci->platdata->flags & CI_HDRC_PULLUP_ON_VBUS)) return -EOPNOTSUPP; spin_lock_irqsave(&ci->lock, flags); @@ -1358,7 +1463,7 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active) hw_device_state(ci, 0); if (ci->platdata->notify_event) ci->platdata->notify_event(ci, - CI13XXX_CONTROLLER_STOPPED_EVENT); + CI_HDRC_CONTROLLER_STOPPED_EVENT); _gadget_stop_activity(&ci->gadget); pm_runtime_put_sync(&_gadget->dev); } @@ -1367,9 +1472,9 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active) return 0; } -static int ci13xxx_wakeup(struct usb_gadget *_gadget) +static int ci_udc_wakeup(struct usb_gadget *_gadget) { - struct ci13xxx *ci = container_of(_gadget, struct ci13xxx, gadget); + struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); unsigned long flags; int ret = 0; @@ -1388,21 +1493,21 @@ out: return ret; } -static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA) +static int ci_udc_vbus_draw(struct usb_gadget *_gadget, unsigned ma) { - struct ci13xxx *ci = container_of(_gadget, struct ci13xxx, gadget); + struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); if (ci->transceiver) - return usb_phy_set_power(ci->transceiver, mA); + return usb_phy_set_power(ci->transceiver, ma); return -ENOTSUPP; } /* Change Data+ pullup status * this func is used by usb_gadget_connect/disconnet */ -static int ci13xxx_pullup(struct usb_gadget *_gadget, int is_on) +static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on) { - struct ci13xxx *ci = container_of(_gadget, struct ci13xxx, gadget); + struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); if (is_on) hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS); @@ -1412,9 +1517,9 @@ static int ci13xxx_pullup(struct usb_gadget *_gadget, int is_on) return 0; } -static int ci13xxx_start(struct usb_gadget *gadget, +static int ci_udc_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver); -static int ci13xxx_stop(struct usb_gadget *gadget, +static int ci_udc_stop(struct usb_gadget *gadget, struct usb_gadget_driver *driver); /** * Device operations part of the API to the USB controller hardware, @@ -1422,46 +1527,46 @@ static int ci13xxx_stop(struct usb_gadget *gadget, * Check "usb_gadget.h" for details */ static const struct usb_gadget_ops usb_gadget_ops = { - .vbus_session = ci13xxx_vbus_session, - .wakeup = ci13xxx_wakeup, - .pullup = ci13xxx_pullup, - .vbus_draw = ci13xxx_vbus_draw, - .udc_start = ci13xxx_start, - .udc_stop = ci13xxx_stop, + .vbus_session = ci_udc_vbus_session, + .wakeup = ci_udc_wakeup, + .pullup = ci_udc_pullup, + .vbus_draw = ci_udc_vbus_draw, + .udc_start = ci_udc_start, + .udc_stop = ci_udc_stop, }; -static int init_eps(struct ci13xxx *ci) +static int init_eps(struct ci_hdrc *ci) { int retval = 0, i, j; for (i = 0; i < ci->hw_ep_max/2; i++) for (j = RX; j <= TX; j++) { int k = i + j * ci->hw_ep_max/2; - struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[k]; + struct ci_hw_ep *hwep = &ci->ci_hw_ep[k]; - scnprintf(mEp->name, sizeof(mEp->name), "ep%i%s", i, + scnprintf(hwep->name, sizeof(hwep->name), "ep%i%s", i, (j == TX) ? "in" : "out"); - mEp->ci = ci; - mEp->lock = &ci->lock; - mEp->td_pool = ci->td_pool; + hwep->ci = ci; + hwep->lock = &ci->lock; + hwep->td_pool = ci->td_pool; - mEp->ep.name = mEp->name; - mEp->ep.ops = &usb_ep_ops; + hwep->ep.name = hwep->name; + hwep->ep.ops = &usb_ep_ops; /* * for ep0: maxP defined in desc, for other * eps, maxP is set by epautoconfig() called * by gadget layer */ - mEp->ep.maxpacket = (unsigned short)~0; + hwep->ep.maxpacket = (unsigned short)~0; - INIT_LIST_HEAD(&mEp->qh.queue); - mEp->qh.ptr = dma_pool_alloc(ci->qh_pool, GFP_KERNEL, - &mEp->qh.dma); - if (mEp->qh.ptr == NULL) + INIT_LIST_HEAD(&hwep->qh.queue); + hwep->qh.ptr = dma_pool_alloc(ci->qh_pool, GFP_KERNEL, + &hwep->qh.dma); + if (hwep->qh.ptr == NULL) retval = -ENOMEM; else - memset(mEp->qh.ptr, 0, sizeof(*mEp->qh.ptr)); + memset(hwep->qh.ptr, 0, sizeof(*hwep->qh.ptr)); /* * set up shorthands for ep0 out and in endpoints, @@ -1469,42 +1574,42 @@ static int init_eps(struct ci13xxx *ci) */ if (i == 0) { if (j == RX) - ci->ep0out = mEp; + ci->ep0out = hwep; else - ci->ep0in = mEp; + ci->ep0in = hwep; - mEp->ep.maxpacket = CTRL_PAYLOAD_MAX; + hwep->ep.maxpacket = CTRL_PAYLOAD_MAX; continue; } - list_add_tail(&mEp->ep.ep_list, &ci->gadget.ep_list); + list_add_tail(&hwep->ep.ep_list, &ci->gadget.ep_list); } return retval; } -static void destroy_eps(struct ci13xxx *ci) +static void destroy_eps(struct ci_hdrc *ci) { int i; for (i = 0; i < ci->hw_ep_max; i++) { - struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i]; + struct ci_hw_ep *hwep = &ci->ci_hw_ep[i]; - dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma); + dma_pool_free(ci->qh_pool, hwep->qh.ptr, hwep->qh.dma); } } /** - * ci13xxx_start: register a gadget driver + * ci_udc_start: register a gadget driver * @gadget: our gadget * @driver: the driver being registered * * Interrupts are enabled here. */ -static int ci13xxx_start(struct usb_gadget *gadget, +static int ci_udc_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { - struct ci13xxx *ci = container_of(gadget, struct ci13xxx, gadget); + struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget); unsigned long flags; int retval = -ENOMEM; @@ -1525,9 +1630,9 @@ static int ci13xxx_start(struct usb_gadget *gadget, ci->driver = driver; pm_runtime_get_sync(&ci->gadget.dev); - if (ci->platdata->flags & CI13XXX_PULLUP_ON_VBUS) { + if (ci->platdata->flags & CI_HDRC_PULLUP_ON_VBUS) { if (ci->vbus_active) { - if (ci->platdata->flags & CI13XXX_REGS_SHARED) + if (ci->platdata->flags & CI_HDRC_REGS_SHARED) hw_device_reset(ci, USBMODE_CM_DC); } else { pm_runtime_put_sync(&ci->gadget.dev); @@ -1545,22 +1650,22 @@ static int ci13xxx_start(struct usb_gadget *gadget, } /** - * ci13xxx_stop: unregister a gadget driver + * ci_udc_stop: unregister a gadget driver */ -static int ci13xxx_stop(struct usb_gadget *gadget, +static int ci_udc_stop(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { - struct ci13xxx *ci = container_of(gadget, struct ci13xxx, gadget); + struct ci_hdrc *ci = container_of(gadget, struct ci_hdrc, gadget); unsigned long flags; spin_lock_irqsave(&ci->lock, flags); - if (!(ci->platdata->flags & CI13XXX_PULLUP_ON_VBUS) || + if (!(ci->platdata->flags & CI_HDRC_PULLUP_ON_VBUS) || ci->vbus_active) { hw_device_state(ci, 0); if (ci->platdata->notify_event) ci->platdata->notify_event(ci, - CI13XXX_CONTROLLER_STOPPED_EVENT); + CI_HDRC_CONTROLLER_STOPPED_EVENT); ci->driver = NULL; spin_unlock_irqrestore(&ci->lock, flags); _gadget_stop_activity(&ci->gadget); @@ -1582,7 +1687,7 @@ static int ci13xxx_stop(struct usb_gadget *gadget, * This function returns IRQ_HANDLED if the IRQ has been handled * It locks access to registers */ -static irqreturn_t udc_irq(struct ci13xxx *ci) +static irqreturn_t udc_irq(struct ci_hdrc *ci) { irqreturn_t retval; u32 intr; @@ -1592,7 +1697,7 @@ static irqreturn_t udc_irq(struct ci13xxx *ci) spin_lock(&ci->lock); - if (ci->platdata->flags & CI13XXX_REGS_SHARED) { + if (ci->platdata->flags & CI_HDRC_REGS_SHARED) { if (hw_read(ci, OP_USBMODE, USBMODE_CM) != USBMODE_CM_DC) { spin_unlock(&ci->lock); @@ -1642,7 +1747,7 @@ static irqreturn_t udc_irq(struct ci13xxx *ci) * udc_start: initialize gadget role * @ci: chipidea controller */ -static int udc_start(struct ci13xxx *ci) +static int udc_start(struct ci_hdrc *ci) { struct device *dev = ci->dev; int retval = 0; @@ -1658,15 +1763,15 @@ static int udc_start(struct ci13xxx *ci) INIT_LIST_HEAD(&ci->gadget.ep_list); /* alloc resources */ - ci->qh_pool = dma_pool_create("ci13xxx_qh", dev, - sizeof(struct ci13xxx_qh), - 64, CI13XXX_PAGE_SIZE); + ci->qh_pool = dma_pool_create("ci_hw_qh", dev, + sizeof(struct ci_hw_qh), + 64, CI_HDRC_PAGE_SIZE); if (ci->qh_pool == NULL) return -ENOMEM; - ci->td_pool = dma_pool_create("ci13xxx_td", dev, - sizeof(struct ci13xxx_td), - 64, CI13XXX_PAGE_SIZE); + ci->td_pool = dma_pool_create("ci_hw_td", dev, + sizeof(struct ci_hw_td), + 64, CI_HDRC_PAGE_SIZE); if (ci->td_pool == NULL) { retval = -ENOMEM; goto free_qh_pool; @@ -1678,23 +1783,26 @@ static int udc_start(struct ci13xxx *ci) ci->gadget.ep0 = &ci->ep0in->ep; - if (ci->global_phy) + if (ci->global_phy) { ci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); + if (IS_ERR(ci->transceiver)) + ci->transceiver = NULL; + } - if (ci->platdata->flags & CI13XXX_REQUIRE_TRANSCEIVER) { + if (ci->platdata->flags & CI_HDRC_REQUIRE_TRANSCEIVER) { if (ci->transceiver == NULL) { retval = -ENODEV; goto destroy_eps; } } - if (!(ci->platdata->flags & CI13XXX_REGS_SHARED)) { + if (!(ci->platdata->flags & CI_HDRC_REGS_SHARED)) { retval = hw_device_reset(ci, USBMODE_CM_DC); if (retval) goto put_transceiver; } - if (!IS_ERR_OR_NULL(ci->transceiver)) { + if (ci->transceiver) { retval = otg_set_peripheral(ci->transceiver->otg, &ci->gadget); if (retval) @@ -1711,7 +1819,7 @@ static int udc_start(struct ci13xxx *ci) return retval; remove_trans: - if (!IS_ERR_OR_NULL(ci->transceiver)) { + if (ci->transceiver) { otg_set_peripheral(ci->transceiver->otg, NULL); if (ci->global_phy) usb_put_phy(ci->transceiver); @@ -1719,7 +1827,7 @@ remove_trans: dev_err(dev, "error = %i\n", retval); put_transceiver: - if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy) + if (ci->transceiver && ci->global_phy) usb_put_phy(ci->transceiver); destroy_eps: destroy_eps(ci); @@ -1735,7 +1843,7 @@ free_qh_pool: * * No interrupts active, the IRQ has been released */ -static void udc_stop(struct ci13xxx *ci) +static void udc_stop(struct ci_hdrc *ci) { if (ci == NULL) return; @@ -1747,7 +1855,7 @@ static void udc_stop(struct ci13xxx *ci) dma_pool_destroy(ci->td_pool); dma_pool_destroy(ci->qh_pool); - if (!IS_ERR_OR_NULL(ci->transceiver)) { + if (ci->transceiver) { otg_set_peripheral(ci->transceiver->otg, NULL); if (ci->global_phy) usb_put_phy(ci->transceiver); @@ -1762,7 +1870,7 @@ static void udc_stop(struct ci13xxx *ci) * * This function enables the gadget role, if the device is "device capable". */ -int ci_hdrc_gadget_init(struct ci13xxx *ci) +int ci_hdrc_gadget_init(struct ci_hdrc *ci) { struct ci_role_driver *rdrv; |