+/* workaround for seemingly-lost IRQs for RX ACKs... */
+#define PIO_OUT_TIMEOUT (jiffies + HZ/3)
+#define HALF_FULL(f) (!((f)&(UDC_NON_ISO_FIFO_FULL|UDC_NON_ISO_FIFO_EMPTY)))
+
+static void pio_out_timer(unsigned long _ep)
+{
+ struct omap_ep *ep = (void *) _ep;
+ unsigned long flags;
+ u16 stat_flg;
+
+ spin_lock_irqsave(&ep->udc->lock, flags);
+ if (!list_empty(&ep->queue) && ep->ackwait) {
+ use_ep(ep, 0);
+ stat_flg = UDC_STAT_FLG_REG;
+
+ if ((stat_flg & UDC_ACK) && (!(stat_flg & UDC_FIFO_EN)
+ || (ep->double_buf && HALF_FULL(stat_flg)))) {
+ struct omap_req *req;
+
+ VDBG("%s: lose, %04x\n", ep->ep.name, stat_flg);
+ req = container_of(ep->queue.next,
+ struct omap_req, queue);
+ UDC_EP_NUM_REG = ep->bEndpointAddress | UDC_EP_SEL;
+ (void) read_fifo(ep, req);
+ UDC_EP_NUM_REG = ep->bEndpointAddress;
+ UDC_CTRL_REG = UDC_SET_FIFO_EN;
+ ep->ackwait = 1 + ep->double_buf;
+ }
+ }
+ mod_timer(&ep->timer, PIO_OUT_TIMEOUT);
+ spin_unlock_irqrestore(&ep->udc->lock, flags);
+}
+