ARM: 5682/1: Add cpu.c and dev.c and modify some files of w90p910 platform
[safe/jmp/linux-2.6] / drivers / usb / host / isp116x-hcd.c
index 35b3507..a2b3054 100644 (file)
@@ -94,6 +94,10 @@ static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len)
        u16 w;
        int quot = len % 4;
 
+       /* buffer is already in 'usb data order', which is LE. */
+       /* When reading buffer as u16, we have to take care byte order */
+       /* doesn't get mixed up */
+
        if ((unsigned long)dp2 & 1) {
                /* not aligned */
                for (; len > 1; len -= 2) {
@@ -105,8 +109,11 @@ static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len)
                        isp116x_write_data16(isp116x, (u16) * dp);
        } else {
                /* aligned */
-               for (; len > 1; len -= 2)
-                       isp116x_raw_write_data16(isp116x, *dp2++);
+               for (; len > 1; len -= 2) {
+                       /* Keep byte order ! */
+                       isp116x_raw_write_data16(isp116x, cpu_to_le16(*dp2++));
+               }
+
                if (len)
                        isp116x_write_data16(isp116x, 0xff & *((u8 *) dp2));
        }
@@ -124,6 +131,10 @@ static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
        u16 w;
        int quot = len % 4;
 
+       /* buffer is already in 'usb data order', which is LE. */
+       /* When reading buffer as u16, we have to take care byte order */
+       /* doesn't get mixed up */
+
        if ((unsigned long)dp2 & 1) {
                /* not aligned */
                for (; len > 1; len -= 2) {
@@ -131,12 +142,16 @@ static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
                        *dp++ = w & 0xff;
                        *dp++ = (w >> 8) & 0xff;
                }
+
                if (len)
                        *dp = 0xff & isp116x_read_data16(isp116x);
        } else {
                /* aligned */
-               for (; len > 1; len -= 2)
-                       *dp2++ = isp116x_raw_read_data16(isp116x);
+               for (; len > 1; len -= 2) {
+                       /* Keep byte order! */
+                       *dp2++ = le16_to_cpu(isp116x_raw_read_data16(isp116x));
+               }
+
                if (len)
                        *(u8 *) dp2 = 0xff & isp116x_read_data16(isp116x);
        }
@@ -277,7 +292,7 @@ static void preproc_atl_queue(struct isp116x *isp116x)
   processed urbs.
 */
 static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep,
-                          struct urb *urb)
+                          struct urb *urb, int status)
 __releases(isp116x->lock) __acquires(isp116x->lock)
 {
        unsigned i;
@@ -291,7 +306,7 @@ __releases(isp116x->lock) __acquires(isp116x->lock)
 
        usb_hcd_unlink_urb_from_ep(isp116x_to_hcd(isp116x), urb);
        spin_unlock(&isp116x->lock);
-       usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb);
+       usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb, status);
        spin_lock(&isp116x->lock);
 
        /* take idle endpoints out of the schedule */
@@ -453,13 +468,8 @@ static void postproc_atl_queue(struct isp116x *isp116x)
                }
 
  done:
-               if (status != -EINPROGRESS) {
-                       spin_lock(&urb->lock);
-                       urb->status = status;
-                       spin_unlock(&urb->lock);
-               }
-               if (urb->status != -EINPROGRESS || urb->unlinked)
-                       finish_request(isp116x, ep, urb);
+               if (status != -EINPROGRESS || urb->unlinked)
+                       finish_request(isp116x, ep, urb, status);
        }
 }
 
@@ -762,7 +772,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd,
                break;
        case PIPE_INTERRUPT:
                urb->interval = ep->period;
-               ep->length = min((int)ep->maxpacket,
+               ep->length = min_t(u32, ep->maxpacket,
                                 urb->transfer_buffer_length);
 
                /* urb submitted for already existing endpoint */
@@ -853,7 +863,7 @@ static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
                        }
 
        if (urb)
-               finish_request(isp116x, ep, urb);
+               finish_request(isp116x, ep, urb, status);
  done:
        spin_unlock_irqrestore(&isp116x->lock, flags);
        return rc;
