diff options
| author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-02-24 14:31:04 -0500 |
|---|---|---|
| committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-02-24 14:33:45 -0500 |
| commit | 109d28152b6e9d5de64cd23e3bc08885ccb3d1ef (patch) | |
| tree | b7b8863faa05254781acfb85cc41da3eef467c6b /drivers/usb/host | |
| parent | 168cf9af699e87d5a6f44b684583714ecabb8e71 (diff) | |
| parent | 60b341b778cc2929df16c0a504c91621b3c6a4ad (diff) | |
Merge tag 'v2.6.33' for its firewire changes since last branch point
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/usb/host')
| -rw-r--r-- | drivers/usb/host/ehci-hcd.c | 5 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-hub.c | 33 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-q.c | 11 | ||||
| -rw-r--r-- | drivers/usb/host/fhci-hcd.c | 3 | ||||
| -rw-r--r-- | drivers/usb/host/fhci-tds.c | 6 | ||||
| -rw-r--r-- | drivers/usb/host/isp1362-hcd.c | 25 | ||||
| -rw-r--r-- | drivers/usb/host/isp1760-hcd.c | 6 | ||||
| -rw-r--r-- | drivers/usb/host/r8a66597-hcd.c | 58 | ||||
| -rw-r--r-- | drivers/usb/host/uhci-hcd.c | 15 | ||||
| -rw-r--r-- | drivers/usb/host/uhci-hub.c | 2 |
10 files changed, 122 insertions, 42 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 5859522d6edd..1ec3857f22e6 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
| @@ -787,9 +787,10 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
| 787 | 787 | ||
| 788 | /* start 20 msec resume signaling from this port, | 788 | /* start 20 msec resume signaling from this port, |
| 789 | * and make khubd collect PORT_STAT_C_SUSPEND to | 789 | * and make khubd collect PORT_STAT_C_SUSPEND to |
| 790 | * stop that signaling. | 790 | * stop that signaling. Use 5 ms extra for safety, |
| 791 | * like usb_port_resume() does. | ||
| 791 | */ | 792 | */ |
| 792 | ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); | 793 | ehci->reset_done[i] = jiffies + msecs_to_jiffies(25); |
| 793 | ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); | 794 | ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); |
| 794 | mod_timer(&hcd->rh_timer, ehci->reset_done[i]); | 795 | mod_timer(&hcd->rh_timer, ehci->reset_done[i]); |
| 795 | } | 796 | } |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 2c6571c05f35..19372673bf09 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
| @@ -120,9 +120,26 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
| 120 | del_timer_sync(&ehci->watchdog); | 120 | del_timer_sync(&ehci->watchdog); |
| 121 | del_timer_sync(&ehci->iaa_watchdog); | 121 | del_timer_sync(&ehci->iaa_watchdog); |
| 122 | 122 | ||
| 123 | port = HCS_N_PORTS (ehci->hcs_params); | ||
| 124 | spin_lock_irq (&ehci->lock); | 123 | spin_lock_irq (&ehci->lock); |
| 125 | 124 | ||
| 125 | /* Once the controller is stopped, port resumes that are already | ||
| 126 | * in progress won't complete. Hence if remote wakeup is enabled | ||
| 127 | * for the root hub and any ports are in the middle of a resume or | ||
| 128 | * remote wakeup, we must fail the suspend. | ||
| 129 | */ | ||
| 130 | if (hcd->self.root_hub->do_remote_wakeup) { | ||
| 131 | port = HCS_N_PORTS(ehci->hcs_params); | ||
| 132 | while (port--) { | ||
| 133 | if (ehci->reset_done[port] != 0) { | ||
| 134 | spin_unlock_irq(&ehci->lock); | ||
| 135 | ehci_dbg(ehci, "suspend failed because " | ||
| 136 | "port %d is resuming\n", | ||
| 137 | port + 1); | ||
| 138 | return -EBUSY; | ||
| 139 | } | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 126 | /* stop schedules, clean any completed work */ | 143 | /* stop schedules, clean any completed work */ |
| 127 | if (HC_IS_RUNNING(hcd->state)) { | 144 | if (HC_IS_RUNNING(hcd->state)) { |
| 128 | ehci_quiesce (ehci); | 145 | ehci_quiesce (ehci); |
| @@ -138,6 +155,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
| 138 | */ | 155 | */ |
| 139 | ehci->bus_suspended = 0; | 156 | ehci->bus_suspended = 0; |
| 140 | ehci->owned_ports = 0; | 157 | ehci->owned_ports = 0; |
| 158 | port = HCS_N_PORTS(ehci->hcs_params); | ||
| 141 | while (port--) { | 159 | while (port--) { |
| 142 | u32 __iomem *reg = &ehci->regs->port_status [port]; | 160 | u32 __iomem *reg = &ehci->regs->port_status [port]; |
| 143 | u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; | 161 | u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; |
| @@ -178,7 +196,9 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
| 178 | if (hostpc_reg) { | 196 | if (hostpc_reg) { |
| 179 | u32 t3; | 197 | u32 t3; |
| 180 | 198 | ||
| 199 | spin_unlock_irq(&ehci->lock); | ||
| 181 | msleep(5);/* 5ms for HCD enter low pwr mode */ | 200 | msleep(5);/* 5ms for HCD enter low pwr mode */ |
| 201 | spin_lock_irq(&ehci->lock); | ||
| 182 | t3 = ehci_readl(ehci, hostpc_reg); | 202 | t3 = ehci_readl(ehci, hostpc_reg); |
| 183 | ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg); | 203 | ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg); |
| 184 | t3 = ehci_readl(ehci, hostpc_reg); | 204 | t3 = ehci_readl(ehci, hostpc_reg); |
| @@ -886,17 +906,18 @@ static int ehci_hub_control ( | |||
| 886 | if ((temp & PORT_PE) == 0 | 906 | if ((temp & PORT_PE) == 0 |
| 887 | || (temp & PORT_RESET) != 0) | 907 | || (temp & PORT_RESET) != 0) |
| 888 | goto error; | 908 | goto error; |
| 889 | ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); | 909 | |
| 890 | /* After above check the port must be connected. | 910 | /* After above check the port must be connected. |
| 891 | * Set appropriate bit thus could put phy into low power | 911 | * Set appropriate bit thus could put phy into low power |
| 892 | * mode if we have hostpc feature | 912 | * mode if we have hostpc feature |
| 893 | */ | 913 | */ |
| 914 | temp &= ~PORT_WKCONN_E; | ||
| 915 | temp |= PORT_WKDISC_E | PORT_WKOC_E; | ||
| 916 | ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); | ||
| 894 | if (hostpc_reg) { | 917 | if (hostpc_reg) { |
| 895 | temp &= ~PORT_WKCONN_E; | 918 | spin_unlock_irqrestore(&ehci->lock, flags); |
| 896 | temp |= (PORT_WKDISC_E | PORT_WKOC_E); | ||
| 897 | ehci_writel(ehci, temp | PORT_SUSPEND, | ||
| 898 | status_reg); | ||
| 899 | msleep(5);/* 5ms for HCD enter low pwr mode */ | 919 | msleep(5);/* 5ms for HCD enter low pwr mode */ |
| 920 | spin_lock_irqsave(&ehci->lock, flags); | ||
| 900 | temp1 = ehci_readl(ehci, hostpc_reg); | 921 | temp1 = ehci_readl(ehci, hostpc_reg); |
| 901 | ehci_writel(ehci, temp1 | HOSTPC_PHCD, | 922 | ehci_writel(ehci, temp1 | HOSTPC_PHCD, |
| 902 | hostpc_reg); | 923 | hostpc_reg); |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index a427d3b00634..89521775c567 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
| @@ -849,9 +849,10 @@ qh_make ( | |||
| 849 | * But interval 1 scheduling is simpler, and | 849 | * But interval 1 scheduling is simpler, and |
| 850 | * includes high bandwidth. | 850 | * includes high bandwidth. |
| 851 | */ | 851 | */ |
| 852 | dbg ("intr period %d uframes, NYET!", | 852 | urb->interval = 1; |
| 853 | urb->interval); | 853 | } else if (qh->period > ehci->periodic_size) { |
| 854 | goto done; | 854 | qh->period = ehci->periodic_size; |
| 855 | urb->interval = qh->period << 3; | ||
| 855 | } | 856 | } |
| 856 | } else { | 857 | } else { |
| 857 | int think_time; | 858 | int think_time; |
| @@ -874,6 +875,10 @@ qh_make ( | |||
| 874 | usb_calc_bus_time (urb->dev->speed, | 875 | usb_calc_bus_time (urb->dev->speed, |
| 875 | is_input, 0, max_packet (maxp))); | 876 | is_input, 0, max_packet (maxp))); |
| 876 | qh->period = urb->interval; | 877 | qh->period = urb->interval; |
| 878 | if (qh->period > ehci->periodic_size) { | ||
| 879 | qh->period = ehci->periodic_size; | ||
| 880 | urb->interval = qh->period; | ||
| 881 | } | ||
| 877 | } | 882 | } |
| 878 | } | 883 | } |
| 879 | 884 | ||
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 0951818ef93b..78e7c3cfcb72 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c | |||
| @@ -242,9 +242,10 @@ err: | |||
| 242 | static void fhci_usb_free(void *lld) | 242 | static void fhci_usb_free(void *lld) |
| 243 | { | 243 | { |
| 244 | struct fhci_usb *usb = lld; | 244 | struct fhci_usb *usb = lld; |
| 245 | struct fhci_hcd *fhci = usb->fhci; | 245 | struct fhci_hcd *fhci; |
| 246 | 246 | ||
| 247 | if (usb) { | 247 | if (usb) { |
| 248 | fhci = usb->fhci; | ||
| 248 | fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF); | 249 | fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF); |
| 249 | fhci_ep0_free(usb); | 250 | fhci_ep0_free(usb); |
| 250 | kfree(usb->actual_frame); | 251 | kfree(usb->actual_frame); |
diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c index d224ab467a40..e1232890c78b 100644 --- a/drivers/usb/host/fhci-tds.c +++ b/drivers/usb/host/fhci-tds.c | |||
| @@ -105,7 +105,7 @@ void fhci_ep0_free(struct fhci_usb *usb) | |||
| 105 | if (ep->td_base) | 105 | if (ep->td_base) |
| 106 | cpm_muram_free(cpm_muram_offset(ep->td_base)); | 106 | cpm_muram_free(cpm_muram_offset(ep->td_base)); |
| 107 | 107 | ||
| 108 | if (ep->conf_frame_Q) { | 108 | if (kfifo_initialized(&ep->conf_frame_Q)) { |
| 109 | size = cq_howmany(&ep->conf_frame_Q); | 109 | size = cq_howmany(&ep->conf_frame_Q); |
| 110 | for (; size; size--) { | 110 | for (; size; size--) { |
| 111 | struct packet *pkt = cq_get(&ep->conf_frame_Q); | 111 | struct packet *pkt = cq_get(&ep->conf_frame_Q); |
| @@ -115,7 +115,7 @@ void fhci_ep0_free(struct fhci_usb *usb) | |||
| 115 | cq_delete(&ep->conf_frame_Q); | 115 | cq_delete(&ep->conf_frame_Q); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | if (ep->empty_frame_Q) { | 118 | if (kfifo_initialized(&ep->empty_frame_Q)) { |
| 119 | size = cq_howmany(&ep->empty_frame_Q); | 119 | size = cq_howmany(&ep->empty_frame_Q); |
| 120 | for (; size; size--) { | 120 | for (; size; size--) { |
| 121 | struct packet *pkt = cq_get(&ep->empty_frame_Q); | 121 | struct packet *pkt = cq_get(&ep->empty_frame_Q); |
| @@ -125,7 +125,7 @@ void fhci_ep0_free(struct fhci_usb *usb) | |||
| 125 | cq_delete(&ep->empty_frame_Q); | 125 | cq_delete(&ep->empty_frame_Q); |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | if (ep->dummy_packets_Q) { | 128 | if (kfifo_initialized(&ep->dummy_packets_Q)) { |
| 129 | size = cq_howmany(&ep->dummy_packets_Q); | 129 | size = cq_howmany(&ep->dummy_packets_Q); |
| 130 | for (; size; size--) { | 130 | for (; size; size--) { |
| 131 | u8 *buff = cq_get(&ep->dummy_packets_Q); | 131 | u8 *buff = cq_get(&ep->dummy_packets_Q); |
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 73352f3739b5..42971657fde2 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c | |||
| @@ -2270,10 +2270,10 @@ static int isp1362_mem_config(struct usb_hcd *hcd) | |||
| 2270 | dev_info(hcd->self.controller, "ISP1362 Memory usage:\n"); | 2270 | dev_info(hcd->self.controller, "ISP1362 Memory usage:\n"); |
| 2271 | dev_info(hcd->self.controller, " ISTL: 2 * %4d: %4d @ $%04x:$%04x\n", | 2271 | dev_info(hcd->self.controller, " ISTL: 2 * %4d: %4d @ $%04x:$%04x\n", |
| 2272 | istl_size / 2, istl_size, 0, istl_size / 2); | 2272 | istl_size / 2, istl_size, 0, istl_size / 2); |
| 2273 | dev_info(hcd->self.controller, " INTL: %4d * (%3lu+8): %4d @ $%04x\n", | 2273 | dev_info(hcd->self.controller, " INTL: %4d * (%3zu+8): %4d @ $%04x\n", |
| 2274 | ISP1362_INTL_BUFFERS, intl_blksize - PTD_HEADER_SIZE, | 2274 | ISP1362_INTL_BUFFERS, intl_blksize - PTD_HEADER_SIZE, |
| 2275 | intl_size, istl_size); | 2275 | intl_size, istl_size); |
| 2276 | dev_info(hcd->self.controller, " ATL : %4d * (%3lu+8): %4d @ $%04x\n", | 2276 | dev_info(hcd->self.controller, " ATL : %4d * (%3zu+8): %4d @ $%04x\n", |
| 2277 | atl_buffers, atl_blksize - PTD_HEADER_SIZE, | 2277 | atl_buffers, atl_blksize - PTD_HEADER_SIZE, |
| 2278 | atl_size, istl_size + intl_size); | 2278 | atl_size, istl_size + intl_size); |
| 2279 | dev_info(hcd->self.controller, " USED/FREE: %4d %4d\n", total, | 2279 | dev_info(hcd->self.controller, " USED/FREE: %4d %4d\n", total, |
| @@ -2697,6 +2697,8 @@ static int __init isp1362_probe(struct platform_device *pdev) | |||
| 2697 | void __iomem *data_reg; | 2697 | void __iomem *data_reg; |
| 2698 | int irq; | 2698 | int irq; |
| 2699 | int retval = 0; | 2699 | int retval = 0; |
| 2700 | struct resource *irq_res; | ||
| 2701 | unsigned int irq_flags = 0; | ||
| 2700 | 2702 | ||
| 2701 | /* basic sanity checks first. board-specific init logic should | 2703 | /* basic sanity checks first. board-specific init logic should |
| 2702 | * have initialized this the three resources and probably board | 2704 | * have initialized this the three resources and probably board |
| @@ -2710,11 +2712,12 @@ static int __init isp1362_probe(struct platform_device *pdev) | |||
| 2710 | 2712 | ||
| 2711 | data = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2713 | data = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 2712 | addr = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 2714 | addr = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
| 2713 | irq = platform_get_irq(pdev, 0); | 2715 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
| 2714 | if (!addr || !data || irq < 0) { | 2716 | if (!addr || !data || !irq_res) { |
| 2715 | retval = -ENODEV; | 2717 | retval = -ENODEV; |
| 2716 | goto err1; | 2718 | goto err1; |
| 2717 | } | 2719 | } |
| 2720 | irq = irq_res->start; | ||
| 2718 | 2721 | ||
| 2719 | #ifdef CONFIG_USB_HCD_DMA | 2722 | #ifdef CONFIG_USB_HCD_DMA |
| 2720 | if (pdev->dev.dma_mask) { | 2723 | if (pdev->dev.dma_mask) { |
| @@ -2781,12 +2784,16 @@ static int __init isp1362_probe(struct platform_device *pdev) | |||
| 2781 | } | 2784 | } |
| 2782 | #endif | 2785 | #endif |
| 2783 | 2786 | ||
| 2784 | #ifdef CONFIG_ARM | 2787 | if (irq_res->flags & IORESOURCE_IRQ_HIGHEDGE) |
| 2785 | if (isp1362_hcd->board) | 2788 | irq_flags |= IRQF_TRIGGER_RISING; |
| 2786 | set_irq_type(irq, isp1362_hcd->board->int_act_high ? IRQT_RISING : IRQT_FALLING); | 2789 | if (irq_res->flags & IORESOURCE_IRQ_LOWEDGE) |
| 2787 | #endif | 2790 | irq_flags |= IRQF_TRIGGER_FALLING; |
| 2791 | if (irq_res->flags & IORESOURCE_IRQ_HIGHLEVEL) | ||
| 2792 | irq_flags |= IRQF_TRIGGER_HIGH; | ||
| 2793 | if (irq_res->flags & IORESOURCE_IRQ_LOWLEVEL) | ||
| 2794 | irq_flags |= IRQF_TRIGGER_LOW; | ||
| 2788 | 2795 | ||
| 2789 | retval = usb_add_hcd(hcd, irq, IRQF_TRIGGER_LOW | IRQF_DISABLED | IRQF_SHARED); | 2796 | retval = usb_add_hcd(hcd, irq, irq_flags | IRQF_DISABLED | IRQF_SHARED); |
| 2790 | if (retval != 0) | 2797 | if (retval != 0) |
| 2791 | goto err6; | 2798 | goto err6; |
| 2792 | pr_info("%s, irq %d\n", hcd->product_desc, irq); | 2799 | pr_info("%s, irq %d\n", hcd->product_desc, irq); |
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 9600a58299db..27b8f7cb4471 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c | |||
| @@ -1039,12 +1039,12 @@ static void do_atl_int(struct usb_hcd *usb_hcd) | |||
| 1039 | if (!nakcount && (dw3 & DW3_QTD_ACTIVE)) { | 1039 | if (!nakcount && (dw3 & DW3_QTD_ACTIVE)) { |
| 1040 | u32 buffstatus; | 1040 | u32 buffstatus; |
| 1041 | 1041 | ||
| 1042 | /* XXX | 1042 | /* |
| 1043 | * NAKs are handled in HW by the chip. Usually if the | 1043 | * NAKs are handled in HW by the chip. Usually if the |
| 1044 | * device is not able to send data fast enough. | 1044 | * device is not able to send data fast enough. |
| 1045 | * This did not trigger for a long time now. | 1045 | * This happens mostly on slower hardware. |
| 1046 | */ | 1046 | */ |
| 1047 | printk(KERN_ERR "Reloading ptd %p/%p... qh %p readed: " | 1047 | printk(KERN_NOTICE "Reloading ptd %p/%p... qh %p read: " |
| 1048 | "%d of %zu done: %08x cur: %08x\n", qtd, | 1048 | "%d of %zu done: %08x cur: %08x\n", qtd, |
| 1049 | urb, qh, PTD_XFERRED_LENGTH(dw3), | 1049 | urb, qh, PTD_XFERRED_LENGTH(dw3), |
| 1050 | qtd->length, done_map, | 1050 | qtd->length, done_map, |
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index b7a661c02bcd..bee558aed427 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
| @@ -35,7 +35,9 @@ | |||
| 35 | #include <linux/usb.h> | 35 | #include <linux/usb.h> |
| 36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
| 37 | #include <linux/io.h> | 37 | #include <linux/io.h> |
| 38 | #include <linux/mm.h> | ||
| 38 | #include <linux/irq.h> | 39 | #include <linux/irq.h> |
| 40 | #include <asm/cacheflush.h> | ||
| 39 | 41 | ||
| 40 | #include "../core/hcd.h" | 42 | #include "../core/hcd.h" |
| 41 | #include "r8a66597.h" | 43 | #include "r8a66597.h" |
| @@ -216,8 +218,17 @@ static void disable_controller(struct r8a66597 *r8a66597) | |||
| 216 | { | 218 | { |
| 217 | int port; | 219 | int port; |
| 218 | 220 | ||
| 221 | /* disable interrupts */ | ||
| 219 | r8a66597_write(r8a66597, 0, INTENB0); | 222 | r8a66597_write(r8a66597, 0, INTENB0); |
| 220 | r8a66597_write(r8a66597, 0, INTSTS0); | 223 | r8a66597_write(r8a66597, 0, INTENB1); |
| 224 | r8a66597_write(r8a66597, 0, BRDYENB); | ||
| 225 | r8a66597_write(r8a66597, 0, BEMPENB); | ||
| 226 | r8a66597_write(r8a66597, 0, NRDYENB); | ||
| 227 | |||
| 228 | /* clear status */ | ||
| 229 | r8a66597_write(r8a66597, 0, BRDYSTS); | ||
| 230 | r8a66597_write(r8a66597, 0, NRDYSTS); | ||
| 231 | r8a66597_write(r8a66597, 0, BEMPSTS); | ||
| 221 | 232 | ||
| 222 | for (port = 0; port < r8a66597->max_root_hub; port++) | 233 | for (port = 0; port < r8a66597->max_root_hub; port++) |
| 223 | r8a66597_disable_port(r8a66597, port); | 234 | r8a66597_disable_port(r8a66597, port); |
| @@ -811,6 +822,26 @@ static void enable_r8a66597_pipe(struct r8a66597 *r8a66597, struct urb *urb, | |||
| 811 | enable_r8a66597_pipe_dma(r8a66597, dev, pipe, urb); | 822 | enable_r8a66597_pipe_dma(r8a66597, dev, pipe, urb); |
| 812 | } | 823 | } |
| 813 | 824 | ||
| 825 | static void r8a66597_urb_done(struct r8a66597 *r8a66597, struct urb *urb, | ||
| 826 | int status) | ||
| 827 | __releases(r8a66597->lock) | ||
| 828 | __acquires(r8a66597->lock) | ||
| 829 | { | ||
| 830 | if (usb_pipein(urb->pipe) && usb_pipetype(urb->pipe) != PIPE_CONTROL) { | ||
| 831 | void *ptr; | ||
| 832 | |||
| 833 | for (ptr = urb->transfer_buffer; | ||
| 834 | ptr < urb->transfer_buffer + urb->transfer_buffer_length; | ||
| 835 | ptr += PAGE_SIZE) | ||
| 836 | flush_dcache_page(virt_to_page(ptr)); | ||
| 837 | } | ||
| 838 | |||
| 839 | usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), urb); | ||
| 840 | spin_unlock(&r8a66597->lock); | ||
| 841 | usb_hcd_giveback_urb(r8a66597_to_hcd(r8a66597), urb, status); | ||
| 842 | spin_lock(&r8a66597->lock); | ||
| 843 | } | ||
| 844 | |||
| 814 | /* this function must be called with interrupt disabled */ | 845 | /* this function must be called with interrupt disabled */ |
| 815 | static void force_dequeue(struct r8a66597 *r8a66597, u16 pipenum, u16 address) | 846 | static void force_dequeue(struct r8a66597 *r8a66597, u16 pipenum, u16 address) |
| 816 | { | 847 | { |
| @@ -829,15 +860,9 @@ static void force_dequeue(struct r8a66597 *r8a66597, u16 pipenum, u16 address) | |||
| 829 | list_del(&td->queue); | 860 | list_del(&td->queue); |
| 830 | kfree(td); | 861 | kfree(td); |
| 831 | 862 | ||
| 832 | if (urb) { | 863 | if (urb) |
| 833 | usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), | 864 | r8a66597_urb_done(r8a66597, urb, -ENODEV); |
| 834 | urb); | ||
| 835 | 865 | ||
| 836 | spin_unlock(&r8a66597->lock); | ||
| 837 | usb_hcd_giveback_urb(r8a66597_to_hcd(r8a66597), urb, | ||
| 838 | -ENODEV); | ||
| 839 | spin_lock(&r8a66597->lock); | ||
| 840 | } | ||
| 841 | break; | 866 | break; |
| 842 | } | 867 | } |
| 843 | } | 868 | } |
| @@ -997,6 +1022,8 @@ static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port, | |||
| 997 | /* this function must be called with interrupt disabled */ | 1022 | /* this function must be called with interrupt disabled */ |
| 998 | static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port, | 1023 | static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port, |
| 999 | u16 syssts) | 1024 | u16 syssts) |
| 1025 | __releases(r8a66597->lock) | ||
| 1026 | __acquires(r8a66597->lock) | ||
| 1000 | { | 1027 | { |
| 1001 | if (syssts == SE0) { | 1028 | if (syssts == SE0) { |
| 1002 | r8a66597_write(r8a66597, ~ATTCH, get_intsts_reg(port)); | 1029 | r8a66597_write(r8a66597, ~ATTCH, get_intsts_reg(port)); |
| @@ -1014,7 +1041,9 @@ static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port, | |||
| 1014 | usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597)); | 1041 | usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597)); |
| 1015 | } | 1042 | } |
| 1016 | 1043 | ||
| 1044 | spin_unlock(&r8a66597->lock); | ||
| 1017 | usb_hcd_poll_rh_status(r8a66597_to_hcd(r8a66597)); | 1045 | usb_hcd_poll_rh_status(r8a66597_to_hcd(r8a66597)); |
| 1046 | spin_lock(&r8a66597->lock); | ||
| 1018 | } | 1047 | } |
| 1019 | 1048 | ||
| 1020 | /* this function must be called with interrupt disabled */ | 1049 | /* this function must be called with interrupt disabled */ |
| @@ -1274,10 +1303,7 @@ __releases(r8a66597->lock) __acquires(r8a66597->lock) | |||
| 1274 | if (usb_pipeisoc(urb->pipe)) | 1303 | if (usb_pipeisoc(urb->pipe)) |
| 1275 | urb->start_frame = r8a66597_get_frame(hcd); | 1304 | urb->start_frame = r8a66597_get_frame(hcd); |
| 1276 | 1305 | ||
| 1277 | usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), urb); | 1306 | r8a66597_urb_done(r8a66597, urb, status); |
| 1278 | spin_unlock(&r8a66597->lock); | ||
| 1279 | usb_hcd_giveback_urb(hcd, urb, status); | ||
| 1280 | spin_lock(&r8a66597->lock); | ||
| 1281 | } | 1307 | } |
| 1282 | 1308 | ||
| 1283 | if (restart) { | 1309 | if (restart) { |
| @@ -2466,6 +2492,12 @@ static int __devinit r8a66597_probe(struct platform_device *pdev) | |||
| 2466 | r8a66597->rh_timer.data = (unsigned long)r8a66597; | 2492 | r8a66597->rh_timer.data = (unsigned long)r8a66597; |
| 2467 | r8a66597->reg = (unsigned long)reg; | 2493 | r8a66597->reg = (unsigned long)reg; |
| 2468 | 2494 | ||
| 2495 | /* make sure no interrupts are pending */ | ||
| 2496 | ret = r8a66597_clock_enable(r8a66597); | ||
| 2497 | if (ret < 0) | ||
| 2498 | goto clean_up3; | ||
| 2499 | disable_controller(r8a66597); | ||
| 2500 | |||
| 2469 | for (i = 0; i < R8A66597_MAX_NUM_PIPE; i++) { | 2501 | for (i = 0; i < R8A66597_MAX_NUM_PIPE; i++) { |
| 2470 | INIT_LIST_HEAD(&r8a66597->pipe_queue[i]); | 2502 | INIT_LIST_HEAD(&r8a66597->pipe_queue[i]); |
| 2471 | init_timer(&r8a66597->td_timer[i]); | 2503 | init_timer(&r8a66597->td_timer[i]); |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 5cd0e48f67fb..99cd00fd3514 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
| @@ -749,7 +749,20 @@ static int uhci_rh_suspend(struct usb_hcd *hcd) | |||
| 749 | spin_lock_irq(&uhci->lock); | 749 | spin_lock_irq(&uhci->lock); |
| 750 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) | 750 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) |
| 751 | rc = -ESHUTDOWN; | 751 | rc = -ESHUTDOWN; |
| 752 | else if (!uhci->dead) | 752 | else if (uhci->dead) |
| 753 | ; /* Dead controllers tell no tales */ | ||
| 754 | |||
| 755 | /* Once the controller is stopped, port resumes that are already | ||
| 756 | * in progress won't complete. Hence if remote wakeup is enabled | ||
| 757 | * for the root hub and any ports are in the middle of a resume or | ||
| 758 | * remote wakeup, we must fail the suspend. | ||
| 759 | */ | ||
| 760 | else if (hcd->self.root_hub->do_remote_wakeup && | ||
| 761 | uhci->resuming_ports) { | ||
| 762 | dev_dbg(uhci_dev(uhci), "suspend failed because a port " | ||
| 763 | "is resuming\n"); | ||
| 764 | rc = -EBUSY; | ||
| 765 | } else | ||
| 753 | suspend_rh(uhci, UHCI_RH_SUSPENDED); | 766 | suspend_rh(uhci, UHCI_RH_SUSPENDED); |
| 754 | spin_unlock_irq(&uhci->lock); | 767 | spin_unlock_irq(&uhci->lock); |
| 755 | return rc; | 768 | return rc; |
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 885b585360b9..8270055848ca 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c | |||
| @@ -167,7 +167,7 @@ static void uhci_check_ports(struct uhci_hcd *uhci) | |||
| 167 | /* Port received a wakeup request */ | 167 | /* Port received a wakeup request */ |
| 168 | set_bit(port, &uhci->resuming_ports); | 168 | set_bit(port, &uhci->resuming_ports); |
| 169 | uhci->ports_timeout = jiffies + | 169 | uhci->ports_timeout = jiffies + |
| 170 | msecs_to_jiffies(20); | 170 | msecs_to_jiffies(25); |
| 171 | 171 | ||
| 172 | /* Make sure we see the port again | 172 | /* Make sure we see the port again |
| 173 | * after the resuming period is over. */ | 173 | * after the resuming period is over. */ |
