*/
 static unsigned int dwc2_gadget_get_chain_limit(struct dwc2_hsotg_ep *hs_ep)
 {
+       const struct usb_endpoint_descriptor *ep_desc = hs_ep->ep.desc;
        int is_isoc = hs_ep->isochronous;
        unsigned int maxsize;
+       u32 mps = hs_ep->ep.maxpacket;
+       int dir_in = hs_ep->dir_in;
 
        if (is_isoc)
                maxsize = (hs_ep->dir_in ? DEV_DMA_ISOC_TX_NBYTES_LIMIT :
        else
                maxsize = DEV_DMA_NBYTES_LIMIT * MAX_DMA_DESC_NUM_GENERIC;
 
+       /* Interrupt OUT EP with mps not multiple of 4 */
+       if (hs_ep->index)
+               if (usb_endpoint_xfer_int(ep_desc) && !dir_in && (mps % 4))
+                       maxsize = mps * MAX_DMA_DESC_NUM_GENERIC;
+
        return maxsize;
 }
 
  * Isochronous - descriptor rx/tx bytes bitfield limit,
  * Control In/Bulk/Interrupt - multiple of mps. This will allow to not
  * have concatenations from various descriptors within one packet.
+ * Interrupt OUT - if mps not multiple of 4 then a single packet corresponds
+ * to a single descriptor.
  *
  * Selects corresponding mask for RX/TX bytes as well.
  */
 static u32 dwc2_gadget_get_desc_params(struct dwc2_hsotg_ep *hs_ep, u32 *mask)
 {
+       const struct usb_endpoint_descriptor *ep_desc = hs_ep->ep.desc;
        u32 mps = hs_ep->ep.maxpacket;
        int dir_in = hs_ep->dir_in;
        u32 desc_size = 0;
                desc_size -= desc_size % mps;
        }
 
+       /* Interrupt OUT EP with mps not multiple of 4 */
+       if (hs_ep->index)
+               if (usb_endpoint_xfer_int(ep_desc) && !dir_in && (mps % 4)) {
+                       desc_size = mps;
+                       *mask = DEV_DMA_NBYTES_MASK;
+               }
+
        return desc_size;
 }
 
                                length += (mps - (length % mps));
                }
 
-               /*
-                * If more data to send, adjust DMA for EP0 out data stage.
-                * ureq->dma stays unchanged, hence increment it by already
-                * passed passed data count before starting new transaction.
-                */
-               if (!index && hsotg->ep0_state == DWC2_EP0_DATA_OUT &&
-                   continuing)
+               if (continuing)
                        offset = ureq->actual;
 
                /* Fill DDMA chain entries */
  */
 static unsigned int dwc2_gadget_get_xfersize_ddma(struct dwc2_hsotg_ep *hs_ep)
 {
+       const struct usb_endpoint_descriptor *ep_desc = hs_ep->ep.desc;
        struct dwc2_hsotg *hsotg = hs_ep->parent;
        unsigned int bytes_rem = 0;
+       unsigned int bytes_rem_correction = 0;
        struct dwc2_dma_desc *desc = hs_ep->desc_list;
        int i;
        u32 status;
+       u32 mps = hs_ep->ep.maxpacket;
+       int dir_in = hs_ep->dir_in;
 
        if (!desc)
                return -EINVAL;
 
+       /* Interrupt OUT EP with mps not multiple of 4 */
+       if (hs_ep->index)
+               if (usb_endpoint_xfer_int(ep_desc) && !dir_in && (mps % 4))
+                       bytes_rem_correction = 4 - (mps % 4);
+
        for (i = 0; i < hs_ep->desc_count; ++i) {
                status = desc->status;
                bytes_rem += status & DEV_DMA_NBYTES_MASK;
+               bytes_rem -= bytes_rem_correction;
 
                if (status & DEV_DMA_STS_MASK)
                        dev_err(hsotg->dev, "descriptor %d closed with %x\n",
                                i, status & DEV_DMA_STS_MASK);
+
+               if (status & DEV_DMA_L)
+                       break;
+
                desc++;
        }