rtc: rtc-lp8788: use devm_rtc_device_register()
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / usb / chipidea / udc.c
index 3abd1ad5ced1f07dffa3592b3c3e64f7342c0405..519ead2443c5630baaacaa4e1023e8ec766a2e39 100644 (file)
@@ -429,12 +429,14 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
                        mReq->ptr->token  |= cpu_to_le32(TD_IOC);
        }
        mReq->ptr->page[0]  = cpu_to_le32(mReq->req.dma);
-       for (i = 1; i < 5; i++) {
+       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);
        }
 
+       wmb();
+
        if (!list_empty(&mEp->qh.queue)) {
                struct ci13xxx_req *mReqPrev;
                int n = hw_ep_bit(mEp->num, mEp->dir);
@@ -463,7 +465,6 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
        mEp->qh.ptr->td.next   = cpu_to_le32(mReq->dma);    /* TERMINATE = 0 */
        mEp->qh.ptr->td.token &=
                cpu_to_le32(~(TD_STATUS_HALTED|TD_STATUS_ACTIVE));
-       mEp->qh.ptr->cap |=  cpu_to_le32(QH_ZLT);
 
        wmb();   /* synchronize before ep prime */
 
@@ -482,10 +483,12 @@ done:
  */
 static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
 {
+       u32 tmptoken = le32_to_cpu(mReq->ptr->token);
+
        if (mReq->req.status != -EALREADY)
                return -EINVAL;
 
-       if ((cpu_to_le32(TD_STATUS_ACTIVE) & mReq->ptr->token) != 0)
+       if ((TD_STATUS_ACTIVE & tmptoken) != 0)
                return -EBUSY;
 
        if (mReq->zptr) {
@@ -499,7 +502,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
 
        usb_gadget_unmap_request(&mEp->ci->gadget, &mReq->req, mEp->dir);
 
-       mReq->req.status = le32_to_cpu(mReq->ptr->token) & TD_STATUS;
+       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)
@@ -507,7 +510,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
        else if ((TD_STATUS_TR_ERR & mReq->req.status) != 0)
                mReq->req.status = -1;
 
-       mReq->req.actual   = le32_to_cpu(mReq->ptr->token) & TD_TOTAL_BYTES;
+       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;
@@ -537,6 +540,12 @@ __acquires(mEp->lock)
                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;
+               }
+
                list_del_init(&mReq->queue);
                mReq->req.status = -ESHUTDOWN;
 
@@ -641,6 +650,59 @@ static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req)
        usb_ep_free_request(ep, req);
 }
 
+/**
+ * _ep_queue: queues (submits) an I/O request to an endpoint
+ *
+ * Caller must hold lock
+ */
+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;
+       int retval = 0;
+
+       if (ep == NULL || req == NULL || mEp->ep.desc == NULL)
+               return -EINVAL;
+
+       if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
+               if (req->length)
+                       mEp = (ci->ep0_dir == RX) ?
+                              ci->ep0out : ci->ep0in;
+               if (!list_empty(&mEp->qh.queue)) {
+                       _ep_nuke(mEp);
+                       retval = -EOVERFLOW;
+                       dev_warn(mEp->ci->dev, "endpoint ctrl %X nuked\n",
+                                _usb_addr(mEp));
+               }
+       }
+
+       /* 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 (req->length > (TD_PAGE_COUNT - 1) * CI13XXX_PAGE_SIZE) {
+               dev_err(mEp->ci->dev, "request bigger than one td\n");
+               return -EMSGSIZE;
+       }
+
+       /* push request */
+       mReq->req.status = -EINPROGRESS;
+       mReq->req.actual = 0;
+
+       retval = _hardware_enqueue(mEp, mReq);
+
+       if (retval == -EALREADY)
+               retval = 0;
+       if (!retval)
+               list_add_tail(&mReq->queue, &mEp->qh.queue);
+
+       return retval;
+}
+
 /**
  * isr_get_status_response: get_status request response
  * @ci: ci struct
@@ -688,9 +750,7 @@ __acquires(mEp->lock)
        }
        /* else do nothing; reserved for future use */
 
-       spin_unlock(mEp->lock);
-       retval = usb_ep_queue(&mEp->ep, req, gfp_flags);
-       spin_lock(mEp->lock);
+       retval = _ep_queue(&mEp->ep, req, gfp_flags);
        if (retval)
                goto err_free_buf;
 
@@ -737,8 +797,6 @@ 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)
-__releases(mEp->lock)
-__acquires(mEp->lock)
 {
        int retval;
        struct ci13xxx_ep *mEp;
@@ -747,9 +805,7 @@ __acquires(mEp->lock)
        ci->status->context = ci;
        ci->status->complete = isr_setup_status_complete;
 
-       spin_unlock(mEp->lock);
-       retval = usb_ep_queue(&mEp->ep, ci->status, GFP_ATOMIC);
-       spin_lock(mEp->lock);
+       retval = _ep_queue(&mEp->ep, ci->status, GFP_ATOMIC);
 
        return retval;
 }
