diff options
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 13 | ||||
-rw-r--r-- | drivers/usb/host/fhci-tds.c | 6 | ||||
-rw-r--r-- | drivers/usb/host/r8a66597-hcd.c | 58 |
3 files changed, 56 insertions, 21 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index c75d9270c752..19372673bf09 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -196,7 +196,9 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
196 | if (hostpc_reg) { | 196 | if (hostpc_reg) { |
197 | u32 t3; | 197 | u32 t3; |
198 | 198 | ||
199 | spin_unlock_irq(&ehci->lock); | ||
199 | 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); | ||
200 | t3 = ehci_readl(ehci, hostpc_reg); | 202 | t3 = ehci_readl(ehci, hostpc_reg); |
201 | ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg); | 203 | ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg); |
202 | t3 = ehci_readl(ehci, hostpc_reg); | 204 | t3 = ehci_readl(ehci, hostpc_reg); |
@@ -904,17 +906,18 @@ static int ehci_hub_control ( | |||
904 | if ((temp & PORT_PE) == 0 | 906 | if ((temp & PORT_PE) == 0 |
905 | || (temp & PORT_RESET) != 0) | 907 | || (temp & PORT_RESET) != 0) |
906 | goto error; | 908 | goto error; |
907 | ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); | 909 | |
908 | /* After above check the port must be connected. | 910 | /* After above check the port must be connected. |
909 | * Set appropriate bit thus could put phy into low power | 911 | * Set appropriate bit thus could put phy into low power |
910 | * mode if we have hostpc feature | 912 | * mode if we have hostpc feature |
911 | */ | 913 | */ |
914 | temp &= ~PORT_WKCONN_E; | ||
915 | temp |= PORT_WKDISC_E | PORT_WKOC_E; | ||
916 | ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); | ||
912 | if (hostpc_reg) { | 917 | if (hostpc_reg) { |
913 | temp &= ~PORT_WKCONN_E; | 918 | spin_unlock_irqrestore(&ehci->lock, flags); |
914 | temp |= (PORT_WKDISC_E | PORT_WKOC_E); | ||
915 | ehci_writel(ehci, temp | PORT_SUSPEND, | ||
916 | status_reg); | ||
917 | 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); | ||
918 | temp1 = ehci_readl(ehci, hostpc_reg); | 921 | temp1 = ehci_readl(ehci, hostpc_reg); |
919 | ehci_writel(ehci, temp1 | HOSTPC_PHCD, | 922 | ehci_writel(ehci, temp1 | HOSTPC_PHCD, |
920 | hostpc_reg); | 923 | hostpc_reg); |
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/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]); |