diff options
Diffstat (limited to 'drivers/usb/host/isp1760-hcd.c')
-rw-r--r-- | drivers/usb/host/isp1760-hcd.c | 81 |
1 files changed, 60 insertions, 21 deletions
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 65aa5ecf569a..c858f2adb929 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c | |||
@@ -38,6 +38,7 @@ struct isp1760_hcd { | |||
38 | unsigned i_thresh; | 38 | unsigned i_thresh; |
39 | unsigned long reset_done; | 39 | unsigned long reset_done; |
40 | unsigned long next_statechange; | 40 | unsigned long next_statechange; |
41 | unsigned int devflags; | ||
41 | }; | 42 | }; |
42 | 43 | ||
43 | static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) | 44 | static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd) |
@@ -378,9 +379,31 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) | |||
378 | { | 379 | { |
379 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | 380 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
380 | int result; | 381 | int result; |
381 | u32 scratch; | 382 | u32 scratch, hwmode; |
383 | |||
384 | /* Setup HW Mode Control: This assumes a level active-low interrupt */ | ||
385 | hwmode = HW_DATA_BUS_32BIT; | ||
386 | |||
387 | if (priv->devflags & ISP1760_FLAG_BUS_WIDTH_16) | ||
388 | hwmode &= ~HW_DATA_BUS_32BIT; | ||
389 | if (priv->devflags & ISP1760_FLAG_ANALOG_OC) | ||
390 | hwmode |= HW_ANA_DIGI_OC; | ||
391 | if (priv->devflags & ISP1760_FLAG_DACK_POL_HIGH) | ||
392 | hwmode |= HW_DACK_POL_HIGH; | ||
393 | if (priv->devflags & ISP1760_FLAG_DREQ_POL_HIGH) | ||
394 | hwmode |= HW_DREQ_POL_HIGH; | ||
395 | |||
396 | /* | ||
397 | * We have to set this first in case we're in 16-bit mode. | ||
398 | * Write it twice to ensure correct upper bits if switching | ||
399 | * to 16-bit mode. | ||
400 | */ | ||
401 | isp1760_writel(hwmode, hcd->regs + HC_HW_MODE_CTRL); | ||
402 | isp1760_writel(hwmode, hcd->regs + HC_HW_MODE_CTRL); | ||
382 | 403 | ||
383 | isp1760_writel(0xdeadbabe, hcd->regs + HC_SCRATCH_REG); | 404 | isp1760_writel(0xdeadbabe, hcd->regs + HC_SCRATCH_REG); |
405 | /* Change bus pattern */ | ||
406 | scratch = isp1760_readl(hcd->regs + HC_CHIP_ID_REG); | ||
384 | scratch = isp1760_readl(hcd->regs + HC_SCRATCH_REG); | 407 | scratch = isp1760_readl(hcd->regs + HC_SCRATCH_REG); |
385 | if (scratch != 0xdeadbabe) { | 408 | if (scratch != 0xdeadbabe) { |
386 | printk(KERN_ERR "ISP1760: Scratch test failed.\n"); | 409 | printk(KERN_ERR "ISP1760: Scratch test failed.\n"); |
@@ -403,17 +426,29 @@ static int isp1760_hc_setup(struct usb_hcd *hcd) | |||
403 | 426 | ||
404 | /* Step 11 passed */ | 427 | /* Step 11 passed */ |
405 | 428 | ||
406 | isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_REG); | 429 | isp1760_info(priv, "bus width: %d, oc: %s\n", |
407 | isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_ENABLE); | 430 | (priv->devflags & ISP1760_FLAG_BUS_WIDTH_16) ? |
431 | 16 : 32, (priv->devflags & ISP1760_FLAG_ANALOG_OC) ? | ||
432 | "analog" : "digital"); | ||
408 | 433 | ||
409 | /* ATL reset */ | 434 | /* ATL reset */ |
410 | scratch = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); | 435 | isp1760_writel(hwmode | ALL_ATX_RESET, hcd->regs + HC_HW_MODE_CTRL); |
411 | isp1760_writel(scratch | ALL_ATX_RESET, hcd->regs + HC_HW_MODE_CTRL); | ||
412 | mdelay(10); | 436 | mdelay(10); |
413 | isp1760_writel(scratch, hcd->regs + HC_HW_MODE_CTRL); | 437 | isp1760_writel(hwmode, hcd->regs + HC_HW_MODE_CTRL); |
414 | 438 | ||
415 | isp1760_writel(PORT1_POWER | PORT1_INIT2, hcd->regs + HC_PORT1_CTRL); | 439 | isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_REG); |
416 | mdelay(10); | 440 | isp1760_writel(INTERRUPT_ENABLE_MASK, hcd->regs + HC_INTERRUPT_ENABLE); |
441 | |||
442 | /* | ||
443 | * PORT 1 Control register of the ISP1760 is the OTG control | ||
444 | * register on ISP1761. | ||
445 | */ | ||
446 | if (!(priv->devflags & ISP1760_FLAG_ISP1761) && | ||
447 | !(priv->devflags & ISP1760_FLAG_PORT1_DIS)) { | ||
448 | isp1760_writel(PORT1_POWER | PORT1_INIT2, | ||
449 | hcd->regs + HC_PORT1_CTRL); | ||
450 | mdelay(10); | ||
451 | } | ||
417 | 452 | ||
418 | priv->hcs_params = isp1760_readl(hcd->regs + HC_HCSPARAMS); | 453 | priv->hcs_params = isp1760_readl(hcd->regs + HC_HCSPARAMS); |
419 | 454 | ||
@@ -453,8 +488,7 @@ static int isp1760_run(struct usb_hcd *hcd) | |||
453 | hcd->state = HC_STATE_RUNNING; | 488 | hcd->state = HC_STATE_RUNNING; |
454 | isp1760_enable_interrupts(hcd); | 489 | isp1760_enable_interrupts(hcd); |
455 | temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); | 490 | temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); |
456 | temp |= FINAL_HW_CONFIG; | 491 | isp1760_writel(temp | HW_GLOBAL_INTR_EN, hcd->regs + HC_HW_MODE_CTRL); |
457 | isp1760_writel(temp, hcd->regs + HC_HW_MODE_CTRL); | ||
458 | 492 | ||
459 | command = isp1760_readl(hcd->regs + HC_USBCMD); | 493 | command = isp1760_readl(hcd->regs + HC_USBCMD); |
460 | command &= ~(CMD_LRESET|CMD_RESET); | 494 | command &= ~(CMD_LRESET|CMD_RESET); |
@@ -782,8 +816,8 @@ static void enqueue_one_int_qtd(u32 int_regs, u32 payload, | |||
782 | qtd->status |= slot << 16; | 816 | qtd->status |= slot << 16; |
783 | } | 817 | } |
784 | 818 | ||
785 | void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | 819 | static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, |
786 | struct isp1760_qtd *qtd) | 820 | struct isp1760_qtd *qtd) |
787 | { | 821 | { |
788 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | 822 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
789 | u32 skip_map, or_map; | 823 | u32 skip_map, or_map; |
@@ -816,8 +850,8 @@ void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | |||
816 | isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG); | 850 | isp1760_writel(buffstatus, hcd->regs + HC_BUFFER_STATUS_REG); |
817 | } | 851 | } |
818 | 852 | ||
819 | void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | 853 | static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, |
820 | struct isp1760_qtd *qtd) | 854 | struct isp1760_qtd *qtd) |
821 | { | 855 | { |
822 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | 856 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
823 | u32 skip_map, or_map; | 857 | u32 skip_map, or_map; |
@@ -1592,7 +1626,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, | |||
1592 | struct inter_packet_info *ints; | 1626 | struct inter_packet_info *ints; |
1593 | u32 i; | 1627 | u32 i; |
1594 | u32 reg_base, or_reg, skip_reg; | 1628 | u32 reg_base, or_reg, skip_reg; |
1595 | int flags; | 1629 | unsigned long flags; |
1596 | struct ptd ptd; | 1630 | struct ptd ptd; |
1597 | 1631 | ||
1598 | switch (usb_pipetype(urb->pipe)) { | 1632 | switch (usb_pipetype(urb->pipe)) { |
@@ -2061,7 +2095,7 @@ static void isp1760_endpoint_disable(struct usb_hcd *usb_hcd, | |||
2061 | struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); | 2095 | struct isp1760_hcd *priv = hcd_to_priv(usb_hcd); |
2062 | struct isp1760_qh *qh; | 2096 | struct isp1760_qh *qh; |
2063 | struct isp1760_qtd *qtd; | 2097 | struct isp1760_qtd *qtd; |
2064 | u32 flags; | 2098 | unsigned long flags; |
2065 | 2099 | ||
2066 | spin_lock_irqsave(&priv->lock, flags); | 2100 | spin_lock_irqsave(&priv->lock, flags); |
2067 | qh = ep->hcpriv; | 2101 | qh = ep->hcpriv; |
@@ -2112,6 +2146,7 @@ static int isp1760_get_frame(struct usb_hcd *hcd) | |||
2112 | static void isp1760_stop(struct usb_hcd *hcd) | 2146 | static void isp1760_stop(struct usb_hcd *hcd) |
2113 | { | 2147 | { |
2114 | struct isp1760_hcd *priv = hcd_to_priv(hcd); | 2148 | struct isp1760_hcd *priv = hcd_to_priv(hcd); |
2149 | u32 temp; | ||
2115 | 2150 | ||
2116 | isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1, | 2151 | isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER, 1, |
2117 | NULL, 0); | 2152 | NULL, 0); |
@@ -2120,7 +2155,8 @@ static void isp1760_stop(struct usb_hcd *hcd) | |||
2120 | spin_lock_irq(&priv->lock); | 2155 | spin_lock_irq(&priv->lock); |
2121 | ehci_reset(priv); | 2156 | ehci_reset(priv); |
2122 | /* Disable IRQ */ | 2157 | /* Disable IRQ */ |
2123 | isp1760_writel(HW_DATA_BUS_32BIT, hcd->regs + HC_HW_MODE_CTRL); | 2158 | temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); |
2159 | isp1760_writel(temp &= ~HW_GLOBAL_INTR_EN, hcd->regs + HC_HW_MODE_CTRL); | ||
2124 | spin_unlock_irq(&priv->lock); | 2160 | spin_unlock_irq(&priv->lock); |
2125 | 2161 | ||
2126 | isp1760_writel(0, hcd->regs + HC_CONFIGFLAG); | 2162 | isp1760_writel(0, hcd->regs + HC_CONFIGFLAG); |
@@ -2128,10 +2164,11 @@ static void isp1760_stop(struct usb_hcd *hcd) | |||
2128 | 2164 | ||
2129 | static void isp1760_shutdown(struct usb_hcd *hcd) | 2165 | static void isp1760_shutdown(struct usb_hcd *hcd) |
2130 | { | 2166 | { |
2131 | u32 command; | 2167 | u32 command, temp; |
2132 | 2168 | ||
2133 | isp1760_stop(hcd); | 2169 | isp1760_stop(hcd); |
2134 | isp1760_writel(HW_DATA_BUS_32BIT, hcd->regs + HC_HW_MODE_CTRL); | 2170 | temp = isp1760_readl(hcd->regs + HC_HW_MODE_CTRL); |
2171 | isp1760_writel(temp &= ~HW_GLOBAL_INTR_EN, hcd->regs + HC_HW_MODE_CTRL); | ||
2135 | 2172 | ||
2136 | command = isp1760_readl(hcd->regs + HC_USBCMD); | 2173 | command = isp1760_readl(hcd->regs + HC_USBCMD); |
2137 | command &= ~CMD_RUN; | 2174 | command &= ~CMD_RUN; |
@@ -2183,7 +2220,8 @@ void deinit_kmem_cache(void) | |||
2183 | } | 2220 | } |
2184 | 2221 | ||
2185 | struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, | 2222 | struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, |
2186 | u64 irqflags, struct device *dev, const char *busname) | 2223 | u64 irqflags, struct device *dev, const char *busname, |
2224 | unsigned int devflags) | ||
2187 | { | 2225 | { |
2188 | struct usb_hcd *hcd; | 2226 | struct usb_hcd *hcd; |
2189 | struct isp1760_hcd *priv; | 2227 | struct isp1760_hcd *priv; |
@@ -2195,11 +2233,12 @@ struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, | |||
2195 | /* prevent usb-core allocating DMA pages */ | 2233 | /* prevent usb-core allocating DMA pages */ |
2196 | dev->dma_mask = NULL; | 2234 | dev->dma_mask = NULL; |
2197 | 2235 | ||
2198 | hcd = usb_create_hcd(&isp1760_hc_driver, dev, dev->bus_id); | 2236 | hcd = usb_create_hcd(&isp1760_hc_driver, dev, dev_name(dev)); |
2199 | if (!hcd) | 2237 | if (!hcd) |
2200 | return ERR_PTR(-ENOMEM); | 2238 | return ERR_PTR(-ENOMEM); |
2201 | 2239 | ||
2202 | priv = hcd_to_priv(hcd); | 2240 | priv = hcd_to_priv(hcd); |
2241 | priv->devflags = devflags; | ||
2203 | init_memory(priv); | 2242 | init_memory(priv); |
2204 | hcd->regs = ioremap(res_start, res_len); | 2243 | hcd->regs = ioremap(res_start, res_len); |
2205 | if (!hcd->regs) { | 2244 | if (!hcd->regs) { |