@@ -872,7 +882,7 @@ static void isp116x_endpoint_disable(struct usb_hcd *hcd,
        for (i = 0; i < 100 && !list_empty(&hep->urb_list); i++)
                msleep(3);
        if (!list_empty(&hep->urb_list))
-               WARN("ep %p not empty?\n", ep);
+               WARNING("ep %p not empty?\n", ep);
 
        kfree(ep);
        hep->hcpriv = NULL;
@@ -916,14 +926,12 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf)
                buf[0] = 0;
 
        for (i = 0; i < ports; i++) {
-               u32 status = isp116x->rhport[i] =
-                   isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1);
+               u32 status = isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1);
 
                if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
                              | RH_PS_OCIC | RH_PS_PRSC)) {
                        changed = 1;
                        buf[0] |= 1 << (i + 1);
-                       continue;
                }
        }
        spin_unlock_irqrestore(&isp116x->lock, flags);
@@ -1037,7 +1045,9 @@ static int isp116x_hub_control(struct usb_hcd *hcd,
                DBG("GetPortStatus\n");
                if (!wIndex || wIndex > ports)
                        goto error;
-               tmp = isp116x->rhport[--wIndex];
+               spin_lock_irqsave(&isp116x->lock, flags);
+               tmp = isp116x_read_reg32(isp116x, (--wIndex) ? HCRHPORT2 : HCRHPORT1);
+               spin_unlock_irqrestore(&isp116x->lock, flags);
                *(__le32 *) buf = cpu_to_le32(tmp);
                DBG("GetPortStatus: port[%d]  %08x\n", wIndex + 1, tmp);
                break;
@@ -1086,8 +1096,6 @@ static int isp116x_hub_control(struct usb_hcd *hcd,
                spin_lock_irqsave(&isp116x->lock, flags);
                isp116x_write_reg32(isp116x, wIndex
                                    ? HCRHPORT2 : HCRHPORT1, tmp);
-               isp116x->rhport[wIndex] =
-                   isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1);
                spin_unlock_irqrestore(&isp116x->lock, flags);
                break;
        case SetPortFeature:
@@ -1101,24 +1109,22 @@ static int isp116x_hub_control(struct usb_hcd *hcd,
                        spin_lock_irqsave(&isp116x->lock, flags);
                        isp116x_write_reg32(isp116x, wIndex
                                            ? HCRHPORT2 : HCRHPORT1, RH_PS_PSS);
+                       spin_unlock_irqrestore(&isp116x->lock, flags);
                        break;
                case USB_PORT_FEAT_POWER:
                        DBG("USB_PORT_FEAT_POWER\n");
                        spin_lock_irqsave(&isp116x->lock, flags);
                        isp116x_write_reg32(isp116x, wIndex
                                            ? HCRHPORT2 : HCRHPORT1, RH_PS_PPS);
+                       spin_unlock_irqrestore(&isp116x->lock, flags);
                        break;
                case USB_PORT_FEAT_RESET:
                        DBG("USB_PORT_FEAT_RESET\n");
                        root_port_reset(isp116x, wIndex);
-                       spin_lock_irqsave(&isp116x->lock, flags);
                        break;
                default:
                        goto error;
                }
-               isp116x->rhport[wIndex] =
-                   isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1);
-               spin_unlock_irqrestore(&isp116x->lock, flags);
                break;
 
        default:
@@ -1409,7 +1415,7 @@ static int isp116x_bus_suspend(struct usb_hcd *hcd)
                spin_unlock_irqrestore(&isp116x->lock, flags);
                val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE);
                val |= HCCONTROL_USB_SUSPEND;
-               if (device_may_wakeup(&hcd->self.root_hub->dev))
+               if (hcd->self.root_hub->do_remote_wakeup)
                        val |= HCCONTROL_RWE;
                /* Wait for usb transfers to finish */
                msleep(2);
@@ -1451,11 +1457,6 @@ static int isp116x_bus_resume(struct usb_hcd *hcd)
                break;
        case HCCONTROL_USB_OPER:
                spin_unlock_irq(&isp116x->lock);