@@ -1008,6 +1064,8 @@ static int ep_enable(struct usb_ep *ep,
 
        if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
                cap |= QH_IOS;
+       if (mEp->num)
+               cap |= QH_ZLT;
        cap |= (mEp->ep.maxpacket << __ffs(QH_MAX_PKT)) & QH_MAX_PKT;
 
        mEp->qh.ptr->cap = cpu_to_le32(cap);
@@ -1125,8 +1183,6 @@ 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;
        int retval = 0;
        unsigned long flags;
 
@@ -1134,44 +1190,7 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req,
                return -EINVAL;
 
        spin_lock_irqsave(mEp->lock, flags);
-
-       if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
-               if (req->length)
-                       mEp = (ci->ep0_dir == RX) ?
-                              ci->ep0out : ci->ep0in;
-               if (!list_empty(&mEp->qh.queue)) {
-                       _ep_nuke(mEp);
-                       retval = -EOVERFLOW;
-                       dev_warn(mEp->ci->dev, "endpoint ctrl %X nuked\n",
-                                _usb_addr(mEp));
-               }
-       }
-
-       /* first nuke then test link, e.g. previous status has not sent */
-       if (!list_empty(&mReq->queue)) {
-               retval = -EBUSY;
-               dev_err(mEp->ci->dev, "request already in queue\n");
-               goto done;
-       }
-
-       if (req->length > 4 * CI13XXX_PAGE_SIZE) {
-               req->length = 4 * CI13XXX_PAGE_SIZE;
-               retval = -EMSGSIZE;
-               dev_warn(mEp->ci->dev, "request length truncated\n");
-       }
-
-       /* push request */
-       mReq->req.status = -EINPROGRESS;
-       mReq->req.actual = 0;
-
-       retval = _hardware_enqueue(mEp, mReq);
-
-       if (retval == -EALREADY)
-               retval = 0;
-       if (!retval)
-               list_add_tail(&mReq->queue, &mEp->qh.queue);
-
- done:
+       retval = _ep_queue(ep, req, gfp_flags);
        spin_unlock_irqrestore(mEp->lock, flags);
        return retval;
 }
@@ -1619,16 +1638,6 @@ static irqreturn_t udc_irq(struct ci13xxx *ci)
        return retval;
 }
 
-/**
- * udc_release: driver release function
- * @dev: device
- *
- * Currently does nothing
- */
-static void udc_release(struct device *dev)
-{
-}
-
 /**
  * udc_start: initialize gadget role
  * @ci: chipidea controller
@@ -1648,12 +1657,6 @@ static int udc_start(struct ci13xxx *ci)
 
        INIT_LIST_HEAD(&ci->gadget.ep_list);
 
-       dev_set_name(&ci->gadget.dev, "gadget");
-       ci->gadget.dev.dma_mask = dev->dma_mask;
-       ci->gadget.dev.coherent_dma_mask = dev->coherent_dma_mask;
-       ci->gadget.dev.parent   = dev;
-       ci->gadget.dev.release  = udc_release;
-
        /* alloc resources */
        ci->qh_pool = dma_pool_create("ci13xxx_qh", dev,
                                       sizeof(struct ci13xxx_qh),
@@ -1691,17 +1694,11 @@ static int udc_start(struct ci13xxx *ci)
                        goto put_transceiver;
        }
 
-       retval = device_register(&ci->gadget.dev);
-       if (retval) {
-               put_device(&ci->gadget.dev);
-               goto put_transceiver;
-       }
-
        if (!IS_ERR_OR_NULL(ci->transceiver)) {
                retval = otg_set_peripheral(ci->transceiver->otg,
                                                &ci->gadget);
                if (retval)
-                       goto unreg_device;
+                       goto put_transceiver;
        }
 
        retval = usb_add_gadget_udc(dev, &ci->gadget);
@@ -1721,8 +1718,6 @@ remove_trans:
        }
 
        dev_err(dev, "error = %i\n", retval);
-unreg_device:
-       device_unregister(&ci->gadget.dev);
 put_transceiver:
        if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy)
                usb_put_phy(ci->transceiver);
@@ -1757,7 +1752,6 @@ static void udc_stop(struct ci13xxx *ci)
                if (ci->global_phy)
                        usb_put_phy(ci->transceiver);
        }
-       device_unregister(&ci->gadget.dev);
        /* my kobject is dynamic, I swear! */
        memset(&ci->gadget, 0, sizeof(ci->gadget));
 }