-               /* Without setting power_state here the
-                  SUSPENDED state won't be removed from
-                  sysfs/usbN/power.state as a response to remote
-                  wakeup. Maybe in the future. */
-               hcd->self.root_hub->dev.power.power_state = PMSG_ON;
                return 0;
        default:
                /* HCCONTROL_USB_RESET: this may happen, when during
@@ -1469,7 +1470,6 @@ static int isp116x_bus_resume(struct usb_hcd *hcd)
                if ((isp116x->rhdesca & RH_A_NDP) == 2)
                        isp116x_hub_control(hcd, SetPortFeature,
                                            USB_PORT_FEAT_POWER, 2, NULL, 0);
-               hcd->self.root_hub->dev.power.power_state = PMSG_ON;
                return 0;
        }
 
@@ -1495,8 +1495,6 @@ static int isp116x_bus_resume(struct usb_hcd *hcd)
        isp116x_write_reg32(isp116x, HCCONTROL,
                            (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER);
        spin_unlock_irq(&isp116x->lock);
-       /* see analogous comment above */
-       hcd->self.root_hub->dev.power.power_state = PMSG_ON;
        hcd->state = HC_STATE_RUNNING;
 
        return 0;
@@ -1564,11 +1562,12 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
 {
        struct usb_hcd *hcd;
        struct isp116x *isp116x;
-       struct resource *addr, *data;
+       struct resource *addr, *data, *ires;
        void __iomem *addr_reg;
        void __iomem *data_reg;
        int irq;
        int ret = 0;
+       unsigned long irqflags;
 
        if (pdev->num_resources < 3) {
                ret = -ENODEV;
@@ -1577,12 +1576,16 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
 
        data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       irq = platform_get_irq(pdev, 0);
-       if (!addr || !data || irq < 0) {
+       ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+       if (!addr || !data || !ires) {
                ret = -ENODEV;
                goto err1;
        }
 
+       irq = ires->start;
+       irqflags = ires->flags & IRQF_TRIGGER_MASK;
+
        if (pdev->dev.dma_mask) {
                DBG("DMA not supported\n");
                ret = -EINVAL;
@@ -1609,7 +1612,7 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
        }
 
        /* allocate and initialize hcd */
-       hcd = usb_create_hcd(&isp116x_hc_driver, &pdev->dev, pdev->dev.bus_id);
+       hcd = usb_create_hcd(&isp116x_hc_driver, &pdev->dev, dev_name(&pdev->dev));
        if (!hcd) {
                ret = -ENOMEM;
                goto err5;
@@ -1636,7 +1639,7 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
                goto err6;
        }
 
-       ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+       ret = usb_add_hcd(hcd, irq, irqflags | IRQF_DISABLED);
        if (ret)
                goto err6;
 
@@ -1672,7 +1675,6 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
 static int isp116x_suspend(struct platform_device *dev, pm_message_t state)
 {
        VDBG("%s: state %x\n", __func__, state.event);
-       dev->dev.power.power_state = state;
        return 0;
 }
 
@@ -1681,8 +1683,7 @@ static int isp116x_suspend(struct platform_device *dev, pm_message_t state)
 */
 static int isp116x_resume(struct platform_device *dev)
 {
-       VDBG("%s:  state %x\n", __func__, dev->power.power_state.event);
-       dev->dev.power.power_state = PMSG_ON;
+       VDBG("%s\n", __func__);
        return 0;
 }
 
@@ -1693,14 +1694,18 @@ static int isp116x_resume(struct platform_device *dev)
 
 #endif
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:isp116x-hcd");
+
 static struct platform_driver isp116x_driver = {
        .probe = isp116x_probe,
        .remove = isp116x_remove,
        .suspend = isp116x_suspend,
        .resume = isp116x_resume,
        .driver = {
-                  .name = (char *)hcd_name,
-                  },
+               .name = (char *)hcd_name,
+               .owner  = THIS_MODULE,
+       },
 };
 
 /*-----------------------------------------------------------------*/