diff options
author | Dave Jones <davej@redhat.com> | 2007-02-10 20:36:29 -0500 |
---|---|---|
committer | Dave Jones <davej@redhat.com> | 2007-02-10 20:36:29 -0500 |
commit | bd0561c9d8dcbf21cd9aa46c416bbf6a3a12e4b1 (patch) | |
tree | 64fe15d4db42e0840acea00e4cf7e1855bba9e96 /drivers/usb/host | |
parent | 348f31ed2bd18391fe5903aa0ad7bfcda6d8ca0b (diff) | |
parent | 66efc5a7e3061c3597ac43a8bb1026488d57e66b (diff) |
[CPUFREQ] Fix up merge conflicts with recent ACPI changes.
Signed-off-by: Dave Jones <davej@redhat.com>
Diffstat (limited to 'drivers/usb/host')
30 files changed, 1718 insertions, 612 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index cc60759083bf..62711870f8ee 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -67,6 +67,11 @@ config USB_EHCI_TT_NEWSCHED | |||
67 | 67 | ||
68 | If unsure, say N. | 68 | If unsure, say N. |
69 | 69 | ||
70 | config USB_EHCI_BIG_ENDIAN_MMIO | ||
71 | bool | ||
72 | depends on USB_EHCI_HCD | ||
73 | default n | ||
74 | |||
70 | config USB_ISP116X_HCD | 75 | config USB_ISP116X_HCD |
71 | tristate "ISP116X HCD support" | 76 | tristate "ISP116X HCD support" |
72 | depends on USB | 77 | depends on USB |
@@ -101,21 +106,48 @@ config USB_OHCI_HCD_PPC_SOC | |||
101 | bool "OHCI support for on-chip PPC USB controller" | 106 | bool "OHCI support for on-chip PPC USB controller" |
102 | depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) | 107 | depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) |
103 | default y | 108 | default y |
104 | select USB_OHCI_BIG_ENDIAN | 109 | select USB_OHCI_BIG_ENDIAN_DESC |
110 | select USB_OHCI_BIG_ENDIAN_MMIO | ||
105 | ---help--- | 111 | ---help--- |
106 | Enables support for the USB controller on the MPC52xx or | 112 | Enables support for the USB controller on the MPC52xx or |
107 | STB03xxx processor chip. If unsure, say Y. | 113 | STB03xxx processor chip. If unsure, say Y. |
108 | 114 | ||
115 | config USB_OHCI_HCD_PPC_OF | ||
116 | bool "OHCI support for PPC USB controller on OF platform bus" | ||
117 | depends on USB_OHCI_HCD && PPC_OF | ||
118 | default y | ||
119 | ---help--- | ||
120 | Enables support for the USB controller PowerPC present on the | ||
121 | OpenFirmware platform bus. | ||
122 | |||
123 | config USB_OHCI_HCD_PPC_OF_BE | ||
124 | bool "Support big endian HC" | ||
125 | depends on USB_OHCI_HCD_PPC_OF | ||
126 | default y | ||
127 | select USB_OHCI_BIG_ENDIAN_DESC | ||
128 | select USB_OHCI_BIG_ENDIAN_MMIO | ||
129 | |||
130 | config USB_OHCI_HCD_PPC_OF_LE | ||
131 | bool "Support little endian HC" | ||
132 | depends on USB_OHCI_HCD_PPC_OF | ||
133 | default n | ||
134 | select USB_OHCI_LITTLE_ENDIAN | ||
135 | |||
109 | config USB_OHCI_HCD_PCI | 136 | config USB_OHCI_HCD_PCI |
110 | bool "OHCI support for PCI-bus USB controllers" | 137 | bool "OHCI support for PCI-bus USB controllers" |
111 | depends on USB_OHCI_HCD && PCI && (STB03xxx || PPC_MPC52xx) | 138 | depends on USB_OHCI_HCD && PCI && (STB03xxx || PPC_MPC52xx || USB_OHCI_HCD_PPC_OF) |
112 | default y | 139 | default y |
113 | select USB_OHCI_LITTLE_ENDIAN | 140 | select USB_OHCI_LITTLE_ENDIAN |
114 | ---help--- | 141 | ---help--- |
115 | Enables support for PCI-bus plug-in USB controller cards. | 142 | Enables support for PCI-bus plug-in USB controller cards. |
116 | If unsure, say Y. | 143 | If unsure, say Y. |
117 | 144 | ||
118 | config USB_OHCI_BIG_ENDIAN | 145 | config USB_OHCI_BIG_ENDIAN_DESC |
146 | bool | ||
147 | depends on USB_OHCI_HCD | ||
148 | default n | ||
149 | |||
150 | config USB_OHCI_BIG_ENDIAN_MMIO | ||
119 | bool | 151 | bool |
120 | depends on USB_OHCI_HCD | 152 | depends on USB_OHCI_HCD |
121 | default n | 153 | default n |
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 56349d21e6ea..246afea9e83b 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c | |||
@@ -43,7 +43,7 @@ | |||
43 | */ | 43 | */ |
44 | static void dbg_hcs_params (struct ehci_hcd *ehci, char *label) | 44 | static void dbg_hcs_params (struct ehci_hcd *ehci, char *label) |
45 | { | 45 | { |
46 | u32 params = readl (&ehci->caps->hcs_params); | 46 | u32 params = ehci_readl(ehci, &ehci->caps->hcs_params); |
47 | 47 | ||
48 | ehci_dbg (ehci, | 48 | ehci_dbg (ehci, |
49 | "%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d\n", | 49 | "%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d\n", |
@@ -87,7 +87,7 @@ static inline void dbg_hcs_params (struct ehci_hcd *ehci, char *label) {} | |||
87 | * */ | 87 | * */ |
88 | static void dbg_hcc_params (struct ehci_hcd *ehci, char *label) | 88 | static void dbg_hcc_params (struct ehci_hcd *ehci, char *label) |
89 | { | 89 | { |
90 | u32 params = readl (&ehci->caps->hcc_params); | 90 | u32 params = ehci_readl(ehci, &ehci->caps->hcc_params); |
91 | 91 | ||
92 | if (HCC_ISOC_CACHE (params)) { | 92 | if (HCC_ISOC_CACHE (params)) { |
93 | ehci_dbg (ehci, | 93 | ehci_dbg (ehci, |
@@ -653,7 +653,7 @@ show_registers (struct class_device *class_dev, char *buf) | |||
653 | } | 653 | } |
654 | 654 | ||
655 | /* Capability Registers */ | 655 | /* Capability Registers */ |
656 | i = HC_VERSION(readl (&ehci->caps->hc_capbase)); | 656 | i = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); |
657 | temp = scnprintf (next, size, | 657 | temp = scnprintf (next, size, |
658 | "bus %s, device %s (driver " DRIVER_VERSION ")\n" | 658 | "bus %s, device %s (driver " DRIVER_VERSION ")\n" |
659 | "%s\n" | 659 | "%s\n" |
@@ -673,7 +673,7 @@ show_registers (struct class_device *class_dev, char *buf) | |||
673 | unsigned count = 256/4; | 673 | unsigned count = 256/4; |
674 | 674 | ||
675 | pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); | 675 | pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); |
676 | offset = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params)); | 676 | offset = HCC_EXT_CAPS (ehci_readl(ehci, &ehci->caps->hcc_params)); |
677 | while (offset && count--) { | 677 | while (offset && count--) { |
678 | pci_read_config_dword (pdev, offset, &cap); | 678 | pci_read_config_dword (pdev, offset, &cap); |
679 | switch (cap & 0xff) { | 679 | switch (cap & 0xff) { |
@@ -704,50 +704,50 @@ show_registers (struct class_device *class_dev, char *buf) | |||
704 | #endif | 704 | #endif |
705 | 705 | ||
706 | // FIXME interpret both types of params | 706 | // FIXME interpret both types of params |
707 | i = readl (&ehci->caps->hcs_params); | 707 | i = ehci_readl(ehci, &ehci->caps->hcs_params); |
708 | temp = scnprintf (next, size, "structural params 0x%08x\n", i); | 708 | temp = scnprintf (next, size, "structural params 0x%08x\n", i); |
709 | size -= temp; | 709 | size -= temp; |
710 | next += temp; | 710 | next += temp; |
711 | 711 | ||
712 | i = readl (&ehci->caps->hcc_params); | 712 | i = ehci_readl(ehci, &ehci->caps->hcc_params); |
713 | temp = scnprintf (next, size, "capability params 0x%08x\n", i); | 713 | temp = scnprintf (next, size, "capability params 0x%08x\n", i); |
714 | size -= temp; | 714 | size -= temp; |
715 | next += temp; | 715 | next += temp; |
716 | 716 | ||
717 | /* Operational Registers */ | 717 | /* Operational Registers */ |
718 | temp = dbg_status_buf (scratch, sizeof scratch, label, | 718 | temp = dbg_status_buf (scratch, sizeof scratch, label, |
719 | readl (&ehci->regs->status)); | 719 | ehci_readl(ehci, &ehci->regs->status)); |
720 | temp = scnprintf (next, size, fmt, temp, scratch); | 720 | temp = scnprintf (next, size, fmt, temp, scratch); |
721 | size -= temp; | 721 | size -= temp; |
722 | next += temp; | 722 | next += temp; |
723 | 723 | ||
724 | temp = dbg_command_buf (scratch, sizeof scratch, label, | 724 | temp = dbg_command_buf (scratch, sizeof scratch, label, |
725 | readl (&ehci->regs->command)); | 725 | ehci_readl(ehci, &ehci->regs->command)); |
726 | temp = scnprintf (next, size, fmt, temp, scratch); | 726 | temp = scnprintf (next, size, fmt, temp, scratch); |
727 | size -= temp; | 727 | size -= temp; |
728 | next += temp; | 728 | next += temp; |
729 | 729 | ||
730 | temp = dbg_intr_buf (scratch, sizeof scratch, label, | 730 | temp = dbg_intr_buf (scratch, sizeof scratch, label, |
731 | readl (&ehci->regs->intr_enable)); | 731 | ehci_readl(ehci, &ehci->regs->intr_enable)); |
732 | temp = scnprintf (next, size, fmt, temp, scratch); | 732 | temp = scnprintf (next, size, fmt, temp, scratch); |
733 | size -= temp; | 733 | size -= temp; |
734 | next += temp; | 734 | next += temp; |
735 | 735 | ||
736 | temp = scnprintf (next, size, "uframe %04x\n", | 736 | temp = scnprintf (next, size, "uframe %04x\n", |
737 | readl (&ehci->regs->frame_index)); | 737 | ehci_readl(ehci, &ehci->regs->frame_index)); |
738 | size -= temp; | 738 | size -= temp; |
739 | next += temp; | 739 | next += temp; |
740 | 740 | ||
741 | for (i = 1; i <= HCS_N_PORTS (ehci->hcs_params); i++) { | 741 | for (i = 1; i <= HCS_N_PORTS (ehci->hcs_params); i++) { |
742 | temp = dbg_port_buf (scratch, sizeof scratch, label, i, | 742 | temp = dbg_port_buf (scratch, sizeof scratch, label, i, |
743 | readl (&ehci->regs->port_status [i - 1])); | 743 | ehci_readl(ehci, &ehci->regs->port_status [i - 1])); |
744 | temp = scnprintf (next, size, fmt, temp, scratch); | 744 | temp = scnprintf (next, size, fmt, temp, scratch); |
745 | size -= temp; | 745 | size -= temp; |
746 | next += temp; | 746 | next += temp; |
747 | if (i == HCS_DEBUG_PORT(ehci->hcs_params) && ehci->debug) { | 747 | if (i == HCS_DEBUG_PORT(ehci->hcs_params) && ehci->debug) { |
748 | temp = scnprintf (next, size, | 748 | temp = scnprintf (next, size, |
749 | " debug control %08x\n", | 749 | " debug control %08x\n", |
750 | readl (&ehci->debug->control)); | 750 | ehci_readl(ehci, &ehci->debug->control)); |
751 | size -= temp; | 751 | size -= temp; |
752 | next += temp; | 752 | next += temp; |
753 | } | 753 | } |
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 1a915e982c1c..a52480505f78 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -177,7 +177,7 @@ static void mpc83xx_setup_phy(struct ehci_hcd *ehci, | |||
177 | case FSL_USB2_PHY_NONE: | 177 | case FSL_USB2_PHY_NONE: |
178 | break; | 178 | break; |
179 | } | 179 | } |
180 | writel(portsc, &ehci->regs->port_status[port_offset]); | 180 | ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); |
181 | } | 181 | } |
182 | 182 | ||
183 | static void mpc83xx_usb_setup(struct usb_hcd *hcd) | 183 | static void mpc83xx_usb_setup(struct usb_hcd *hcd) |
@@ -214,7 +214,7 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd) | |||
214 | } | 214 | } |
215 | 215 | ||
216 | /* put controller in host mode. */ | 216 | /* put controller in host mode. */ |
217 | writel(0x00000003, non_ehci + FSL_SOC_USB_USBMODE); | 217 | ehci_writel(ehci, 0x00000003, non_ehci + FSL_SOC_USB_USBMODE); |
218 | out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c); | 218 | out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c); |
219 | out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040); | 219 | out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040); |
220 | out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001); | 220 | out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001); |
@@ -238,12 +238,12 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) | |||
238 | /* EHCI registers start at offset 0x100 */ | 238 | /* EHCI registers start at offset 0x100 */ |
239 | ehci->caps = hcd->regs + 0x100; | 239 | ehci->caps = hcd->regs + 0x100; |
240 | ehci->regs = hcd->regs + 0x100 + | 240 | ehci->regs = hcd->regs + 0x100 + |
241 | HC_LENGTH(readl(&ehci->caps->hc_capbase)); | 241 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); |
242 | dbg_hcs_params(ehci, "reset"); | 242 | dbg_hcs_params(ehci, "reset"); |
243 | dbg_hcc_params(ehci, "reset"); | 243 | dbg_hcc_params(ehci, "reset"); |
244 | 244 | ||
245 | /* cache this readonly data; minimize chip reads */ | 245 | /* cache this readonly data; minimize chip reads */ |
246 | ehci->hcs_params = readl(&ehci->caps->hcs_params); | 246 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
247 | 247 | ||
248 | retval = ehci_halt(ehci); | 248 | retval = ehci_halt(ehci); |
249 | if (retval) | 249 | if (retval) |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 025d33313681..185721dba42b 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -157,12 +157,13 @@ MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications"); | |||
157 | * before driver shutdown. But it also seems to be caused by bugs in cardbus | 157 | * before driver shutdown. But it also seems to be caused by bugs in cardbus |
158 | * bridge shutdown: shutting down the bridge before the devices using it. | 158 | * bridge shutdown: shutting down the bridge before the devices using it. |
159 | */ | 159 | */ |
160 | static int handshake (void __iomem *ptr, u32 mask, u32 done, int usec) | 160 | static int handshake (struct ehci_hcd *ehci, void __iomem *ptr, |
161 | u32 mask, u32 done, int usec) | ||
161 | { | 162 | { |
162 | u32 result; | 163 | u32 result; |
163 | 164 | ||
164 | do { | 165 | do { |
165 | result = readl (ptr); | 166 | result = ehci_readl(ehci, ptr); |
166 | if (result == ~(u32)0) /* card removed */ | 167 | if (result == ~(u32)0) /* card removed */ |
167 | return -ENODEV; | 168 | return -ENODEV; |
168 | result &= mask; | 169 | result &= mask; |
@@ -177,18 +178,19 @@ static int handshake (void __iomem *ptr, u32 mask, u32 done, int usec) | |||
177 | /* force HC to halt state from unknown (EHCI spec section 2.3) */ | 178 | /* force HC to halt state from unknown (EHCI spec section 2.3) */ |
178 | static int ehci_halt (struct ehci_hcd *ehci) | 179 | static int ehci_halt (struct ehci_hcd *ehci) |
179 | { | 180 | { |
180 | u32 temp = readl (&ehci->regs->status); | 181 | u32 temp = ehci_readl(ehci, &ehci->regs->status); |
181 | 182 | ||
182 | /* disable any irqs left enabled by previous code */ | 183 | /* disable any irqs left enabled by previous code */ |
183 | writel (0, &ehci->regs->intr_enable); | 184 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
184 | 185 | ||
185 | if ((temp & STS_HALT) != 0) | 186 | if ((temp & STS_HALT) != 0) |
186 | return 0; | 187 | return 0; |
187 | 188 | ||
188 | temp = readl (&ehci->regs->command); | 189 | temp = ehci_readl(ehci, &ehci->regs->command); |
189 | temp &= ~CMD_RUN; | 190 | temp &= ~CMD_RUN; |
190 | writel (temp, &ehci->regs->command); | 191 | ehci_writel(ehci, temp, &ehci->regs->command); |
191 | return handshake (&ehci->regs->status, STS_HALT, STS_HALT, 16 * 125); | 192 | return handshake (ehci, &ehci->regs->status, |
193 | STS_HALT, STS_HALT, 16 * 125); | ||
192 | } | 194 | } |
193 | 195 | ||
194 | /* put TDI/ARC silicon into EHCI mode */ | 196 | /* put TDI/ARC silicon into EHCI mode */ |
@@ -198,23 +200,24 @@ static void tdi_reset (struct ehci_hcd *ehci) | |||
198 | u32 tmp; | 200 | u32 tmp; |
199 | 201 | ||
200 | reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + 0x68); | 202 | reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + 0x68); |
201 | tmp = readl (reg_ptr); | 203 | tmp = ehci_readl(ehci, reg_ptr); |
202 | tmp |= 0x3; | 204 | tmp |= 0x3; |
203 | writel (tmp, reg_ptr); | 205 | ehci_writel(ehci, tmp, reg_ptr); |
204 | } | 206 | } |
205 | 207 | ||
206 | /* reset a non-running (STS_HALT == 1) controller */ | 208 | /* reset a non-running (STS_HALT == 1) controller */ |
207 | static int ehci_reset (struct ehci_hcd *ehci) | 209 | static int ehci_reset (struct ehci_hcd *ehci) |
208 | { | 210 | { |
209 | int retval; | 211 | int retval; |
210 | u32 command = readl (&ehci->regs->command); | 212 | u32 command = ehci_readl(ehci, &ehci->regs->command); |
211 | 213 | ||
212 | command |= CMD_RESET; | 214 | command |= CMD_RESET; |
213 | dbg_cmd (ehci, "reset", command); | 215 | dbg_cmd (ehci, "reset", command); |
214 | writel (command, &ehci->regs->command); | 216 | ehci_writel(ehci, command, &ehci->regs->command); |
215 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 217 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; |
216 | ehci->next_statechange = jiffies; | 218 | ehci->next_statechange = jiffies; |
217 | retval = handshake (&ehci->regs->command, CMD_RESET, 0, 250 * 1000); | 219 | retval = handshake (ehci, &ehci->regs->command, |
220 | CMD_RESET, 0, 250 * 1000); | ||
218 | 221 | ||
219 | if (retval) | 222 | if (retval) |
220 | return retval; | 223 | return retval; |
@@ -236,21 +239,21 @@ static void ehci_quiesce (struct ehci_hcd *ehci) | |||
236 | #endif | 239 | #endif |
237 | 240 | ||
238 | /* wait for any schedule enables/disables to take effect */ | 241 | /* wait for any schedule enables/disables to take effect */ |
239 | temp = readl (&ehci->regs->command) << 10; | 242 | temp = ehci_readl(ehci, &ehci->regs->command) << 10; |
240 | temp &= STS_ASS | STS_PSS; | 243 | temp &= STS_ASS | STS_PSS; |
241 | if (handshake (&ehci->regs->status, STS_ASS | STS_PSS, | 244 | if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS, |
242 | temp, 16 * 125) != 0) { | 245 | temp, 16 * 125) != 0) { |
243 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 246 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; |
244 | return; | 247 | return; |
245 | } | 248 | } |
246 | 249 | ||
247 | /* then disable anything that's still active */ | 250 | /* then disable anything that's still active */ |
248 | temp = readl (&ehci->regs->command); | 251 | temp = ehci_readl(ehci, &ehci->regs->command); |
249 | temp &= ~(CMD_ASE | CMD_IAAD | CMD_PSE); | 252 | temp &= ~(CMD_ASE | CMD_IAAD | CMD_PSE); |
250 | writel (temp, &ehci->regs->command); | 253 | ehci_writel(ehci, temp, &ehci->regs->command); |
251 | 254 | ||
252 | /* hardware can take 16 microframes to turn off ... */ | 255 | /* hardware can take 16 microframes to turn off ... */ |
253 | if (handshake (&ehci->regs->status, STS_ASS | STS_PSS, | 256 | if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS, |
254 | 0, 16 * 125) != 0) { | 257 | 0, 16 * 125) != 0) { |
255 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 258 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; |
256 | return; | 259 | return; |
@@ -277,11 +280,11 @@ static void ehci_watchdog (unsigned long param) | |||
277 | 280 | ||
278 | /* lost IAA irqs wedge things badly; seen with a vt8235 */ | 281 | /* lost IAA irqs wedge things badly; seen with a vt8235 */ |
279 | if (ehci->reclaim) { | 282 | if (ehci->reclaim) { |
280 | u32 status = readl (&ehci->regs->status); | 283 | u32 status = ehci_readl(ehci, &ehci->regs->status); |
281 | if (status & STS_IAA) { | 284 | if (status & STS_IAA) { |
282 | ehci_vdbg (ehci, "lost IAA\n"); | 285 | ehci_vdbg (ehci, "lost IAA\n"); |
283 | COUNT (ehci->stats.lost_iaa); | 286 | COUNT (ehci->stats.lost_iaa); |
284 | writel (STS_IAA, &ehci->regs->status); | 287 | ehci_writel(ehci, STS_IAA, &ehci->regs->status); |
285 | ehci->reclaim_ready = 1; | 288 | ehci->reclaim_ready = 1; |
286 | } | 289 | } |
287 | } | 290 | } |
@@ -309,7 +312,7 @@ ehci_shutdown (struct usb_hcd *hcd) | |||
309 | (void) ehci_halt (ehci); | 312 | (void) ehci_halt (ehci); |
310 | 313 | ||
311 | /* make BIOS/etc use companion controller during reboot */ | 314 | /* make BIOS/etc use companion controller during reboot */ |
312 | writel (0, &ehci->regs->configured_flag); | 315 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
313 | } | 316 | } |
314 | 317 | ||
315 | static void ehci_port_power (struct ehci_hcd *ehci, int is_on) | 318 | static void ehci_port_power (struct ehci_hcd *ehci, int is_on) |
@@ -379,12 +382,13 @@ static void ehci_stop (struct usb_hcd *hcd) | |||
379 | ehci_quiesce (ehci); | 382 | ehci_quiesce (ehci); |
380 | 383 | ||
381 | ehci_reset (ehci); | 384 | ehci_reset (ehci); |
382 | writel (0, &ehci->regs->intr_enable); | 385 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
383 | spin_unlock_irq(&ehci->lock); | 386 | spin_unlock_irq(&ehci->lock); |
384 | 387 | ||
385 | /* let companion controllers work when we aren't */ | 388 | /* let companion controllers work when we aren't */ |
386 | writel (0, &ehci->regs->configured_flag); | 389 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
387 | 390 | ||
391 | remove_companion_file(ehci); | ||
388 | remove_debug_files (ehci); | 392 | remove_debug_files (ehci); |
389 | 393 | ||
390 | /* root hub is shut down separately (first, when possible) */ | 394 | /* root hub is shut down separately (first, when possible) */ |
@@ -402,7 +406,8 @@ static void ehci_stop (struct usb_hcd *hcd) | |||
402 | ehci->stats.complete, ehci->stats.unlink); | 406 | ehci->stats.complete, ehci->stats.unlink); |
403 | #endif | 407 | #endif |
404 | 408 | ||
405 | dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status)); | 409 | dbg_status (ehci, "ehci_stop completed", |
410 | ehci_readl(ehci, &ehci->regs->status)); | ||
406 | } | 411 | } |
407 | 412 | ||
408 | /* one-time init, only for memory state */ | 413 | /* one-time init, only for memory state */ |
@@ -428,7 +433,7 @@ static int ehci_init(struct usb_hcd *hcd) | |||
428 | return retval; | 433 | return retval; |
429 | 434 | ||
430 | /* controllers may cache some of the periodic schedule ... */ | 435 | /* controllers may cache some of the periodic schedule ... */ |
431 | hcc_params = readl(&ehci->caps->hcc_params); | 436 | hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); |
432 | if (HCC_ISOC_CACHE(hcc_params)) // full frame cache | 437 | if (HCC_ISOC_CACHE(hcc_params)) // full frame cache |
433 | ehci->i_thresh = 8; | 438 | ehci->i_thresh = 8; |
434 | else // N microframes cached | 439 | else // N microframes cached |
@@ -496,13 +501,16 @@ static int ehci_run (struct usb_hcd *hcd) | |||
496 | u32 temp; | 501 | u32 temp; |
497 | u32 hcc_params; | 502 | u32 hcc_params; |
498 | 503 | ||
504 | hcd->uses_new_polling = 1; | ||
505 | hcd->poll_rh = 0; | ||
506 | |||
499 | /* EHCI spec section 4.1 */ | 507 | /* EHCI spec section 4.1 */ |
500 | if ((retval = ehci_reset(ehci)) != 0) { | 508 | if ((retval = ehci_reset(ehci)) != 0) { |
501 | ehci_mem_cleanup(ehci); | 509 | ehci_mem_cleanup(ehci); |
502 | return retval; | 510 | return retval; |
503 | } | 511 | } |
504 | writel(ehci->periodic_dma, &ehci->regs->frame_list); | 512 | ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); |
505 | writel((u32)ehci->async->qh_dma, &ehci->regs->async_next); | 513 | ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next); |
506 | 514 | ||
507 | /* | 515 | /* |
508 | * hcc_params controls whether ehci->regs->segment must (!!!) | 516 | * hcc_params controls whether ehci->regs->segment must (!!!) |
@@ -516,9 +524,9 @@ static int ehci_run (struct usb_hcd *hcd) | |||
516 | * Scsi_Host.highmem_io, and so forth. It's readonly to all | 524 | * Scsi_Host.highmem_io, and so forth. It's readonly to all |
517 | * host side drivers though. | 525 | * host side drivers though. |
518 | */ | 526 | */ |
519 | hcc_params = readl(&ehci->caps->hcc_params); | 527 | hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); |
520 | if (HCC_64BIT_ADDR(hcc_params)) { | 528 | if (HCC_64BIT_ADDR(hcc_params)) { |
521 | writel(0, &ehci->regs->segment); | 529 | ehci_writel(ehci, 0, &ehci->regs->segment); |
522 | #if 0 | 530 | #if 0 |
523 | // this is deeply broken on almost all architectures | 531 | // this is deeply broken on almost all architectures |
524 | if (!dma_set_mask(hcd->self.controller, DMA_64BIT_MASK)) | 532 | if (!dma_set_mask(hcd->self.controller, DMA_64BIT_MASK)) |
@@ -531,7 +539,7 @@ static int ehci_run (struct usb_hcd *hcd) | |||
531 | // root hub will detect new devices (why?); NEC doesn't | 539 | // root hub will detect new devices (why?); NEC doesn't |
532 | ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); | 540 | ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); |
533 | ehci->command |= CMD_RUN; | 541 | ehci->command |= CMD_RUN; |
534 | writel (ehci->command, &ehci->regs->command); | 542 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
535 | dbg_cmd (ehci, "init", ehci->command); | 543 | dbg_cmd (ehci, "init", ehci->command); |
536 | 544 | ||
537 | /* | 545 | /* |
@@ -541,23 +549,25 @@ static int ehci_run (struct usb_hcd *hcd) | |||
541 | * and there's no companion controller unless maybe for USB OTG.) | 549 | * and there's no companion controller unless maybe for USB OTG.) |
542 | */ | 550 | */ |
543 | hcd->state = HC_STATE_RUNNING; | 551 | hcd->state = HC_STATE_RUNNING; |
544 | writel (FLAG_CF, &ehci->regs->configured_flag); | 552 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); |
545 | readl (&ehci->regs->command); /* unblock posted writes */ | 553 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ |
546 | 554 | ||
547 | temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); | 555 | temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); |
548 | ehci_info (ehci, | 556 | ehci_info (ehci, |
549 | "USB %x.%x started, EHCI %x.%02x, driver %s%s\n", | 557 | "USB %x.%x started, EHCI %x.%02x, driver %s%s\n", |
550 | ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), | 558 | ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), |
551 | temp >> 8, temp & 0xff, DRIVER_VERSION, | 559 | temp >> 8, temp & 0xff, DRIVER_VERSION, |
552 | ignore_oc ? ", overcurrent ignored" : ""); | 560 | ignore_oc ? ", overcurrent ignored" : ""); |
553 | 561 | ||
554 | writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */ | 562 | ehci_writel(ehci, INTR_MASK, |
563 | &ehci->regs->intr_enable); /* Turn On Interrupts */ | ||
555 | 564 | ||
556 | /* GRR this is run-once init(), being done every time the HC starts. | 565 | /* GRR this is run-once init(), being done every time the HC starts. |
557 | * So long as they're part of class devices, we can't do it init() | 566 | * So long as they're part of class devices, we can't do it init() |
558 | * since the class device isn't created that early. | 567 | * since the class device isn't created that early. |
559 | */ | 568 | */ |
560 | create_debug_files(ehci); | 569 | create_debug_files(ehci); |
570 | create_companion_file(ehci); | ||
561 | 571 | ||
562 | return 0; | 572 | return 0; |
563 | } | 573 | } |
@@ -567,12 +577,12 @@ static int ehci_run (struct usb_hcd *hcd) | |||
567 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) | 577 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) |
568 | { | 578 | { |
569 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 579 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
570 | u32 status; | 580 | u32 status, pcd_status = 0; |
571 | int bh; | 581 | int bh; |
572 | 582 | ||
573 | spin_lock (&ehci->lock); | 583 | spin_lock (&ehci->lock); |
574 | 584 | ||
575 | status = readl (&ehci->regs->status); | 585 | status = ehci_readl(ehci, &ehci->regs->status); |
576 | 586 | ||
577 | /* e.g. cardbus physical eject */ | 587 | /* e.g. cardbus physical eject */ |
578 | if (status == ~(u32) 0) { | 588 | if (status == ~(u32) 0) { |
@@ -587,8 +597,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
587 | } | 597 | } |
588 | 598 | ||
589 | /* clear (just) interrupts */ | 599 | /* clear (just) interrupts */ |
590 | writel (status, &ehci->regs->status); | 600 | ehci_writel(ehci, status, &ehci->regs->status); |
591 | readl (&ehci->regs->command); /* unblock posted write */ | 601 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted write */ |
592 | bh = 0; | 602 | bh = 0; |
593 | 603 | ||
594 | #ifdef EHCI_VERBOSE_DEBUG | 604 | #ifdef EHCI_VERBOSE_DEBUG |
@@ -617,13 +627,15 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
617 | /* remote wakeup [4.3.1] */ | 627 | /* remote wakeup [4.3.1] */ |
618 | if (status & STS_PCD) { | 628 | if (status & STS_PCD) { |
619 | unsigned i = HCS_N_PORTS (ehci->hcs_params); | 629 | unsigned i = HCS_N_PORTS (ehci->hcs_params); |
630 | pcd_status = status; | ||
620 | 631 | ||
621 | /* resume root hub? */ | 632 | /* resume root hub? */ |
622 | if (!(readl(&ehci->regs->command) & CMD_RUN)) | 633 | if (!(ehci_readl(ehci, &ehci->regs->command) & CMD_RUN)) |
623 | usb_hcd_resume_root_hub(hcd); | 634 | usb_hcd_resume_root_hub(hcd); |
624 | 635 | ||
625 | while (i--) { | 636 | while (i--) { |
626 | int pstatus = readl (&ehci->regs->port_status [i]); | 637 | int pstatus = ehci_readl(ehci, |
638 | &ehci->regs->port_status [i]); | ||
627 | 639 | ||
628 | if (pstatus & PORT_OWNER) | 640 | if (pstatus & PORT_OWNER) |
629 | continue; | 641 | continue; |
@@ -643,14 +655,15 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
643 | /* PCI errors [4.15.2.4] */ | 655 | /* PCI errors [4.15.2.4] */ |
644 | if (unlikely ((status & STS_FATAL) != 0)) { | 656 | if (unlikely ((status & STS_FATAL) != 0)) { |
645 | /* bogus "fatal" IRQs appear on some chips... why? */ | 657 | /* bogus "fatal" IRQs appear on some chips... why? */ |
646 | status = readl (&ehci->regs->status); | 658 | status = ehci_readl(ehci, &ehci->regs->status); |
647 | dbg_cmd (ehci, "fatal", readl (&ehci->regs->command)); | 659 | dbg_cmd (ehci, "fatal", ehci_readl(ehci, |
660 | &ehci->regs->command)); | ||
648 | dbg_status (ehci, "fatal", status); | 661 | dbg_status (ehci, "fatal", status); |
649 | if (status & STS_HALT) { | 662 | if (status & STS_HALT) { |
650 | ehci_err (ehci, "fatal error\n"); | 663 | ehci_err (ehci, "fatal error\n"); |
651 | dead: | 664 | dead: |
652 | ehci_reset (ehci); | 665 | ehci_reset (ehci); |
653 | writel (0, &ehci->regs->configured_flag); | 666 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
654 | /* generic layer kills/unlinks all urbs, then | 667 | /* generic layer kills/unlinks all urbs, then |
655 | * uses ehci_stop to clean up the rest | 668 | * uses ehci_stop to clean up the rest |
656 | */ | 669 | */ |
@@ -661,6 +674,8 @@ dead: | |||
661 | if (bh) | 674 | if (bh) |
662 | ehci_work (ehci); | 675 | ehci_work (ehci); |
663 | spin_unlock (&ehci->lock); | 676 | spin_unlock (&ehci->lock); |
677 | if (pcd_status & STS_PCD) | ||
678 | usb_hcd_poll_rh_status(hcd); | ||
664 | return IRQ_HANDLED; | 679 | return IRQ_HANDLED; |
665 | } | 680 | } |
666 | 681 | ||
@@ -873,7 +888,8 @@ done: | |||
873 | static int ehci_get_frame (struct usb_hcd *hcd) | 888 | static int ehci_get_frame (struct usb_hcd *hcd) |
874 | { | 889 | { |
875 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 890 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
876 | return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size; | 891 | return (ehci_readl(ehci, &ehci->regs->frame_index) >> 3) % |
892 | ehci->periodic_size; | ||
877 | } | 893 | } |
878 | 894 | ||
879 | /*-------------------------------------------------------------------------*/ | 895 | /*-------------------------------------------------------------------------*/ |
@@ -899,7 +915,13 @@ MODULE_LICENSE ("GPL"); | |||
899 | #define PLATFORM_DRIVER ehci_hcd_au1xxx_driver | 915 | #define PLATFORM_DRIVER ehci_hcd_au1xxx_driver |
900 | #endif | 916 | #endif |
901 | 917 | ||
902 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) | 918 | #ifdef CONFIG_PPC_PS3 |
919 | #include "ehci-ps3.c" | ||
920 | #define PS3_SYSTEM_BUS_DRIVER ps3_ehci_sb_driver | ||
921 | #endif | ||
922 | |||
923 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ | ||
924 | !defined(PS3_SYSTEM_BUS_DRIVER) | ||
903 | #error "missing bus glue for ehci-hcd" | 925 | #error "missing bus glue for ehci-hcd" |
904 | #endif | 926 | #endif |
905 | 927 | ||
@@ -924,6 +946,20 @@ static int __init ehci_hcd_init(void) | |||
924 | #ifdef PLATFORM_DRIVER | 946 | #ifdef PLATFORM_DRIVER |
925 | platform_driver_unregister(&PLATFORM_DRIVER); | 947 | platform_driver_unregister(&PLATFORM_DRIVER); |
926 | #endif | 948 | #endif |
949 | return retval; | ||
950 | } | ||
951 | #endif | ||
952 | |||
953 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
954 | retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER); | ||
955 | if (retval < 0) { | ||
956 | #ifdef PLATFORM_DRIVER | ||
957 | platform_driver_unregister(&PLATFORM_DRIVER); | ||
958 | #endif | ||
959 | #ifdef PCI_DRIVER | ||
960 | pci_unregister_driver(&PCI_DRIVER); | ||
961 | #endif | ||
962 | return retval; | ||
927 | } | 963 | } |
928 | #endif | 964 | #endif |
929 | 965 | ||
@@ -939,6 +975,9 @@ static void __exit ehci_hcd_cleanup(void) | |||
939 | #ifdef PCI_DRIVER | 975 | #ifdef PCI_DRIVER |
940 | pci_unregister_driver(&PCI_DRIVER); | 976 | pci_unregister_driver(&PCI_DRIVER); |
941 | #endif | 977 | #endif |
978 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
979 | ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | ||
980 | #endif | ||
942 | } | 981 | } |
943 | module_exit(ehci_hcd_cleanup); | 982 | module_exit(ehci_hcd_cleanup); |
944 | 983 | ||
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index bfe5f307cba6..0d83c6df1a3b 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -47,7 +47,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
47 | ehci_quiesce (ehci); | 47 | ehci_quiesce (ehci); |
48 | hcd->state = HC_STATE_QUIESCING; | 48 | hcd->state = HC_STATE_QUIESCING; |
49 | } | 49 | } |
50 | ehci->command = readl (&ehci->regs->command); | 50 | ehci->command = ehci_readl(ehci, &ehci->regs->command); |
51 | if (ehci->reclaim) | 51 | if (ehci->reclaim) |
52 | ehci->reclaim_ready = 1; | 52 | ehci->reclaim_ready = 1; |
53 | ehci_work(ehci); | 53 | ehci_work(ehci); |
@@ -60,7 +60,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
60 | ehci->bus_suspended = 0; | 60 | ehci->bus_suspended = 0; |
61 | while (port--) { | 61 | while (port--) { |
62 | u32 __iomem *reg = &ehci->regs->port_status [port]; | 62 | u32 __iomem *reg = &ehci->regs->port_status [port]; |
63 | u32 t1 = readl (reg) & ~PORT_RWC_BITS; | 63 | u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; |
64 | u32 t2 = t1; | 64 | u32 t2 = t1; |
65 | 65 | ||
66 | /* keep track of which ports we suspend */ | 66 | /* keep track of which ports we suspend */ |
@@ -79,7 +79,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
79 | if (t1 != t2) { | 79 | if (t1 != t2) { |
80 | ehci_vdbg (ehci, "port %d, %08x -> %08x\n", | 80 | ehci_vdbg (ehci, "port %d, %08x -> %08x\n", |
81 | port + 1, t1, t2); | 81 | port + 1, t1, t2); |
82 | writel (t2, reg); | 82 | ehci_writel(ehci, t2, reg); |
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
@@ -92,8 +92,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
92 | mask = INTR_MASK; | 92 | mask = INTR_MASK; |
93 | if (!device_may_wakeup(&hcd->self.root_hub->dev)) | 93 | if (!device_may_wakeup(&hcd->self.root_hub->dev)) |
94 | mask &= ~STS_PCD; | 94 | mask &= ~STS_PCD; |
95 | writel(mask, &ehci->regs->intr_enable); | 95 | ehci_writel(ehci, mask, &ehci->regs->intr_enable); |
96 | readl(&ehci->regs->intr_enable); | 96 | ehci_readl(ehci, &ehci->regs->intr_enable); |
97 | 97 | ||
98 | ehci->next_statechange = jiffies + msecs_to_jiffies(10); | 98 | ehci->next_statechange = jiffies + msecs_to_jiffies(10); |
99 | spin_unlock_irq (&ehci->lock); | 99 | spin_unlock_irq (&ehci->lock); |
@@ -118,26 +118,26 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
118 | * the last user of the controller, not reset/pm hardware keeping | 118 | * the last user of the controller, not reset/pm hardware keeping |
119 | * state we gave to it. | 119 | * state we gave to it. |
120 | */ | 120 | */ |
121 | temp = readl(&ehci->regs->intr_enable); | 121 | temp = ehci_readl(ehci, &ehci->regs->intr_enable); |
122 | ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss"); | 122 | ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss"); |
123 | 123 | ||
124 | /* at least some APM implementations will try to deliver | 124 | /* at least some APM implementations will try to deliver |
125 | * IRQs right away, so delay them until we're ready. | 125 | * IRQs right away, so delay them until we're ready. |
126 | */ | 126 | */ |
127 | writel(0, &ehci->regs->intr_enable); | 127 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
128 | 128 | ||
129 | /* re-init operational registers */ | 129 | /* re-init operational registers */ |
130 | writel(0, &ehci->regs->segment); | 130 | ehci_writel(ehci, 0, &ehci->regs->segment); |
131 | writel(ehci->periodic_dma, &ehci->regs->frame_list); | 131 | ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); |
132 | writel((u32) ehci->async->qh_dma, &ehci->regs->async_next); | 132 | ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next); |
133 | 133 | ||
134 | /* restore CMD_RUN, framelist size, and irq threshold */ | 134 | /* restore CMD_RUN, framelist size, and irq threshold */ |
135 | writel (ehci->command, &ehci->regs->command); | 135 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
136 | 136 | ||
137 | /* manually resume the ports we suspended during bus_suspend() */ | 137 | /* manually resume the ports we suspended during bus_suspend() */ |
138 | i = HCS_N_PORTS (ehci->hcs_params); | 138 | i = HCS_N_PORTS (ehci->hcs_params); |
139 | while (i--) { | 139 | while (i--) { |
140 | temp = readl (&ehci->regs->port_status [i]); | 140 | temp = ehci_readl(ehci, &ehci->regs->port_status [i]); |
141 | temp &= ~(PORT_RWC_BITS | 141 | temp &= ~(PORT_RWC_BITS |
142 | | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E); | 142 | | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E); |
143 | if (test_bit(i, &ehci->bus_suspended) && | 143 | if (test_bit(i, &ehci->bus_suspended) && |
@@ -145,20 +145,20 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
145 | ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); | 145 | ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); |
146 | temp |= PORT_RESUME; | 146 | temp |= PORT_RESUME; |
147 | } | 147 | } |
148 | writel (temp, &ehci->regs->port_status [i]); | 148 | ehci_writel(ehci, temp, &ehci->regs->port_status [i]); |
149 | } | 149 | } |
150 | i = HCS_N_PORTS (ehci->hcs_params); | 150 | i = HCS_N_PORTS (ehci->hcs_params); |
151 | mdelay (20); | 151 | mdelay (20); |
152 | while (i--) { | 152 | while (i--) { |
153 | temp = readl (&ehci->regs->port_status [i]); | 153 | temp = ehci_readl(ehci, &ehci->regs->port_status [i]); |
154 | if (test_bit(i, &ehci->bus_suspended) && | 154 | if (test_bit(i, &ehci->bus_suspended) && |
155 | (temp & PORT_SUSPEND)) { | 155 | (temp & PORT_SUSPEND)) { |
156 | temp &= ~(PORT_RWC_BITS | PORT_RESUME); | 156 | temp &= ~(PORT_RWC_BITS | PORT_RESUME); |
157 | writel (temp, &ehci->regs->port_status [i]); | 157 | ehci_writel(ehci, temp, &ehci->regs->port_status [i]); |
158 | ehci_vdbg (ehci, "resumed port %d\n", i + 1); | 158 | ehci_vdbg (ehci, "resumed port %d\n", i + 1); |
159 | } | 159 | } |
160 | } | 160 | } |
161 | (void) readl (&ehci->regs->command); | 161 | (void) ehci_readl(ehci, &ehci->regs->command); |
162 | 162 | ||
163 | /* maybe re-activate the schedule(s) */ | 163 | /* maybe re-activate the schedule(s) */ |
164 | temp = 0; | 164 | temp = 0; |
@@ -168,14 +168,14 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
168 | temp |= CMD_PSE; | 168 | temp |= CMD_PSE; |
169 | if (temp) { | 169 | if (temp) { |
170 | ehci->command |= temp; | 170 | ehci->command |= temp; |
171 | writel (ehci->command, &ehci->regs->command); | 171 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
172 | } | 172 | } |
173 | 173 | ||
174 | ehci->next_statechange = jiffies + msecs_to_jiffies(5); | 174 | ehci->next_statechange = jiffies + msecs_to_jiffies(5); |
175 | hcd->state = HC_STATE_RUNNING; | 175 | hcd->state = HC_STATE_RUNNING; |
176 | 176 | ||
177 | /* Now we can safely re-enable irqs */ | 177 | /* Now we can safely re-enable irqs */ |
178 | writel(INTR_MASK, &ehci->regs->intr_enable); | 178 | ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); |
179 | 179 | ||
180 | spin_unlock_irq (&ehci->lock); | 180 | spin_unlock_irq (&ehci->lock); |
181 | return 0; | 181 | return 0; |
@@ -190,9 +190,107 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
190 | 190 | ||
191 | /*-------------------------------------------------------------------------*/ | 191 | /*-------------------------------------------------------------------------*/ |
192 | 192 | ||
193 | /* Display the ports dedicated to the companion controller */ | ||
194 | static ssize_t show_companion(struct class_device *class_dev, char *buf) | ||
195 | { | ||
196 | struct ehci_hcd *ehci; | ||
197 | int nports, index, n; | ||
198 | int count = PAGE_SIZE; | ||
199 | char *ptr = buf; | ||
200 | |||
201 | ehci = hcd_to_ehci(bus_to_hcd(class_get_devdata(class_dev))); | ||
202 | nports = HCS_N_PORTS(ehci->hcs_params); | ||
203 | |||
204 | for (index = 0; index < nports; ++index) { | ||
205 | if (test_bit(index, &ehci->companion_ports)) { | ||
206 | n = scnprintf(ptr, count, "%d\n", index + 1); | ||
207 | ptr += n; | ||
208 | count -= n; | ||
209 | } | ||
210 | } | ||
211 | return ptr - buf; | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * Dedicate or undedicate a port to the companion controller. | ||
216 | * Syntax is "[-]portnum", where a leading '-' sign means | ||
217 | * return control of the port to the EHCI controller. | ||
218 | */ | ||
219 | static ssize_t store_companion(struct class_device *class_dev, | ||
220 | const char *buf, size_t count) | ||
221 | { | ||
222 | struct ehci_hcd *ehci; | ||
223 | int portnum, new_owner, try; | ||
224 | u32 __iomem *status_reg; | ||
225 | u32 port_status; | ||
226 | |||
227 | ehci = hcd_to_ehci(bus_to_hcd(class_get_devdata(class_dev))); | ||
228 | new_owner = PORT_OWNER; /* Owned by companion */ | ||
229 | if (sscanf(buf, "%d", &portnum) != 1) | ||
230 | return -EINVAL; | ||
231 | if (portnum < 0) { | ||
232 | portnum = - portnum; | ||
233 | new_owner = 0; /* Owned by EHCI */ | ||
234 | } | ||
235 | if (portnum <= 0 || portnum > HCS_N_PORTS(ehci->hcs_params)) | ||
236 | return -ENOENT; | ||
237 | status_reg = &ehci->regs->port_status[--portnum]; | ||
238 | if (new_owner) | ||
239 | set_bit(portnum, &ehci->companion_ports); | ||
240 | else | ||
241 | clear_bit(portnum, &ehci->companion_ports); | ||
242 | |||
243 | /* | ||
244 | * The controller won't set the OWNER bit if the port is | ||
245 | * enabled, so this loop will sometimes require at least two | ||
246 | * iterations: one to disable the port and one to set OWNER. | ||
247 | */ | ||
248 | |||
249 | for (try = 4; try > 0; --try) { | ||
250 | spin_lock_irq(&ehci->lock); | ||
251 | port_status = ehci_readl(ehci, status_reg); | ||
252 | if ((port_status & PORT_OWNER) == new_owner | ||
253 | || (port_status & (PORT_OWNER | PORT_CONNECT)) | ||
254 | == 0) | ||
255 | try = 0; | ||
256 | else { | ||
257 | port_status ^= PORT_OWNER; | ||
258 | port_status &= ~(PORT_PE | PORT_RWC_BITS); | ||
259 | ehci_writel(ehci, port_status, status_reg); | ||
260 | } | ||
261 | spin_unlock_irq(&ehci->lock); | ||
262 | if (try > 1) | ||
263 | msleep(5); | ||
264 | } | ||
265 | return count; | ||
266 | } | ||
267 | static CLASS_DEVICE_ATTR(companion, 0644, show_companion, store_companion); | ||
268 | |||
269 | static inline void create_companion_file(struct ehci_hcd *ehci) | ||
270 | { | ||
271 | int i; | ||
272 | |||
273 | /* with integrated TT there is no companion! */ | ||
274 | if (!ehci_is_TDI(ehci)) | ||
275 | i = class_device_create_file(ehci_to_hcd(ehci)->self.class_dev, | ||
276 | &class_device_attr_companion); | ||
277 | } | ||
278 | |||
279 | static inline void remove_companion_file(struct ehci_hcd *ehci) | ||
280 | { | ||
281 | /* with integrated TT there is no companion! */ | ||
282 | if (!ehci_is_TDI(ehci)) | ||
283 | class_device_remove_file(ehci_to_hcd(ehci)->self.class_dev, | ||
284 | &class_device_attr_companion); | ||
285 | } | ||
286 | |||
287 | |||
288 | /*-------------------------------------------------------------------------*/ | ||
289 | |||
193 | static int check_reset_complete ( | 290 | static int check_reset_complete ( |
194 | struct ehci_hcd *ehci, | 291 | struct ehci_hcd *ehci, |
195 | int index, | 292 | int index, |
293 | u32 __iomem *status_reg, | ||
196 | int port_status | 294 | int port_status |
197 | ) { | 295 | ) { |
198 | if (!(port_status & PORT_CONNECT)) { | 296 | if (!(port_status & PORT_CONNECT)) { |
@@ -217,7 +315,7 @@ static int check_reset_complete ( | |||
217 | // what happens if HCS_N_CC(params) == 0 ? | 315 | // what happens if HCS_N_CC(params) == 0 ? |
218 | port_status |= PORT_OWNER; | 316 | port_status |= PORT_OWNER; |
219 | port_status &= ~PORT_RWC_BITS; | 317 | port_status &= ~PORT_RWC_BITS; |
220 | writel (port_status, &ehci->regs->port_status [index]); | 318 | ehci_writel(ehci, port_status, status_reg); |
221 | 319 | ||
222 | } else | 320 | } else |
223 | ehci_dbg (ehci, "port %d high speed\n", index + 1); | 321 | ehci_dbg (ehci, "port %d high speed\n", index + 1); |
@@ -268,22 +366,21 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
268 | /* port N changes (bit N)? */ | 366 | /* port N changes (bit N)? */ |
269 | spin_lock_irqsave (&ehci->lock, flags); | 367 | spin_lock_irqsave (&ehci->lock, flags); |
270 | for (i = 0; i < ports; i++) { | 368 | for (i = 0; i < ports; i++) { |
271 | temp = readl (&ehci->regs->port_status [i]); | 369 | temp = ehci_readl(ehci, &ehci->regs->port_status [i]); |
272 | if (temp & PORT_OWNER) { | 370 | |
273 | /* don't report this in GetPortStatus */ | 371 | /* |
274 | if (temp & PORT_CSC) { | 372 | * Return status information even for ports with OWNER set. |
275 | temp &= ~PORT_RWC_BITS; | 373 | * Otherwise khubd wouldn't see the disconnect event when a |
276 | temp |= PORT_CSC; | 374 | * high-speed device is switched over to the companion |
277 | writel (temp, &ehci->regs->port_status [i]); | 375 | * controller by the user. |
278 | } | 376 | */ |
279 | continue; | 377 | |
280 | } | ||
281 | if (!(temp & PORT_CONNECT)) | 378 | if (!(temp & PORT_CONNECT)) |
282 | ehci->reset_done [i] = 0; | 379 | ehci->reset_done [i] = 0; |
283 | if ((temp & mask) != 0 | 380 | if ((temp & mask) != 0 |
284 | || ((temp & PORT_RESUME) != 0 | 381 | || ((temp & PORT_RESUME) != 0 |
285 | && time_after (jiffies, | 382 | && time_after_eq(jiffies, |
286 | ehci->reset_done [i]))) { | 383 | ehci->reset_done[i]))) { |
287 | if (i < 7) | 384 | if (i < 7) |
288 | buf [0] |= 1 << (i + 1); | 385 | buf [0] |= 1 << (i + 1); |
289 | else | 386 | else |
@@ -345,6 +442,7 @@ static int ehci_hub_control ( | |||
345 | ) { | 442 | ) { |
346 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 443 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
347 | int ports = HCS_N_PORTS (ehci->hcs_params); | 444 | int ports = HCS_N_PORTS (ehci->hcs_params); |
445 | u32 __iomem *status_reg = &ehci->regs->port_status[wIndex - 1]; | ||
348 | u32 temp, status; | 446 | u32 temp, status; |
349 | unsigned long flags; | 447 | unsigned long flags; |
350 | int retval = 0; | 448 | int retval = 0; |
@@ -373,18 +471,22 @@ static int ehci_hub_control ( | |||
373 | if (!wIndex || wIndex > ports) | 471 | if (!wIndex || wIndex > ports) |
374 | goto error; | 472 | goto error; |
375 | wIndex--; | 473 | wIndex--; |
376 | temp = readl (&ehci->regs->port_status [wIndex]); | 474 | temp = ehci_readl(ehci, status_reg); |
377 | if (temp & PORT_OWNER) | 475 | |
378 | break; | 476 | /* |
477 | * Even if OWNER is set, so the port is owned by the | ||
478 | * companion controller, khubd needs to be able to clear | ||
479 | * the port-change status bits (especially | ||
480 | * USB_PORT_FEAT_C_CONNECTION). | ||
481 | */ | ||
379 | 482 | ||
380 | switch (wValue) { | 483 | switch (wValue) { |
381 | case USB_PORT_FEAT_ENABLE: | 484 | case USB_PORT_FEAT_ENABLE: |
382 | writel (temp & ~PORT_PE, | 485 | ehci_writel(ehci, temp & ~PORT_PE, status_reg); |
383 | &ehci->regs->port_status [wIndex]); | ||
384 | break; | 486 | break; |
385 | case USB_PORT_FEAT_C_ENABLE: | 487 | case USB_PORT_FEAT_C_ENABLE: |
386 | writel((temp & ~PORT_RWC_BITS) | PORT_PEC, | 488 | ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_PEC, |
387 | &ehci->regs->port_status [wIndex]); | 489 | status_reg); |
388 | break; | 490 | break; |
389 | case USB_PORT_FEAT_SUSPEND: | 491 | case USB_PORT_FEAT_SUSPEND: |
390 | if (temp & PORT_RESET) | 492 | if (temp & PORT_RESET) |
@@ -396,8 +498,8 @@ static int ehci_hub_control ( | |||
396 | goto error; | 498 | goto error; |
397 | /* resume signaling for 20 msec */ | 499 | /* resume signaling for 20 msec */ |
398 | temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); | 500 | temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); |
399 | writel (temp | PORT_RESUME, | 501 | ehci_writel(ehci, temp | PORT_RESUME, |
400 | &ehci->regs->port_status [wIndex]); | 502 | status_reg); |
401 | ehci->reset_done [wIndex] = jiffies | 503 | ehci->reset_done [wIndex] = jiffies |
402 | + msecs_to_jiffies (20); | 504 | + msecs_to_jiffies (20); |
403 | } | 505 | } |
@@ -407,16 +509,17 @@ static int ehci_hub_control ( | |||
407 | break; | 509 | break; |
408 | case USB_PORT_FEAT_POWER: | 510 | case USB_PORT_FEAT_POWER: |
409 | if (HCS_PPC (ehci->hcs_params)) | 511 | if (HCS_PPC (ehci->hcs_params)) |
410 | writel (temp & ~(PORT_RWC_BITS | PORT_POWER), | 512 | ehci_writel(ehci, |
411 | &ehci->regs->port_status [wIndex]); | 513 | temp & ~(PORT_RWC_BITS | PORT_POWER), |
514 | status_reg); | ||
412 | break; | 515 | break; |
413 | case USB_PORT_FEAT_C_CONNECTION: | 516 | case USB_PORT_FEAT_C_CONNECTION: |
414 | writel((temp & ~PORT_RWC_BITS) | PORT_CSC, | 517 | ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_CSC, |
415 | &ehci->regs->port_status [wIndex]); | 518 | status_reg); |
416 | break; | 519 | break; |
417 | case USB_PORT_FEAT_C_OVER_CURRENT: | 520 | case USB_PORT_FEAT_C_OVER_CURRENT: |
418 | writel((temp & ~PORT_RWC_BITS) | PORT_OCC, | 521 | ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_OCC, |
419 | &ehci->regs->port_status [wIndex]); | 522 | status_reg); |
420 | break; | 523 | break; |
421 | case USB_PORT_FEAT_C_RESET: | 524 | case USB_PORT_FEAT_C_RESET: |
422 | /* GetPortStatus clears reset */ | 525 | /* GetPortStatus clears reset */ |
@@ -424,7 +527,7 @@ static int ehci_hub_control ( | |||
424 | default: | 527 | default: |
425 | goto error; | 528 | goto error; |
426 | } | 529 | } |
427 | readl (&ehci->regs->command); /* unblock posted write */ | 530 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted write */ |
428 | break; | 531 | break; |
429 | case GetHubDescriptor: | 532 | case GetHubDescriptor: |
430 | ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *) | 533 | ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *) |
@@ -440,7 +543,7 @@ static int ehci_hub_control ( | |||
440 | goto error; | 543 | goto error; |
441 | wIndex--; | 544 | wIndex--; |
442 | status = 0; | 545 | status = 0; |
443 | temp = readl (&ehci->regs->port_status [wIndex]); | 546 | temp = ehci_readl(ehci, status_reg); |
444 | 547 | ||
445 | // wPortChange bits | 548 | // wPortChange bits |
446 | if (temp & PORT_CSC) | 549 | if (temp & PORT_CSC) |
@@ -451,42 +554,55 @@ static int ehci_hub_control ( | |||
451 | status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT; | 554 | status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT; |
452 | 555 | ||
453 | /* whoever resumes must GetPortStatus to complete it!! */ | 556 | /* whoever resumes must GetPortStatus to complete it!! */ |
454 | if ((temp & PORT_RESUME) | 557 | if (temp & PORT_RESUME) { |
455 | && time_after (jiffies, | ||
456 | ehci->reset_done [wIndex])) { | ||
457 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | ||
458 | ehci->reset_done [wIndex] = 0; | ||
459 | 558 | ||
460 | /* stop resume signaling */ | 559 | /* Remote Wakeup received? */ |
461 | temp = readl (&ehci->regs->port_status [wIndex]); | 560 | if (!ehci->reset_done[wIndex]) { |
462 | writel (temp & ~(PORT_RWC_BITS | PORT_RESUME), | 561 | /* resume signaling for 20 msec */ |
463 | &ehci->regs->port_status [wIndex]); | 562 | ehci->reset_done[wIndex] = jiffies |
464 | retval = handshake ( | 563 | + msecs_to_jiffies(20); |
465 | &ehci->regs->port_status [wIndex], | 564 | /* check the port again */ |
466 | PORT_RESUME, 0, 2000 /* 2msec */); | 565 | mod_timer(&ehci_to_hcd(ehci)->rh_timer, |
467 | if (retval != 0) { | 566 | ehci->reset_done[wIndex]); |
468 | ehci_err (ehci, "port %d resume error %d\n", | 567 | } |
469 | wIndex + 1, retval); | 568 | |
470 | goto error; | 569 | /* resume completed? */ |
570 | else if (time_after_eq(jiffies, | ||
571 | ehci->reset_done[wIndex])) { | ||
572 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | ||
573 | ehci->reset_done[wIndex] = 0; | ||
574 | |||
575 | /* stop resume signaling */ | ||
576 | temp = ehci_readl(ehci, status_reg); | ||
577 | ehci_writel(ehci, | ||
578 | temp & ~(PORT_RWC_BITS | PORT_RESUME), | ||
579 | status_reg); | ||
580 | retval = handshake(ehci, status_reg, | ||
581 | PORT_RESUME, 0, 2000 /* 2msec */); | ||
582 | if (retval != 0) { | ||
583 | ehci_err(ehci, | ||
584 | "port %d resume error %d\n", | ||
585 | wIndex + 1, retval); | ||
586 | goto error; | ||
587 | } | ||
588 | temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10)); | ||
471 | } | 589 | } |
472 | temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10)); | ||
473 | } | 590 | } |
474 | 591 | ||
475 | /* whoever resets must GetPortStatus to complete it!! */ | 592 | /* whoever resets must GetPortStatus to complete it!! */ |
476 | if ((temp & PORT_RESET) | 593 | if ((temp & PORT_RESET) |
477 | && time_after (jiffies, | 594 | && time_after_eq(jiffies, |
478 | ehci->reset_done [wIndex])) { | 595 | ehci->reset_done[wIndex])) { |
479 | status |= 1 << USB_PORT_FEAT_C_RESET; | 596 | status |= 1 << USB_PORT_FEAT_C_RESET; |
480 | ehci->reset_done [wIndex] = 0; | 597 | ehci->reset_done [wIndex] = 0; |
481 | 598 | ||
482 | /* force reset to complete */ | 599 | /* force reset to complete */ |
483 | writel (temp & ~(PORT_RWC_BITS | PORT_RESET), | 600 | ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET), |
484 | &ehci->regs->port_status [wIndex]); | 601 | status_reg); |
485 | /* REVISIT: some hardware needs 550+ usec to clear | 602 | /* REVISIT: some hardware needs 550+ usec to clear |
486 | * this bit; seems too long to spin routinely... | 603 | * this bit; seems too long to spin routinely... |
487 | */ | 604 | */ |
488 | retval = handshake ( | 605 | retval = handshake(ehci, status_reg, |
489 | &ehci->regs->port_status [wIndex], | ||
490 | PORT_RESET, 0, 750); | 606 | PORT_RESET, 0, 750); |
491 | if (retval != 0) { | 607 | if (retval != 0) { |
492 | ehci_err (ehci, "port %d reset error %d\n", | 608 | ehci_err (ehci, "port %d reset error %d\n", |
@@ -495,28 +611,41 @@ static int ehci_hub_control ( | |||
495 | } | 611 | } |
496 | 612 | ||
497 | /* see what we found out */ | 613 | /* see what we found out */ |
498 | temp = check_reset_complete (ehci, wIndex, | 614 | temp = check_reset_complete (ehci, wIndex, status_reg, |
499 | readl (&ehci->regs->port_status [wIndex])); | 615 | ehci_readl(ehci, status_reg)); |
500 | } | 616 | } |
501 | 617 | ||
502 | // don't show wPortStatus if it's owned by a companion hc | 618 | /* transfer dedicated ports to the companion hc */ |
503 | if (!(temp & PORT_OWNER)) { | 619 | if ((temp & PORT_CONNECT) && |
504 | if (temp & PORT_CONNECT) { | 620 | test_bit(wIndex, &ehci->companion_ports)) { |
505 | status |= 1 << USB_PORT_FEAT_CONNECTION; | 621 | temp &= ~PORT_RWC_BITS; |
506 | // status may be from integrated TT | 622 | temp |= PORT_OWNER; |
507 | status |= ehci_port_speed(ehci, temp); | 623 | ehci_writel(ehci, temp, status_reg); |
508 | } | 624 | ehci_dbg(ehci, "port %d --> companion\n", wIndex + 1); |
509 | if (temp & PORT_PE) | 625 | temp = ehci_readl(ehci, status_reg); |
510 | status |= 1 << USB_PORT_FEAT_ENABLE; | 626 | } |
511 | if (temp & (PORT_SUSPEND|PORT_RESUME)) | 627 | |
512 | status |= 1 << USB_PORT_FEAT_SUSPEND; | 628 | /* |
513 | if (temp & PORT_OC) | 629 | * Even if OWNER is set, there's no harm letting khubd |
514 | status |= 1 << USB_PORT_FEAT_OVER_CURRENT; | 630 | * see the wPortStatus values (they should all be 0 except |
515 | if (temp & PORT_RESET) | 631 | * for PORT_POWER anyway). |
516 | status |= 1 << USB_PORT_FEAT_RESET; | 632 | */ |
517 | if (temp & PORT_POWER) | 633 | |
518 | status |= 1 << USB_PORT_FEAT_POWER; | 634 | if (temp & PORT_CONNECT) { |
635 | status |= 1 << USB_PORT_FEAT_CONNECTION; | ||
636 | // status may be from integrated TT | ||
637 | status |= ehci_port_speed(ehci, temp); | ||
519 | } | 638 | } |
639 | if (temp & PORT_PE) | ||
640 | status |= 1 << USB_PORT_FEAT_ENABLE; | ||
641 | if (temp & (PORT_SUSPEND|PORT_RESUME)) | ||
642 | status |= 1 << USB_PORT_FEAT_SUSPEND; | ||
643 | if (temp & PORT_OC) | ||
644 | status |= 1 << USB_PORT_FEAT_OVER_CURRENT; | ||
645 | if (temp & PORT_RESET) | ||
646 | status |= 1 << USB_PORT_FEAT_RESET; | ||
647 | if (temp & PORT_POWER) | ||
648 | status |= 1 << USB_PORT_FEAT_POWER; | ||
520 | 649 | ||
521 | #ifndef EHCI_VERBOSE_DEBUG | 650 | #ifndef EHCI_VERBOSE_DEBUG |
522 | if (status & ~0xffff) /* only if wPortChange is interesting */ | 651 | if (status & ~0xffff) /* only if wPortChange is interesting */ |
@@ -541,7 +670,7 @@ static int ehci_hub_control ( | |||
541 | if (!wIndex || wIndex > ports) | 670 | if (!wIndex || wIndex > ports) |
542 | goto error; | 671 | goto error; |
543 | wIndex--; | 672 | wIndex--; |
544 | temp = readl (&ehci->regs->port_status [wIndex]); | 673 | temp = ehci_readl(ehci, status_reg); |
545 | if (temp & PORT_OWNER) | 674 | if (temp & PORT_OWNER) |
546 | break; | 675 | break; |
547 | 676 | ||
@@ -555,13 +684,12 @@ static int ehci_hub_control ( | |||
555 | goto error; | 684 | goto error; |
556 | if (device_may_wakeup(&hcd->self.root_hub->dev)) | 685 | if (device_may_wakeup(&hcd->self.root_hub->dev)) |
557 | temp |= PORT_WAKE_BITS; | 686 | temp |= PORT_WAKE_BITS; |
558 | writel (temp | PORT_SUSPEND, | 687 | ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); |
559 | &ehci->regs->port_status [wIndex]); | ||
560 | break; | 688 | break; |
561 | case USB_PORT_FEAT_POWER: | 689 | case USB_PORT_FEAT_POWER: |
562 | if (HCS_PPC (ehci->hcs_params)) | 690 | if (HCS_PPC (ehci->hcs_params)) |
563 | writel (temp | PORT_POWER, | 691 | ehci_writel(ehci, temp | PORT_POWER, |
564 | &ehci->regs->port_status [wIndex]); | 692 | status_reg); |
565 | break; | 693 | break; |
566 | case USB_PORT_FEAT_RESET: | 694 | case USB_PORT_FEAT_RESET: |
567 | if (temp & PORT_RESUME) | 695 | if (temp & PORT_RESUME) |
@@ -589,7 +717,7 @@ static int ehci_hub_control ( | |||
589 | ehci->reset_done [wIndex] = jiffies | 717 | ehci->reset_done [wIndex] = jiffies |
590 | + msecs_to_jiffies (50); | 718 | + msecs_to_jiffies (50); |
591 | } | 719 | } |
592 | writel (temp, &ehci->regs->port_status [wIndex]); | 720 | ehci_writel(ehci, temp, status_reg); |
593 | break; | 721 | break; |
594 | 722 | ||
595 | /* For downstream facing ports (these): one hub port is put | 723 | /* For downstream facing ports (these): one hub port is put |
@@ -604,13 +732,13 @@ static int ehci_hub_control ( | |||
604 | ehci_quiesce(ehci); | 732 | ehci_quiesce(ehci); |
605 | ehci_halt(ehci); | 733 | ehci_halt(ehci); |
606 | temp |= selector << 16; | 734 | temp |= selector << 16; |
607 | writel (temp, &ehci->regs->port_status [wIndex]); | 735 | ehci_writel(ehci, temp, status_reg); |
608 | break; | 736 | break; |
609 | 737 | ||
610 | default: | 738 | default: |
611 | goto error; | 739 | goto error; |
612 | } | 740 | } |
613 | readl (&ehci->regs->command); /* unblock posted writes */ | 741 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ |
614 | break; | 742 | break; |
615 | 743 | ||
616 | default: | 744 | default: |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 4bc7970ba3ef..12edc723ec73 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -38,7 +38,7 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) | |||
38 | if ((temp & (3 << 13)) == (1 << 13)) { | 38 | if ((temp & (3 << 13)) == (1 << 13)) { |
39 | temp &= 0x1fff; | 39 | temp &= 0x1fff; |
40 | ehci->debug = ehci_to_hcd(ehci)->regs + temp; | 40 | ehci->debug = ehci_to_hcd(ehci)->regs + temp; |
41 | temp = readl(&ehci->debug->control); | 41 | temp = ehci_readl(ehci, &ehci->debug->control); |
42 | ehci_info(ehci, "debug port %d%s\n", | 42 | ehci_info(ehci, "debug port %d%s\n", |
43 | HCS_DEBUG_PORT(ehci->hcs_params), | 43 | HCS_DEBUG_PORT(ehci->hcs_params), |
44 | (temp & DBGP_ENABLED) | 44 | (temp & DBGP_ENABLED) |
@@ -71,8 +71,24 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
71 | u32 temp; | 71 | u32 temp; |
72 | int retval; | 72 | int retval; |
73 | 73 | ||
74 | switch (pdev->vendor) { | ||
75 | case PCI_VENDOR_ID_TOSHIBA_2: | ||
76 | /* celleb's companion chip */ | ||
77 | if (pdev->device == 0x01b5) { | ||
78 | #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | ||
79 | ehci->big_endian_mmio = 1; | ||
80 | #else | ||
81 | ehci_warn(ehci, | ||
82 | "unsupported big endian Toshiba quirk\n"); | ||
83 | #endif | ||
84 | } | ||
85 | break; | ||
86 | } | ||
87 | |||
74 | ehci->caps = hcd->regs; | 88 | ehci->caps = hcd->regs; |
75 | ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase)); | 89 | ehci->regs = hcd->regs + |
90 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
91 | |||
76 | dbg_hcs_params(ehci, "reset"); | 92 | dbg_hcs_params(ehci, "reset"); |
77 | dbg_hcc_params(ehci, "reset"); | 93 | dbg_hcc_params(ehci, "reset"); |
78 | 94 | ||
@@ -101,7 +117,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
101 | } | 117 | } |
102 | 118 | ||
103 | /* cache this readonly data; minimize chip reads */ | 119 | /* cache this readonly data; minimize chip reads */ |
104 | ehci->hcs_params = readl(&ehci->caps->hcs_params); | 120 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
105 | 121 | ||
106 | retval = ehci_halt(ehci); | 122 | retval = ehci_halt(ehci); |
107 | if (retval) | 123 | if (retval) |
@@ -235,8 +251,8 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message) | |||
235 | rc = -EINVAL; | 251 | rc = -EINVAL; |
236 | goto bail; | 252 | goto bail; |
237 | } | 253 | } |
238 | writel (0, &ehci->regs->intr_enable); | 254 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
239 | (void)readl(&ehci->regs->intr_enable); | 255 | (void)ehci_readl(ehci, &ehci->regs->intr_enable); |
240 | 256 | ||
241 | /* make sure snapshot being resumed re-enumerates everything */ | 257 | /* make sure snapshot being resumed re-enumerates everything */ |
242 | if (message.event == PM_EVENT_PRETHAW) { | 258 | if (message.event == PM_EVENT_PRETHAW) { |
@@ -270,13 +286,13 @@ static int ehci_pci_resume(struct usb_hcd *hcd) | |||
270 | /* If CF is still set, we maintained PCI Vaux power. | 286 | /* If CF is still set, we maintained PCI Vaux power. |
271 | * Just undo the effect of ehci_pci_suspend(). | 287 | * Just undo the effect of ehci_pci_suspend(). |
272 | */ | 288 | */ |
273 | if (readl(&ehci->regs->configured_flag) == FLAG_CF) { | 289 | if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { |
274 | int mask = INTR_MASK; | 290 | int mask = INTR_MASK; |
275 | 291 | ||
276 | if (!device_may_wakeup(&hcd->self.root_hub->dev)) | 292 | if (!device_may_wakeup(&hcd->self.root_hub->dev)) |
277 | mask &= ~STS_PCD; | 293 | mask &= ~STS_PCD; |
278 | writel(mask, &ehci->regs->intr_enable); | 294 | ehci_writel(ehci, mask, &ehci->regs->intr_enable); |
279 | readl(&ehci->regs->intr_enable); | 295 | ehci_readl(ehci, &ehci->regs->intr_enable); |
280 | return 0; | 296 | return 0; |
281 | } | 297 | } |
282 | 298 | ||
@@ -300,9 +316,9 @@ static int ehci_pci_resume(struct usb_hcd *hcd) | |||
300 | /* here we "know" root ports should always stay powered */ | 316 | /* here we "know" root ports should always stay powered */ |
301 | ehci_port_power(ehci, 1); | 317 | ehci_port_power(ehci, 1); |
302 | 318 | ||
303 | writel(ehci->command, &ehci->regs->command); | 319 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
304 | writel(FLAG_CF, &ehci->regs->configured_flag); | 320 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); |
305 | readl(&ehci->regs->command); /* unblock posted writes */ | 321 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ |
306 | 322 | ||
307 | hcd->state = HC_STATE_SUSPENDED; | 323 | hcd->state = HC_STATE_SUSPENDED; |
308 | return 0; | 324 | return 0; |
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c new file mode 100644 index 000000000000..4d781a2a9807 --- /dev/null +++ b/drivers/usb/host/ehci-ps3.c | |||
@@ -0,0 +1,193 @@ | |||
1 | /* | ||
2 | * PS3 EHCI Host Controller driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Sony Computer Entertainment Inc. | ||
5 | * Copyright 2006 Sony Corp. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <asm/ps3.h> | ||
22 | |||
23 | static int ps3_ehci_hc_reset(struct usb_hcd *hcd) | ||
24 | { | ||
25 | int result; | ||
26 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
27 | |||
28 | ehci->big_endian_mmio = 1; | ||
29 | |||
30 | ehci->caps = hcd->regs; | ||
31 | ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, | ||
32 | &ehci->caps->hc_capbase)); | ||
33 | |||
34 | dbg_hcs_params(ehci, "reset"); | ||
35 | dbg_hcc_params(ehci, "reset"); | ||
36 | |||
37 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
38 | |||
39 | result = ehci_halt(ehci); | ||
40 | |||
41 | if (result) | ||
42 | return result; | ||
43 | |||
44 | result = ehci_init(hcd); | ||
45 | |||
46 | if (result) | ||
47 | return result; | ||
48 | |||
49 | ehci_port_power(ehci, 0); | ||
50 | |||
51 | return result; | ||
52 | } | ||
53 | |||
54 | static const struct hc_driver ps3_ehci_hc_driver = { | ||
55 | .description = hcd_name, | ||
56 | .product_desc = "PS3 EHCI Host Controller", | ||
57 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
58 | .irq = ehci_irq, | ||
59 | .flags = HCD_MEMORY | HCD_USB2, | ||
60 | .reset = ps3_ehci_hc_reset, | ||
61 | .start = ehci_run, | ||
62 | .stop = ehci_stop, | ||
63 | .shutdown = ehci_shutdown, | ||
64 | .urb_enqueue = ehci_urb_enqueue, | ||
65 | .urb_dequeue = ehci_urb_dequeue, | ||
66 | .endpoint_disable = ehci_endpoint_disable, | ||
67 | .get_frame_number = ehci_get_frame, | ||
68 | .hub_status_data = ehci_hub_status_data, | ||
69 | .hub_control = ehci_hub_control, | ||
70 | #if defined(CONFIG_PM) | ||
71 | .bus_suspend = ehci_bus_suspend, | ||
72 | .bus_resume = ehci_bus_resume, | ||
73 | #endif | ||
74 | }; | ||
75 | |||
76 | #if !defined(DEBUG) | ||
77 | #undef dev_dbg | ||
78 | static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg( | ||
79 | const struct device *_dev, const char *fmt, ...) {return 0;} | ||
80 | #endif | ||
81 | |||
82 | |||
83 | static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev) | ||
84 | { | ||
85 | int result; | ||
86 | struct usb_hcd *hcd; | ||
87 | unsigned int virq; | ||
88 | static u64 dummy_mask = DMA_32BIT_MASK; | ||
89 | |||
90 | if (usb_disabled()) { | ||
91 | result = -ENODEV; | ||
92 | goto fail_start; | ||
93 | } | ||
94 | |||
95 | result = ps3_mmio_region_create(dev->m_region); | ||
96 | |||
97 | if (result) { | ||
98 | dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n", | ||
99 | __func__, __LINE__); | ||
100 | result = -EPERM; | ||
101 | goto fail_mmio; | ||
102 | } | ||
103 | |||
104 | dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, | ||
105 | __LINE__, dev->m_region->lpar_addr); | ||
106 | |||
107 | result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); | ||
108 | |||
109 | if (result) { | ||
110 | dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", | ||
111 | __func__, __LINE__, virq); | ||
112 | result = -EPERM; | ||
113 | goto fail_irq; | ||
114 | } | ||
115 | |||
116 | dev->core.power.power_state = PMSG_ON; | ||
117 | dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */ | ||
118 | |||
119 | hcd = usb_create_hcd(&ps3_ehci_hc_driver, &dev->core, dev->core.bus_id); | ||
120 | |||
121 | if (!hcd) { | ||
122 | dev_dbg(&dev->core, "%s:%d: usb_create_hcd failed\n", __func__, | ||
123 | __LINE__); | ||
124 | result = -ENOMEM; | ||
125 | goto fail_create_hcd; | ||
126 | } | ||
127 | |||
128 | hcd->rsrc_start = dev->m_region->lpar_addr; | ||
129 | hcd->rsrc_len = dev->m_region->len; | ||
130 | hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len); | ||
131 | |||
132 | if (!hcd->regs) { | ||
133 | dev_dbg(&dev->core, "%s:%d: ioremap failed\n", __func__, | ||
134 | __LINE__); | ||
135 | result = -EPERM; | ||
136 | goto fail_ioremap; | ||
137 | } | ||
138 | |||
139 | dev_dbg(&dev->core, "%s:%d: hcd->rsrc_start %lxh\n", __func__, __LINE__, | ||
140 | (unsigned long)hcd->rsrc_start); | ||
141 | dev_dbg(&dev->core, "%s:%d: hcd->rsrc_len %lxh\n", __func__, __LINE__, | ||
142 | (unsigned long)hcd->rsrc_len); | ||
143 | dev_dbg(&dev->core, "%s:%d: hcd->regs %lxh\n", __func__, __LINE__, | ||
144 | (unsigned long)hcd->regs); | ||
145 | dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, | ||
146 | (unsigned long)virq); | ||
147 | |||
148 | ps3_system_bus_set_driver_data(dev, hcd); | ||
149 | |||
150 | result = usb_add_hcd(hcd, virq, IRQF_DISABLED); | ||
151 | |||
152 | if (result) { | ||
153 | dev_dbg(&dev->core, "%s:%d: usb_add_hcd failed (%d)\n", | ||
154 | __func__, __LINE__, result); | ||
155 | goto fail_add_hcd; | ||
156 | } | ||
157 | |||
158 | return result; | ||
159 | |||
160 | fail_add_hcd: | ||
161 | iounmap(hcd->regs); | ||
162 | fail_ioremap: | ||
163 | usb_put_hcd(hcd); | ||
164 | fail_create_hcd: | ||
165 | ps3_free_io_irq(virq); | ||
166 | fail_irq: | ||
167 | ps3_free_mmio_region(dev->m_region); | ||
168 | fail_mmio: | ||
169 | fail_start: | ||
170 | return result; | ||
171 | } | ||
172 | |||
173 | static int ps3_ehci_sb_remove(struct ps3_system_bus_device *dev) | ||
174 | { | ||
175 | struct usb_hcd *hcd = | ||
176 | (struct usb_hcd *)ps3_system_bus_get_driver_data(dev); | ||
177 | |||
178 | usb_put_hcd(hcd); | ||
179 | ps3_system_bus_set_driver_data(dev, NULL); | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | MODULE_ALIAS("ps3-ehci"); | ||
185 | |||
186 | static struct ps3_system_bus_driver ps3_ehci_sb_driver = { | ||
187 | .match_id = PS3_MATCH_ID_EHCI, | ||
188 | .core = { | ||
189 | .name = "ps3-ehci-driver", | ||
190 | }, | ||
191 | .probe = ps3_ehci_sb_probe, | ||
192 | .remove = ps3_ehci_sb_remove, | ||
193 | }; | ||
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 62e46dc60e86..e7fbbd00e7cd 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -789,13 +789,14 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
789 | head = ehci->async; | 789 | head = ehci->async; |
790 | timer_action_done (ehci, TIMER_ASYNC_OFF); | 790 | timer_action_done (ehci, TIMER_ASYNC_OFF); |
791 | if (!head->qh_next.qh) { | 791 | if (!head->qh_next.qh) { |
792 | u32 cmd = readl (&ehci->regs->command); | 792 | u32 cmd = ehci_readl(ehci, &ehci->regs->command); |
793 | 793 | ||
794 | if (!(cmd & CMD_ASE)) { | 794 | if (!(cmd & CMD_ASE)) { |
795 | /* in case a clear of CMD_ASE didn't take yet */ | 795 | /* in case a clear of CMD_ASE didn't take yet */ |
796 | (void) handshake (&ehci->regs->status, STS_ASS, 0, 150); | 796 | (void)handshake(ehci, &ehci->regs->status, |
797 | STS_ASS, 0, 150); | ||
797 | cmd |= CMD_ASE | CMD_RUN; | 798 | cmd |= CMD_ASE | CMD_RUN; |
798 | writel (cmd, &ehci->regs->command); | 799 | ehci_writel(ehci, cmd, &ehci->regs->command); |
799 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; | 800 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; |
800 | /* posted write need not be known to HC yet ... */ | 801 | /* posted write need not be known to HC yet ... */ |
801 | } | 802 | } |
@@ -1007,7 +1008,7 @@ static void end_unlink_async (struct ehci_hcd *ehci) | |||
1007 | 1008 | ||
1008 | static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | 1009 | static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) |
1009 | { | 1010 | { |
1010 | int cmd = readl (&ehci->regs->command); | 1011 | int cmd = ehci_readl(ehci, &ehci->regs->command); |
1011 | struct ehci_qh *prev; | 1012 | struct ehci_qh *prev; |
1012 | 1013 | ||
1013 | #ifdef DEBUG | 1014 | #ifdef DEBUG |
@@ -1025,7 +1026,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
1025 | if (ehci_to_hcd(ehci)->state != HC_STATE_HALT | 1026 | if (ehci_to_hcd(ehci)->state != HC_STATE_HALT |
1026 | && !ehci->reclaim) { | 1027 | && !ehci->reclaim) { |
1027 | /* ... and CMD_IAAD clear */ | 1028 | /* ... and CMD_IAAD clear */ |
1028 | writel (cmd & ~CMD_ASE, &ehci->regs->command); | 1029 | ehci_writel(ehci, cmd & ~CMD_ASE, |
1030 | &ehci->regs->command); | ||
1029 | wmb (); | 1031 | wmb (); |
1030 | // handshake later, if we need to | 1032 | // handshake later, if we need to |
1031 | timer_action_done (ehci, TIMER_ASYNC_OFF); | 1033 | timer_action_done (ehci, TIMER_ASYNC_OFF); |
@@ -1054,8 +1056,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
1054 | 1056 | ||
1055 | ehci->reclaim_ready = 0; | 1057 | ehci->reclaim_ready = 0; |
1056 | cmd |= CMD_IAAD; | 1058 | cmd |= CMD_IAAD; |
1057 | writel (cmd, &ehci->regs->command); | 1059 | ehci_writel(ehci, cmd, &ehci->regs->command); |
1058 | (void) readl (&ehci->regs->command); | 1060 | (void)ehci_readl(ehci, &ehci->regs->command); |
1059 | timer_action (ehci, TIMER_IAA_WATCHDOG); | 1061 | timer_action (ehci, TIMER_IAA_WATCHDOG); |
1060 | } | 1062 | } |
1061 | 1063 | ||
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 65c402a0fa7a..7b5ae7111f23 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -433,20 +433,20 @@ static int enable_periodic (struct ehci_hcd *ehci) | |||
433 | /* did clearing PSE did take effect yet? | 433 | /* did clearing PSE did take effect yet? |
434 | * takes effect only at frame boundaries... | 434 | * takes effect only at frame boundaries... |
435 | */ | 435 | */ |
436 | status = handshake (&ehci->regs->status, STS_PSS, 0, 9 * 125); | 436 | status = handshake(ehci, &ehci->regs->status, STS_PSS, 0, 9 * 125); |
437 | if (status != 0) { | 437 | if (status != 0) { |
438 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 438 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; |
439 | return status; | 439 | return status; |
440 | } | 440 | } |
441 | 441 | ||
442 | cmd = readl (&ehci->regs->command) | CMD_PSE; | 442 | cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE; |
443 | writel (cmd, &ehci->regs->command); | 443 | ehci_writel(ehci, cmd, &ehci->regs->command); |
444 | /* posted write ... PSS happens later */ | 444 | /* posted write ... PSS happens later */ |
445 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; | 445 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; |
446 | 446 | ||
447 | /* make sure ehci_work scans these */ | 447 | /* make sure ehci_work scans these */ |
448 | ehci->next_uframe = readl (&ehci->regs->frame_index) | 448 | ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index) |
449 | % (ehci->periodic_size << 3); | 449 | % (ehci->periodic_size << 3); |
450 | return 0; | 450 | return 0; |
451 | } | 451 | } |
452 | 452 | ||
@@ -458,14 +458,14 @@ static int disable_periodic (struct ehci_hcd *ehci) | |||
458 | /* did setting PSE not take effect yet? | 458 | /* did setting PSE not take effect yet? |
459 | * takes effect only at frame boundaries... | 459 | * takes effect only at frame boundaries... |
460 | */ | 460 | */ |
461 | status = handshake (&ehci->regs->status, STS_PSS, STS_PSS, 9 * 125); | 461 | status = handshake(ehci, &ehci->regs->status, STS_PSS, STS_PSS, 9 * 125); |
462 | if (status != 0) { | 462 | if (status != 0) { |
463 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 463 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; |
464 | return status; | 464 | return status; |
465 | } | 465 | } |
466 | 466 | ||
467 | cmd = readl (&ehci->regs->command) & ~CMD_PSE; | 467 | cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE; |
468 | writel (cmd, &ehci->regs->command); | 468 | ehci_writel(ehci, cmd, &ehci->regs->command); |
469 | /* posted write ... */ | 469 | /* posted write ... */ |
470 | 470 | ||
471 | ehci->next_uframe = -1; | 471 | ehci->next_uframe = -1; |
@@ -1336,7 +1336,7 @@ iso_stream_schedule ( | |||
1336 | goto fail; | 1336 | goto fail; |
1337 | } | 1337 | } |
1338 | 1338 | ||
1339 | now = readl (&ehci->regs->frame_index) % mod; | 1339 | now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; |
1340 | 1340 | ||
1341 | /* when's the last uframe this urb could start? */ | 1341 | /* when's the last uframe this urb could start? */ |
1342 | max = now + mod; | 1342 | max = now + mod; |
@@ -2088,7 +2088,7 @@ scan_periodic (struct ehci_hcd *ehci) | |||
2088 | */ | 2088 | */ |
2089 | now_uframe = ehci->next_uframe; | 2089 | now_uframe = ehci->next_uframe; |
2090 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) | 2090 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) |
2091 | clock = readl (&ehci->regs->frame_index); | 2091 | clock = ehci_readl(ehci, &ehci->regs->frame_index); |
2092 | else | 2092 | else |
2093 | clock = now_uframe + mod - 1; | 2093 | clock = now_uframe + mod - 1; |
2094 | clock %= mod; | 2094 | clock %= mod; |
@@ -2213,7 +2213,7 @@ restart: | |||
2213 | if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) | 2213 | if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) |
2214 | break; | 2214 | break; |
2215 | ehci->next_uframe = now_uframe; | 2215 | ehci->next_uframe = now_uframe; |
2216 | now = readl (&ehci->regs->frame_index) % mod; | 2216 | now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; |
2217 | if (now_uframe == now) | 2217 | if (now_uframe == now) |
2218 | break; | 2218 | break; |
2219 | 2219 | ||
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 74dbc6c8228f..46fa57a520d0 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -74,7 +74,11 @@ struct ehci_hcd { /* one per controller */ | |||
74 | 74 | ||
75 | /* per root hub port */ | 75 | /* per root hub port */ |
76 | unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; | 76 | unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; |
77 | unsigned long bus_suspended; | 77 | /* bit vectors (one bit per port) */ |
78 | unsigned long bus_suspended; /* which ports were | ||
79 | already suspended at the start of a bus suspend */ | ||
80 | unsigned long companion_ports; /* which ports are | ||
81 | dedicated to the companion controller */ | ||
78 | 82 | ||
79 | /* per-HC memory pools (could be per-bus, but ...) */ | 83 | /* per-HC memory pools (could be per-bus, but ...) */ |
80 | struct dma_pool *qh_pool; /* qh per active urb */ | 84 | struct dma_pool *qh_pool; /* qh per active urb */ |
@@ -92,6 +96,7 @@ struct ehci_hcd { /* one per controller */ | |||
92 | unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */ | 96 | unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */ |
93 | unsigned no_selective_suspend:1; | 97 | unsigned no_selective_suspend:1; |
94 | unsigned has_fsl_port_bug:1; /* FreeScale */ | 98 | unsigned has_fsl_port_bug:1; /* FreeScale */ |
99 | unsigned big_endian_mmio:1; | ||
95 | 100 | ||
96 | u8 sbrn; /* packed release number */ | 101 | u8 sbrn; /* packed release number */ |
97 | 102 | ||
@@ -651,6 +656,45 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) | |||
651 | #define ehci_has_fsl_portno_bug(e) (0) | 656 | #define ehci_has_fsl_portno_bug(e) (0) |
652 | #endif | 657 | #endif |
653 | 658 | ||
659 | /* | ||
660 | * While most USB host controllers implement their registers in | ||
661 | * little-endian format, a minority (celleb companion chip) implement | ||
662 | * them in big endian format. | ||
663 | * | ||
664 | * This attempts to support either format at compile time without a | ||
665 | * runtime penalty, or both formats with the additional overhead | ||
666 | * of checking a flag bit. | ||
667 | */ | ||
668 | |||
669 | #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | ||
670 | #define ehci_big_endian_mmio(e) ((e)->big_endian_mmio) | ||
671 | #else | ||
672 | #define ehci_big_endian_mmio(e) 0 | ||
673 | #endif | ||
674 | |||
675 | static inline unsigned int ehci_readl (const struct ehci_hcd *ehci, | ||
676 | __u32 __iomem * regs) | ||
677 | { | ||
678 | #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | ||
679 | return ehci_big_endian_mmio(ehci) ? | ||
680 | readl_be(regs) : | ||
681 | readl(regs); | ||
682 | #else | ||
683 | return readl(regs); | ||
684 | #endif | ||
685 | } | ||
686 | |||
687 | static inline void ehci_writel (const struct ehci_hcd *ehci, | ||
688 | const unsigned int val, __u32 __iomem *regs) | ||
689 | { | ||
690 | #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | ||
691 | ehci_big_endian_mmio(ehci) ? | ||
692 | writel_be(val, regs) : | ||
693 | writel(val, regs); | ||
694 | #else | ||
695 | writel(val, regs); | ||
696 | #endif | ||
697 | } | ||
654 | 698 | ||
655 | /*-------------------------------------------------------------------------*/ | 699 | /*-------------------------------------------------------------------------*/ |
656 | 700 | ||
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index cc405512fa1c..930346487278 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -170,7 +170,6 @@ static int usb_hcd_at91_remove(struct usb_hcd *hcd, | |||
170 | at91_stop_hc(pdev); | 170 | at91_stop_hc(pdev); |
171 | iounmap(hcd->regs); | 171 | iounmap(hcd->regs); |
172 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 172 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
173 | disable_irq_wake(hcd->irq); | ||
174 | 173 | ||
175 | clk_put(fclk); | 174 | clk_put(fclk); |
176 | clk_put(iclk); | 175 | clk_put(iclk); |
@@ -271,8 +270,6 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
271 | 270 | ||
272 | if (device_may_wakeup(&pdev->dev)) | 271 | if (device_may_wakeup(&pdev->dev)) |
273 | enable_irq_wake(hcd->irq); | 272 | enable_irq_wake(hcd->irq); |
274 | else | ||
275 | disable_irq_wake(hcd->irq); | ||
276 | 273 | ||
277 | /* | 274 | /* |
278 | * The integrated transceivers seem unable to notice disconnect, | 275 | * The integrated transceivers seem unable to notice disconnect, |
@@ -293,6 +290,11 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
293 | 290 | ||
294 | static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) | 291 | static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) |
295 | { | 292 | { |
293 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
294 | |||
295 | if (device_may_wakeup(&pdev->dev)) | ||
296 | disable_irq_wake(hcd->irq); | ||
297 | |||
296 | if (!clocked) { | 298 | if (!clocked) { |
297 | clk_enable(iclk); | 299 | clk_enable(iclk); |
298 | clk_enable(fclk); | 300 | clk_enable(fclk); |
@@ -320,18 +322,3 @@ static struct platform_driver ohci_hcd_at91_driver = { | |||
320 | }, | 322 | }, |
321 | }; | 323 | }; |
322 | 324 | ||
323 | static int __init ohci_hcd_at91_init (void) | ||
324 | { | ||
325 | if (usb_disabled()) | ||
326 | return -ENODEV; | ||
327 | |||
328 | return platform_driver_register(&ohci_hcd_at91_driver); | ||
329 | } | ||
330 | |||
331 | static void __exit ohci_hcd_at91_cleanup (void) | ||
332 | { | ||
333 | platform_driver_unregister(&ohci_hcd_at91_driver); | ||
334 | } | ||
335 | |||
336 | module_init (ohci_hcd_at91_init); | ||
337 | module_exit (ohci_hcd_at91_cleanup); | ||
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index e70b2430e2a9..663a0600b6e7 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c | |||
@@ -345,19 +345,3 @@ static struct platform_driver ohci_hcd_au1xxx_driver = { | |||
345 | }, | 345 | }, |
346 | }; | 346 | }; |
347 | 347 | ||
348 | static int __init ohci_hcd_au1xxx_init (void) | ||
349 | { | ||
350 | pr_debug (DRIVER_INFO " (Au1xxx)"); | ||
351 | pr_debug ("block sizes: ed %d td %d\n", | ||
352 | sizeof (struct ed), sizeof (struct td)); | ||
353 | |||
354 | return platform_driver_register(&ohci_hcd_au1xxx_driver); | ||
355 | } | ||
356 | |||
357 | static void __exit ohci_hcd_au1xxx_cleanup (void) | ||
358 | { | ||
359 | platform_driver_unregister(&ohci_hcd_au1xxx_driver); | ||
360 | } | ||
361 | |||
362 | module_init (ohci_hcd_au1xxx_init); | ||
363 | module_exit (ohci_hcd_au1xxx_cleanup); | ||
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index 3348b07f0fe5..44c60fba76e1 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c | |||
@@ -214,15 +214,3 @@ static struct platform_driver ohci_hcd_ep93xx_driver = { | |||
214 | }, | 214 | }, |
215 | }; | 215 | }; |
216 | 216 | ||
217 | static int __init ohci_hcd_ep93xx_init(void) | ||
218 | { | ||
219 | return platform_driver_register(&ohci_hcd_ep93xx_driver); | ||
220 | } | ||
221 | |||
222 | static void __exit ohci_hcd_ep93xx_cleanup(void) | ||
223 | { | ||
224 | platform_driver_unregister(&ohci_hcd_ep93xx_driver); | ||
225 | } | ||
226 | |||
227 | module_init(ohci_hcd_ep93xx_init); | ||
228 | module_exit(ohci_hcd_ep93xx_cleanup); | ||
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index c1c1d871aba4..fa6a7ceaa0db 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -855,63 +855,167 @@ MODULE_LICENSE ("GPL"); | |||
855 | 855 | ||
856 | #ifdef CONFIG_PCI | 856 | #ifdef CONFIG_PCI |
857 | #include "ohci-pci.c" | 857 | #include "ohci-pci.c" |
858 | #define PCI_DRIVER ohci_pci_driver | ||
858 | #endif | 859 | #endif |
859 | 860 | ||
860 | #ifdef CONFIG_SA1111 | 861 | #ifdef CONFIG_SA1111 |
861 | #include "ohci-sa1111.c" | 862 | #include "ohci-sa1111.c" |
863 | #define SA1111_DRIVER ohci_hcd_sa1111_driver | ||
862 | #endif | 864 | #endif |
863 | 865 | ||
864 | #ifdef CONFIG_ARCH_S3C2410 | 866 | #ifdef CONFIG_ARCH_S3C2410 |
865 | #include "ohci-s3c2410.c" | 867 | #include "ohci-s3c2410.c" |
868 | #define PLATFORM_DRIVER ohci_hcd_s3c2410_driver | ||
866 | #endif | 869 | #endif |
867 | 870 | ||
868 | #ifdef CONFIG_ARCH_OMAP | 871 | #ifdef CONFIG_ARCH_OMAP |
869 | #include "ohci-omap.c" | 872 | #include "ohci-omap.c" |
873 | #define PLATFORM_DRIVER ohci_hcd_omap_driver | ||
870 | #endif | 874 | #endif |
871 | 875 | ||
872 | #ifdef CONFIG_ARCH_LH7A404 | 876 | #ifdef CONFIG_ARCH_LH7A404 |
873 | #include "ohci-lh7a404.c" | 877 | #include "ohci-lh7a404.c" |
878 | #define PLATFORM_DRIVER ohci_hcd_lh7a404_driver | ||
874 | #endif | 879 | #endif |
875 | 880 | ||
876 | #ifdef CONFIG_PXA27x | 881 | #ifdef CONFIG_PXA27x |
877 | #include "ohci-pxa27x.c" | 882 | #include "ohci-pxa27x.c" |
883 | #define PLATFORM_DRIVER ohci_hcd_pxa27x_driver | ||
878 | #endif | 884 | #endif |
879 | 885 | ||
880 | #ifdef CONFIG_ARCH_EP93XX | 886 | #ifdef CONFIG_ARCH_EP93XX |
881 | #include "ohci-ep93xx.c" | 887 | #include "ohci-ep93xx.c" |
888 | #define PLATFORM_DRIVER ohci_hcd_ep93xx_driver | ||
882 | #endif | 889 | #endif |
883 | 890 | ||
884 | #ifdef CONFIG_SOC_AU1X00 | 891 | #ifdef CONFIG_SOC_AU1X00 |
885 | #include "ohci-au1xxx.c" | 892 | #include "ohci-au1xxx.c" |
893 | #define PLATFORM_DRIVER ohci_hcd_au1xxx_driver | ||
886 | #endif | 894 | #endif |
887 | 895 | ||
888 | #ifdef CONFIG_PNX8550 | 896 | #ifdef CONFIG_PNX8550 |
889 | #include "ohci-pnx8550.c" | 897 | #include "ohci-pnx8550.c" |
898 | #define PLATFORM_DRIVER ohci_hcd_pnx8550_driver | ||
890 | #endif | 899 | #endif |
891 | 900 | ||
892 | #ifdef CONFIG_USB_OHCI_HCD_PPC_SOC | 901 | #ifdef CONFIG_USB_OHCI_HCD_PPC_SOC |
893 | #include "ohci-ppc-soc.c" | 902 | #include "ohci-ppc-soc.c" |
903 | #define PLATFORM_DRIVER ohci_hcd_ppc_soc_driver | ||
894 | #endif | 904 | #endif |
895 | 905 | ||
896 | #ifdef CONFIG_ARCH_AT91 | 906 | #ifdef CONFIG_ARCH_AT91 |
897 | #include "ohci-at91.c" | 907 | #include "ohci-at91.c" |
908 | #define PLATFORM_DRIVER ohci_hcd_at91_driver | ||
898 | #endif | 909 | #endif |
899 | 910 | ||
900 | #ifdef CONFIG_ARCH_PNX4008 | 911 | #ifdef CONFIG_ARCH_PNX4008 |
901 | #include "ohci-pnx4008.c" | 912 | #include "ohci-pnx4008.c" |
913 | #define PLATFORM_DRIVER usb_hcd_pnx4008_driver | ||
902 | #endif | 914 | #endif |
903 | 915 | ||
904 | #if !(defined(CONFIG_PCI) \ | 916 | |
905 | || defined(CONFIG_SA1111) \ | 917 | #ifdef CONFIG_USB_OHCI_HCD_PPC_OF |
906 | || defined(CONFIG_ARCH_S3C2410) \ | 918 | #include "ohci-ppc-of.c" |
907 | || defined(CONFIG_ARCH_OMAP) \ | 919 | #define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver |
908 | || defined (CONFIG_ARCH_LH7A404) \ | 920 | #endif |
909 | || defined (CONFIG_PXA27x) \ | 921 | |
910 | || defined (CONFIG_ARCH_EP93XX) \ | 922 | #ifdef CONFIG_PPC_PS3 |
911 | || defined (CONFIG_SOC_AU1X00) \ | 923 | #include "ohci-ps3.c" |
912 | || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \ | 924 | #define PS3_SYSTEM_BUS_DRIVER ps3_ohci_sb_driver |
913 | || defined (CONFIG_ARCH_AT91) \ | 925 | #endif |
914 | || defined (CONFIG_ARCH_PNX4008) \ | 926 | |
915 | ) | 927 | #if !defined(PCI_DRIVER) && \ |
928 | !defined(PLATFORM_DRIVER) && \ | ||
929 | !defined(OF_PLATFORM_DRIVER) && \ | ||
930 | !defined(SA1111_DRIVER) && \ | ||
931 | !defined(PS3_SYSTEM_BUS_DRIVER) | ||
916 | #error "missing bus glue for ohci-hcd" | 932 | #error "missing bus glue for ohci-hcd" |
917 | #endif | 933 | #endif |
934 | |||
935 | static int __init ohci_hcd_mod_init(void) | ||
936 | { | ||
937 | int retval = 0; | ||
938 | |||
939 | if (usb_disabled()) | ||
940 | return -ENODEV; | ||
941 | |||
942 | printk (KERN_DEBUG "%s: " DRIVER_INFO "\n", hcd_name); | ||
943 | pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, | ||
944 | sizeof (struct ed), sizeof (struct td)); | ||
945 | |||
946 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
947 | retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER); | ||
948 | if (retval < 0) | ||
949 | goto error_ps3; | ||
950 | #endif | ||
951 | |||
952 | #ifdef PLATFORM_DRIVER | ||
953 | retval = platform_driver_register(&PLATFORM_DRIVER); | ||
954 | if (retval < 0) | ||
955 | goto error_platform; | ||
956 | #endif | ||
957 | |||
958 | #ifdef OF_PLATFORM_DRIVER | ||
959 | retval = of_register_platform_driver(&OF_PLATFORM_DRIVER); | ||
960 | if (retval < 0) | ||
961 | goto error_of_platform; | ||
962 | #endif | ||
963 | |||
964 | #ifdef SA1111_DRIVER | ||
965 | retval = sa1111_driver_register(&SA1111_DRIVER); | ||
966 | if (retval < 0) | ||
967 | goto error_sa1111; | ||
968 | #endif | ||
969 | |||
970 | #ifdef PCI_DRIVER | ||
971 | retval = pci_register_driver(&PCI_DRIVER); | ||
972 | if (retval < 0) | ||
973 | goto error_pci; | ||
974 | #endif | ||
975 | |||
976 | return retval; | ||
977 | |||
978 | /* Error path */ | ||
979 | #ifdef PCI_DRIVER | ||
980 | error_pci: | ||
981 | #endif | ||
982 | #ifdef SA1111_DRIVER | ||
983 | sa1111_driver_unregister(&SA1111_DRIVER); | ||
984 | error_sa1111: | ||
985 | #endif | ||
986 | #ifdef OF_PLATFORM_DRIVER | ||
987 | of_unregister_platform_driver(&OF_PLATFORM_DRIVER); | ||
988 | error_of_platform: | ||
989 | #endif | ||
990 | #ifdef PLATFORM_DRIVER | ||
991 | platform_driver_unregister(&PLATFORM_DRIVER); | ||
992 | error_platform: | ||
993 | #endif | ||
994 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
995 | ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | ||
996 | error_ps3: | ||
997 | #endif | ||
998 | return retval; | ||
999 | } | ||
1000 | module_init(ohci_hcd_mod_init); | ||
1001 | |||
1002 | static void __exit ohci_hcd_mod_exit(void) | ||
1003 | { | ||
1004 | #ifdef PCI_DRIVER | ||
1005 | pci_unregister_driver(&PCI_DRIVER); | ||
1006 | #endif | ||
1007 | #ifdef SA1111_DRIVER | ||
1008 | sa1111_driver_unregister(&SA1111_DRIVER); | ||
1009 | #endif | ||
1010 | #ifdef OF_PLATFORM_DRIVER | ||
1011 | of_unregister_platform_driver(&OF_PLATFORM_DRIVER); | ||
1012 | #endif | ||
1013 | #ifdef PLATFORM_DRIVER | ||
1014 | platform_driver_unregister(&PLATFORM_DRIVER); | ||
1015 | #endif | ||
1016 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
1017 | ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | ||
1018 | #endif | ||
1019 | } | ||
1020 | module_exit(ohci_hcd_mod_exit); | ||
1021 | |||
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index e9807cf73a2f..4a043abd85ea 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c | |||
@@ -251,19 +251,3 @@ static struct platform_driver ohci_hcd_lh7a404_driver = { | |||
251 | }, | 251 | }, |
252 | }; | 252 | }; |
253 | 253 | ||
254 | static int __init ohci_hcd_lh7a404_init (void) | ||
255 | { | ||
256 | pr_debug (DRIVER_INFO " (LH7A404)"); | ||
257 | pr_debug ("block sizes: ed %d td %d\n", | ||
258 | sizeof (struct ed), sizeof (struct td)); | ||
259 | |||
260 | return platform_driver_register(&ohci_hcd_lh7a404_driver); | ||
261 | } | ||
262 | |||
263 | static void __exit ohci_hcd_lh7a404_cleanup (void) | ||
264 | { | ||
265 | platform_driver_unregister(&ohci_hcd_lh7a404_driver); | ||
266 | } | ||
267 | |||
268 | module_init (ohci_hcd_lh7a404_init); | ||
269 | module_exit (ohci_hcd_lh7a404_cleanup); | ||
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 27be1f936885..5cfa3d1c4413 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -544,22 +544,3 @@ static struct platform_driver ohci_hcd_omap_driver = { | |||
544 | }, | 544 | }, |
545 | }; | 545 | }; |
546 | 546 | ||
547 | static int __init ohci_hcd_omap_init (void) | ||
548 | { | ||
549 | printk (KERN_DEBUG "%s: " DRIVER_INFO " (OMAP)\n", hcd_name); | ||
550 | if (usb_disabled()) | ||
551 | return -ENODEV; | ||
552 | |||
553 | pr_debug("%s: block sizes: ed %Zd td %Zd\n", hcd_name, | ||
554 | sizeof (struct ed), sizeof (struct td)); | ||
555 | |||
556 | return platform_driver_register(&ohci_hcd_omap_driver); | ||
557 | } | ||
558 | |||
559 | static void __exit ohci_hcd_omap_cleanup (void) | ||
560 | { | ||
561 | platform_driver_unregister(&ohci_hcd_omap_driver); | ||
562 | } | ||
563 | |||
564 | module_init (ohci_hcd_omap_init); | ||
565 | module_exit (ohci_hcd_omap_cleanup); | ||
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 596e0b41e606..b331ac4d0d62 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -20,79 +20,154 @@ | |||
20 | 20 | ||
21 | /*-------------------------------------------------------------------------*/ | 21 | /*-------------------------------------------------------------------------*/ |
22 | 22 | ||
23 | static int | 23 | /* AMD 756, for most chips (early revs), corrupts register |
24 | ohci_pci_reset (struct usb_hcd *hcd) | 24 | * values on read ... so enable the vendor workaround. |
25 | */ | ||
26 | static int __devinit ohci_quirk_amd756(struct usb_hcd *hcd) | ||
25 | { | 27 | { |
26 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 28 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
27 | 29 | ||
28 | ohci_hcd_init (ohci); | 30 | ohci->flags = OHCI_QUIRK_AMD756; |
29 | return ohci_init (ohci); | 31 | ohci_dbg (ohci, "AMD756 erratum 4 workaround\n"); |
32 | |||
33 | /* also erratum 10 (suspend/resume issues) */ | ||
34 | device_init_wakeup(&hcd->self.root_hub->dev, 0); | ||
35 | |||
36 | return 0; | ||
30 | } | 37 | } |
31 | 38 | ||
32 | static int __devinit | 39 | /* Apple's OHCI driver has a lot of bizarre workarounds |
33 | ohci_pci_start (struct usb_hcd *hcd) | 40 | * for this chip. Evidently control and bulk lists |
41 | * can get confused. (B&W G3 models, and ...) | ||
42 | */ | ||
43 | static int __devinit ohci_quirk_opti(struct usb_hcd *hcd) | ||
34 | { | 44 | { |
35 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 45 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
36 | int ret; | ||
37 | 46 | ||
38 | /* REVISIT this whole block should move to reset(), which handles | 47 | ohci_dbg (ohci, "WARNING: OPTi workarounds unavailable\n"); |
39 | * all the other one-time init. | 48 | |
49 | return 0; | ||
50 | } | ||
51 | |||
52 | /* Check for NSC87560. We have to look at the bridge (fn1) to | ||
53 | * identify the USB (fn2). This quirk might apply to more or | ||
54 | * even all NSC stuff. | ||
55 | */ | ||
56 | static int __devinit ohci_quirk_ns(struct usb_hcd *hcd) | ||
57 | { | ||
58 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | ||
59 | struct pci_dev *b; | ||
60 | |||
61 | b = pci_get_slot (pdev->bus, PCI_DEVFN (PCI_SLOT (pdev->devfn), 1)); | ||
62 | if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO | ||
63 | && b->vendor == PCI_VENDOR_ID_NS) { | ||
64 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
65 | |||
66 | ohci->flags |= OHCI_QUIRK_SUPERIO; | ||
67 | ohci_dbg (ohci, "Using NSC SuperIO setup\n"); | ||
68 | } | ||
69 | pci_dev_put(b); | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | /* Check for Compaq's ZFMicro chipset, which needs short | ||
75 | * delays before control or bulk queues get re-activated | ||
76 | * in finish_unlinks() | ||
77 | */ | ||
78 | static int __devinit ohci_quirk_zfmicro(struct usb_hcd *hcd) | ||
79 | { | ||
80 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
81 | |||
82 | ohci->flags |= OHCI_QUIRK_ZFMICRO; | ||
83 | ohci_dbg (ohci, "enabled Compaq ZFMicro chipset quirk\n"); | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | /* Check for Toshiba SCC OHCI which has big endian registers | ||
89 | * and little endian in memory data structures | ||
90 | */ | ||
91 | static int __devinit ohci_quirk_toshiba_scc(struct usb_hcd *hcd) | ||
92 | { | ||
93 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
94 | |||
95 | /* That chip is only present in the southbridge of some | ||
96 | * cell based platforms which are supposed to select | ||
97 | * CONFIG_USB_OHCI_BIG_ENDIAN_MMIO. We verify here if | ||
98 | * that was the case though. | ||
99 | */ | ||
100 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO | ||
101 | ohci->flags |= OHCI_QUIRK_BE_MMIO; | ||
102 | ohci_dbg (ohci, "enabled big endian Toshiba quirk\n"); | ||
103 | return 0; | ||
104 | #else | ||
105 | ohci_err (ohci, "unsupported big endian Toshiba quirk\n"); | ||
106 | return -ENXIO; | ||
107 | #endif | ||
108 | } | ||
109 | |||
110 | /* List of quirks for OHCI */ | ||
111 | static const struct pci_device_id ohci_pci_quirks[] = { | ||
112 | { | ||
113 | PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x740c), | ||
114 | .driver_data = (unsigned long)ohci_quirk_amd756, | ||
115 | }, | ||
116 | { | ||
117 | PCI_DEVICE(PCI_VENDOR_ID_OPTI, 0xc861), | ||
118 | .driver_data = (unsigned long)ohci_quirk_opti, | ||
119 | }, | ||
120 | { | ||
121 | PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_ANY_ID), | ||
122 | .driver_data = (unsigned long)ohci_quirk_ns, | ||
123 | }, | ||
124 | { | ||
125 | PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xa0f8), | ||
126 | .driver_data = (unsigned long)ohci_quirk_zfmicro, | ||
127 | }, | ||
128 | { | ||
129 | PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, 0x01b6), | ||
130 | .driver_data = (unsigned long)ohci_quirk_toshiba_scc, | ||
131 | }, | ||
132 | /* FIXME for some of the early AMD 760 southbridges, OHCI | ||
133 | * won't work at all. blacklist them. | ||
40 | */ | 134 | */ |
135 | |||
136 | {}, | ||
137 | }; | ||
138 | |||
139 | static int ohci_pci_reset (struct usb_hcd *hcd) | ||
140 | { | ||
141 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
142 | int ret = 0; | ||
143 | |||
41 | if (hcd->self.controller) { | 144 | if (hcd->self.controller) { |
42 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 145 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
146 | const struct pci_device_id *quirk_id; | ||
43 | 147 | ||
44 | /* AMD 756, for most chips (early revs), corrupts register | 148 | quirk_id = pci_match_id(ohci_pci_quirks, pdev); |
45 | * values on read ... so enable the vendor workaround. | 149 | if (quirk_id != NULL) { |
46 | */ | 150 | int (*quirk)(struct usb_hcd *ohci); |
47 | if (pdev->vendor == PCI_VENDOR_ID_AMD | 151 | quirk = (void *)quirk_id->driver_data; |
48 | && pdev->device == 0x740c) { | 152 | ret = quirk(hcd); |
49 | ohci->flags = OHCI_QUIRK_AMD756; | ||
50 | ohci_dbg (ohci, "AMD756 erratum 4 workaround\n"); | ||
51 | /* also erratum 10 (suspend/resume issues) */ | ||
52 | device_init_wakeup(&hcd->self.root_hub->dev, 0); | ||
53 | } | 153 | } |
154 | } | ||
155 | if (ret == 0) { | ||
156 | ohci_hcd_init (ohci); | ||
157 | return ohci_init (ohci); | ||
158 | } | ||
159 | return ret; | ||
160 | } | ||
54 | 161 | ||
55 | /* FIXME for some of the early AMD 760 southbridges, OHCI | ||
56 | * won't work at all. blacklist them. | ||
57 | */ | ||
58 | |||
59 | /* Apple's OHCI driver has a lot of bizarre workarounds | ||
60 | * for this chip. Evidently control and bulk lists | ||
61 | * can get confused. (B&W G3 models, and ...) | ||
62 | */ | ||
63 | else if (pdev->vendor == PCI_VENDOR_ID_OPTI | ||
64 | && pdev->device == 0xc861) { | ||
65 | ohci_dbg (ohci, | ||
66 | "WARNING: OPTi workarounds unavailable\n"); | ||
67 | } | ||
68 | 162 | ||
69 | /* Check for NSC87560. We have to look at the bridge (fn1) to | 163 | static int __devinit ohci_pci_start (struct usb_hcd *hcd) |
70 | * identify the USB (fn2). This quirk might apply to more or | 164 | { |
71 | * even all NSC stuff. | 165 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
72 | */ | 166 | int ret; |
73 | else if (pdev->vendor == PCI_VENDOR_ID_NS) { | ||
74 | struct pci_dev *b; | ||
75 | |||
76 | b = pci_get_slot (pdev->bus, | ||
77 | PCI_DEVFN (PCI_SLOT (pdev->devfn), 1)); | ||
78 | if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO | ||
79 | && b->vendor == PCI_VENDOR_ID_NS) { | ||
80 | ohci->flags |= OHCI_QUIRK_SUPERIO; | ||
81 | ohci_dbg (ohci, "Using NSC SuperIO setup\n"); | ||
82 | } | ||
83 | pci_dev_put(b); | ||
84 | } | ||
85 | 167 | ||
86 | /* Check for Compaq's ZFMicro chipset, which needs short | 168 | #ifdef CONFIG_PM /* avoid warnings about unused pdev */ |
87 | * delays before control or bulk queues get re-activated | 169 | if (hcd->self.controller) { |
88 | * in finish_unlinks() | 170 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
89 | */ | ||
90 | else if (pdev->vendor == PCI_VENDOR_ID_COMPAQ | ||
91 | && pdev->device == 0xa0f8) { | ||
92 | ohci->flags |= OHCI_QUIRK_ZFMICRO; | ||
93 | ohci_dbg (ohci, | ||
94 | "enabled Compaq ZFMicro chipset quirk\n"); | ||
95 | } | ||
96 | 171 | ||
97 | /* RWC may not be set for add-in PCI cards, since boot | 172 | /* RWC may not be set for add-in PCI cards, since boot |
98 | * firmware probably ignored them. This transfers PCI | 173 | * firmware probably ignored them. This transfers PCI |
@@ -101,16 +176,14 @@ ohci_pci_start (struct usb_hcd *hcd) | |||
101 | if (device_may_wakeup(&pdev->dev)) | 176 | if (device_may_wakeup(&pdev->dev)) |
102 | ohci->hc_control |= OHCI_CTRL_RWC; | 177 | ohci->hc_control |= OHCI_CTRL_RWC; |
103 | } | 178 | } |
179 | #endif /* CONFIG_PM */ | ||
104 | 180 | ||
105 | /* NOTE: there may have already been a first reset, to | 181 | ret = ohci_run (ohci); |
106 | * keep bios/smm irqs from making trouble | 182 | if (ret < 0) { |
107 | */ | ||
108 | if ((ret = ohci_run (ohci)) < 0) { | ||
109 | ohci_err (ohci, "can't start\n"); | 183 | ohci_err (ohci, "can't start\n"); |
110 | ohci_stop (hcd); | 184 | ohci_stop (hcd); |
111 | return ret; | ||
112 | } | 185 | } |
113 | return 0; | 186 | return ret; |
114 | } | 187 | } |
115 | 188 | ||
116 | #ifdef CONFIG_PM | 189 | #ifdef CONFIG_PM |
@@ -238,23 +311,3 @@ static struct pci_driver ohci_pci_driver = { | |||
238 | .shutdown = usb_hcd_pci_shutdown, | 311 | .shutdown = usb_hcd_pci_shutdown, |
239 | }; | 312 | }; |
240 | 313 | ||
241 | |||
242 | static int __init ohci_hcd_pci_init (void) | ||
243 | { | ||
244 | printk (KERN_DEBUG "%s: " DRIVER_INFO " (PCI)\n", hcd_name); | ||
245 | if (usb_disabled()) | ||
246 | return -ENODEV; | ||
247 | |||
248 | pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, | ||
249 | sizeof (struct ed), sizeof (struct td)); | ||
250 | return pci_register_driver (&ohci_pci_driver); | ||
251 | } | ||
252 | module_init (ohci_hcd_pci_init); | ||
253 | |||
254 | /*-------------------------------------------------------------------------*/ | ||
255 | |||
256 | static void __exit ohci_hcd_pci_cleanup (void) | ||
257 | { | ||
258 | pci_unregister_driver (&ohci_pci_driver); | ||
259 | } | ||
260 | module_exit (ohci_hcd_pci_cleanup); | ||
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c index 3a8cbfb69054..893b172384da 100644 --- a/drivers/usb/host/ohci-pnx4008.c +++ b/drivers/usb/host/ohci-pnx4008.c | |||
@@ -465,15 +465,3 @@ static struct platform_driver usb_hcd_pnx4008_driver = { | |||
465 | .remove = usb_hcd_pnx4008_remove, | 465 | .remove = usb_hcd_pnx4008_remove, |
466 | }; | 466 | }; |
467 | 467 | ||
468 | static int __init usb_hcd_pnx4008_init(void) | ||
469 | { | ||
470 | return platform_driver_register(&usb_hcd_pnx4008_driver); | ||
471 | } | ||
472 | |||
473 | static void __exit usb_hcd_pnx4008_cleanup(void) | ||
474 | { | ||
475 | return platform_driver_unregister(&usb_hcd_pnx4008_driver); | ||
476 | } | ||
477 | |||
478 | module_init(usb_hcd_pnx4008_init); | ||
479 | module_exit(usb_hcd_pnx4008_cleanup); | ||
diff --git a/drivers/usb/host/ohci-pnx8550.c b/drivers/usb/host/ohci-pnx8550.c index 6922b91b1704..de45eb0051a7 100644 --- a/drivers/usb/host/ohci-pnx8550.c +++ b/drivers/usb/host/ohci-pnx8550.c | |||
@@ -240,19 +240,3 @@ static struct platform_driver ohci_hcd_pnx8550_driver = { | |||
240 | .remove = ohci_hcd_pnx8550_drv_remove, | 240 | .remove = ohci_hcd_pnx8550_drv_remove, |
241 | }; | 241 | }; |
242 | 242 | ||
243 | static int __init ohci_hcd_pnx8550_init (void) | ||
244 | { | ||
245 | pr_debug (DRIVER_INFO " (pnx8550)"); | ||
246 | pr_debug ("block sizes: ed %d td %d\n", | ||
247 | sizeof (struct ed), sizeof (struct td)); | ||
248 | |||
249 | return platform_driver_register(&ohci_hcd_pnx8550_driver); | ||
250 | } | ||
251 | |||
252 | static void __exit ohci_hcd_pnx8550_cleanup (void) | ||
253 | { | ||
254 | platform_driver_unregister(&ohci_hcd_pnx8550_driver); | ||
255 | } | ||
256 | |||
257 | module_init (ohci_hcd_pnx8550_init); | ||
258 | module_exit (ohci_hcd_pnx8550_cleanup); | ||
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c new file mode 100644 index 000000000000..08e237c7bc43 --- /dev/null +++ b/drivers/usb/host/ohci-ppc-of.c | |||
@@ -0,0 +1,232 @@ | |||
1 | /* | ||
2 | * OHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | ||
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | ||
6 | * (C) Copyright 2002 Hewlett-Packard Company | ||
7 | * (C) Copyright 2006 Sylvain Munaut <tnt@246tNt.com> | ||
8 | * | ||
9 | * Bus glue for OHCI HC on the of_platform bus | ||
10 | * | ||
11 | * Modified for of_platform bus from ohci-sa1111.c | ||
12 | * | ||
13 | * This file is licenced under the GPL. | ||
14 | */ | ||
15 | |||
16 | #include <linux/signal.h> | ||
17 | |||
18 | #include <asm/of_platform.h> | ||
19 | #include <asm/prom.h> | ||
20 | |||
21 | |||
22 | static int __devinit | ||
23 | ohci_ppc_of_start(struct usb_hcd *hcd) | ||
24 | { | ||
25 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
26 | int ret; | ||
27 | |||
28 | if ((ret = ohci_init(ohci)) < 0) | ||
29 | return ret; | ||
30 | |||
31 | if ((ret = ohci_run(ohci)) < 0) { | ||
32 | err("can't start %s", ohci_to_hcd(ohci)->self.bus_name); | ||
33 | ohci_stop(hcd); | ||
34 | return ret; | ||
35 | } | ||
36 | |||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static const struct hc_driver ohci_ppc_of_hc_driver = { | ||
41 | .description = hcd_name, | ||
42 | .product_desc = "OF OHCI", | ||
43 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
44 | |||
45 | /* | ||
46 | * generic hardware linkage | ||
47 | */ | ||
48 | .irq = ohci_irq, | ||
49 | .flags = HCD_USB11 | HCD_MEMORY, | ||
50 | |||
51 | /* | ||
52 | * basic lifecycle operations | ||
53 | */ | ||
54 | .start = ohci_ppc_of_start, | ||
55 | .stop = ohci_stop, | ||
56 | .shutdown = ohci_shutdown, | ||
57 | |||
58 | /* | ||
59 | * managing i/o requests and associated device resources | ||
60 | */ | ||
61 | .urb_enqueue = ohci_urb_enqueue, | ||
62 | .urb_dequeue = ohci_urb_dequeue, | ||
63 | .endpoint_disable = ohci_endpoint_disable, | ||
64 | |||
65 | /* | ||
66 | * scheduling support | ||
67 | */ | ||
68 | .get_frame_number = ohci_get_frame, | ||
69 | |||
70 | /* | ||
71 | * root hub support | ||
72 | */ | ||
73 | .hub_status_data = ohci_hub_status_data, | ||
74 | .hub_control = ohci_hub_control, | ||
75 | .hub_irq_enable = ohci_rhsc_enable, | ||
76 | #ifdef CONFIG_PM | ||
77 | .bus_suspend = ohci_bus_suspend, | ||
78 | .bus_resume = ohci_bus_resume, | ||
79 | #endif | ||
80 | .start_port_reset = ohci_start_port_reset, | ||
81 | }; | ||
82 | |||
83 | |||
84 | static int __devinit | ||
85 | ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) | ||
86 | { | ||
87 | struct device_node *dn = op->node; | ||
88 | struct usb_hcd *hcd; | ||
89 | struct ohci_hcd *ohci; | ||
90 | struct resource res; | ||
91 | int irq; | ||
92 | |||
93 | int rv; | ||
94 | int is_bigendian; | ||
95 | |||
96 | if (usb_disabled()) | ||
97 | return -ENODEV; | ||
98 | |||
99 | is_bigendian = | ||
100 | device_is_compatible(dn, "ohci-bigendian") || | ||
101 | device_is_compatible(dn, "ohci-be"); | ||
102 | |||
103 | dev_dbg(&op->dev, "initializing PPC-OF USB Controller\n"); | ||
104 | |||
105 | rv = of_address_to_resource(dn, 0, &res); | ||
106 | if (rv) | ||
107 | return rv; | ||
108 | |||
109 | hcd = usb_create_hcd(&ohci_ppc_of_hc_driver, &op->dev, "PPC-OF USB"); | ||
110 | if (!hcd) | ||
111 | return -ENOMEM; | ||
112 | |||
113 | hcd->rsrc_start = res.start; | ||
114 | hcd->rsrc_len = res.end - res.start + 1; | ||
115 | |||
116 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
117 | printk(KERN_ERR __FILE__ ": request_mem_region failed\n"); | ||
118 | rv = -EBUSY; | ||
119 | goto err_rmr; | ||
120 | } | ||
121 | |||
122 | irq = irq_of_parse_and_map(dn, 0); | ||
123 | if (irq == NO_IRQ) { | ||
124 | printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n"); | ||
125 | rv = -EBUSY; | ||
126 | goto err_irq; | ||
127 | } | ||
128 | |||
129 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
130 | if (!hcd->regs) { | ||
131 | printk(KERN_ERR __FILE__ ": ioremap failed\n"); | ||
132 | rv = -ENOMEM; | ||
133 | goto err_ioremap; | ||
134 | } | ||
135 | |||
136 | ohci = hcd_to_ohci(hcd); | ||
137 | if (is_bigendian) | ||
138 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; | ||
139 | |||
140 | ohci_hcd_init(ohci); | ||
141 | |||
142 | rv = usb_add_hcd(hcd, irq, 0); | ||
143 | if (rv == 0) | ||
144 | return 0; | ||
145 | |||
146 | iounmap(hcd->regs); | ||
147 | err_ioremap: | ||
148 | irq_dispose_mapping(irq); | ||
149 | err_irq: | ||
150 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
151 | err_rmr: | ||
152 | usb_put_hcd(hcd); | ||
153 | |||
154 | return rv; | ||
155 | } | ||
156 | |||
157 | static int ohci_hcd_ppc_of_remove(struct of_device *op) | ||
158 | { | ||
159 | struct usb_hcd *hcd = dev_get_drvdata(&op->dev); | ||
160 | dev_set_drvdata(&op->dev, NULL); | ||
161 | |||
162 | dev_dbg(&op->dev, "stopping PPC-OF USB Controller\n"); | ||
163 | |||
164 | usb_remove_hcd(hcd); | ||
165 | |||
166 | iounmap(hcd->regs); | ||
167 | irq_dispose_mapping(hcd->irq); | ||
168 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
169 | |||
170 | usb_put_hcd(hcd); | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static int ohci_hcd_ppc_of_shutdown(struct of_device *op) | ||
176 | { | ||
177 | struct usb_hcd *hcd = dev_get_drvdata(&op->dev); | ||
178 | |||
179 | if (hcd->driver->shutdown) | ||
180 | hcd->driver->shutdown(hcd); | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | |||
186 | static struct of_device_id ohci_hcd_ppc_of_match[] = { | ||
187 | #ifdef CONFIG_USB_OHCI_HCD_PPC_OF_BE | ||
188 | { | ||
189 | .name = "usb", | ||
190 | .compatible = "ohci-bigendian", | ||
191 | }, | ||
192 | { | ||
193 | .name = "usb", | ||
194 | .compatible = "ohci-be", | ||
195 | }, | ||
196 | #endif | ||
197 | #ifdef CONFIG_USB_OHCI_HCD_PPC_OF_LE | ||
198 | { | ||
199 | .name = "usb", | ||
200 | .compatible = "ohci-littledian", | ||
201 | }, | ||
202 | { | ||
203 | .name = "usb", | ||
204 | .compatible = "ohci-le", | ||
205 | }, | ||
206 | #endif | ||
207 | {}, | ||
208 | }; | ||
209 | MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match); | ||
210 | |||
211 | #if !defined(CONFIG_USB_OHCI_HCD_PPC_OF_BE) && \ | ||
212 | !defined(CONFIG_USB_OHCI_HCD_PPC_OF_LE) | ||
213 | #error "No endianess selected for ppc-of-ohci" | ||
214 | #endif | ||
215 | |||
216 | |||
217 | static struct of_platform_driver ohci_hcd_ppc_of_driver = { | ||
218 | .name = "ppc-of-ohci", | ||
219 | .match_table = ohci_hcd_ppc_of_match, | ||
220 | .probe = ohci_hcd_ppc_of_probe, | ||
221 | .remove = ohci_hcd_ppc_of_remove, | ||
222 | .shutdown = ohci_hcd_ppc_of_shutdown, | ||
223 | #ifdef CONFIG_PM | ||
224 | /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ | ||
225 | /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ | ||
226 | #endif | ||
227 | .driver = { | ||
228 | .name = "ppc-of-ohci", | ||
229 | .owner = THIS_MODULE, | ||
230 | }, | ||
231 | }; | ||
232 | |||
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index e1a7eb817313..1a2e1777ca61 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c | |||
@@ -72,7 +72,7 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, | |||
72 | } | 72 | } |
73 | 73 | ||
74 | ohci = hcd_to_ohci(hcd); | 74 | ohci = hcd_to_ohci(hcd); |
75 | ohci->flags |= OHCI_BIG_ENDIAN; | 75 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; |
76 | ohci_hcd_init(ohci); | 76 | ohci_hcd_init(ohci); |
77 | 77 | ||
78 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 78 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); |
@@ -208,19 +208,3 @@ static struct platform_driver ohci_hcd_ppc_soc_driver = { | |||
208 | }, | 208 | }, |
209 | }; | 209 | }; |
210 | 210 | ||
211 | static int __init ohci_hcd_ppc_soc_init(void) | ||
212 | { | ||
213 | pr_debug(DRIVER_INFO " (PPC SOC)\n"); | ||
214 | pr_debug("block sizes: ed %d td %d\n", sizeof(struct ed), | ||
215 | sizeof(struct td)); | ||
216 | |||
217 | return platform_driver_register(&ohci_hcd_ppc_soc_driver); | ||
218 | } | ||
219 | |||
220 | static void __exit ohci_hcd_ppc_soc_cleanup(void) | ||
221 | { | ||
222 | platform_driver_unregister(&ohci_hcd_ppc_soc_driver); | ||
223 | } | ||
224 | |||
225 | module_init(ohci_hcd_ppc_soc_init); | ||
226 | module_exit(ohci_hcd_ppc_soc_cleanup); | ||
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c new file mode 100644 index 000000000000..62283a3926de --- /dev/null +++ b/drivers/usb/host/ohci-ps3.c | |||
@@ -0,0 +1,196 @@ | |||
1 | /* | ||
2 | * PS3 OHCI Host Controller driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Sony Computer Entertainment Inc. | ||
5 | * Copyright 2006 Sony Corp. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <asm/ps3.h> | ||
22 | |||
23 | static int ps3_ohci_hc_reset(struct usb_hcd *hcd) | ||
24 | { | ||
25 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
26 | |||
27 | ohci->flags |= OHCI_QUIRK_BE_MMIO; | ||
28 | ohci_hcd_init(ohci); | ||
29 | return ohci_init(ohci); | ||
30 | } | ||
31 | |||
32 | static int __devinit ps3_ohci_hc_start(struct usb_hcd *hcd) | ||
33 | { | ||
34 | int result; | ||
35 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
36 | |||
37 | /* Handle root hub init quirk in spider south bridge. */ | ||
38 | /* Also set PwrOn2PwrGood to 0x7f (254ms). */ | ||
39 | |||
40 | ohci_writel(ohci, 0x7f000000 | RH_A_PSM | RH_A_OCPM, | ||
41 | &ohci->regs->roothub.a); | ||
42 | ohci_writel(ohci, 0x00060000, &ohci->regs->roothub.b); | ||
43 | |||
44 | result = ohci_run(ohci); | ||
45 | |||
46 | if (result < 0) { | ||
47 | err("can't start %s", hcd->self.bus_name); | ||
48 | ohci_stop(hcd); | ||
49 | } | ||
50 | |||
51 | return result; | ||
52 | } | ||
53 | |||
54 | static const struct hc_driver ps3_ohci_hc_driver = { | ||
55 | .description = hcd_name, | ||
56 | .product_desc = "PS3 OHCI Host Controller", | ||
57 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
58 | .irq = ohci_irq, | ||
59 | .flags = HCD_MEMORY | HCD_USB11, | ||
60 | .reset = ps3_ohci_hc_reset, | ||
61 | .start = ps3_ohci_hc_start, | ||
62 | .stop = ohci_stop, | ||
63 | .shutdown = ohci_shutdown, | ||
64 | .urb_enqueue = ohci_urb_enqueue, | ||
65 | .urb_dequeue = ohci_urb_dequeue, | ||
66 | .endpoint_disable = ohci_endpoint_disable, | ||
67 | .get_frame_number = ohci_get_frame, | ||
68 | .hub_status_data = ohci_hub_status_data, | ||
69 | .hub_control = ohci_hub_control, | ||
70 | .hub_irq_enable = ohci_rhsc_enable, | ||
71 | .start_port_reset = ohci_start_port_reset, | ||
72 | #if defined(CONFIG_PM) | ||
73 | .bus_suspend = ohci_bus_suspend, | ||
74 | .bus_resume = ohci_bus_resume, | ||
75 | #endif | ||
76 | }; | ||
77 | |||
78 | /* redefine dev_dbg to do a syntax check */ | ||
79 | |||
80 | #if !defined(DEBUG) | ||
81 | #undef dev_dbg | ||
82 | static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg( | ||
83 | const struct device *_dev, const char *fmt, ...) {return 0;} | ||
84 | #endif | ||
85 | |||
86 | static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev) | ||
87 | { | ||
88 | int result; | ||
89 | struct usb_hcd *hcd; | ||
90 | unsigned int virq; | ||
91 | static u64 dummy_mask = DMA_32BIT_MASK; | ||
92 | |||
93 | if (usb_disabled()) { | ||
94 | result = -ENODEV; | ||
95 | goto fail_start; | ||
96 | } | ||
97 | |||
98 | result = ps3_mmio_region_create(dev->m_region); | ||
99 | |||
100 | if (result) { | ||
101 | dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n", | ||
102 | __func__, __LINE__); | ||
103 | result = -EPERM; | ||
104 | goto fail_mmio; | ||
105 | } | ||
106 | |||
107 | dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, | ||
108 | __LINE__, dev->m_region->lpar_addr); | ||
109 | |||
110 | result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); | ||
111 | |||
112 | if (result) { | ||
113 | dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", | ||
114 | __func__, __LINE__, virq); | ||
115 | result = -EPERM; | ||
116 | goto fail_irq; | ||
117 | } | ||
118 | |||
119 | dev->core.power.power_state = PMSG_ON; | ||
120 | dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */ | ||
121 | |||
122 | hcd = usb_create_hcd(&ps3_ohci_hc_driver, &dev->core, dev->core.bus_id); | ||
123 | |||
124 | if (!hcd) { | ||
125 | dev_dbg(&dev->core, "%s:%d: usb_create_hcd failed\n", __func__, | ||
126 | __LINE__); | ||
127 | result = -ENOMEM; | ||
128 | goto fail_create_hcd; | ||
129 | } | ||
130 | |||
131 | hcd->rsrc_start = dev->m_region->lpar_addr; | ||
132 | hcd->rsrc_len = dev->m_region->len; | ||
133 | hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len); | ||
134 | |||
135 | if (!hcd->regs) { | ||
136 | dev_dbg(&dev->core, "%s:%d: ioremap failed\n", __func__, | ||
137 | __LINE__); | ||
138 | result = -EPERM; | ||
139 | goto fail_ioremap; | ||
140 | } | ||
141 | |||
142 | dev_dbg(&dev->core, "%s:%d: hcd->rsrc_start %lxh\n", __func__, __LINE__, | ||
143 | (unsigned long)hcd->rsrc_start); | ||
144 | dev_dbg(&dev->core, "%s:%d: hcd->rsrc_len %lxh\n", __func__, __LINE__, | ||
145 | (unsigned long)hcd->rsrc_len); | ||
146 | dev_dbg(&dev->core, "%s:%d: hcd->regs %lxh\n", __func__, __LINE__, | ||
147 | (unsigned long)hcd->regs); | ||
148 | dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, | ||
149 | (unsigned long)virq); | ||
150 | |||
151 | ps3_system_bus_set_driver_data(dev, hcd); | ||
152 | |||
153 | result = usb_add_hcd(hcd, virq, IRQF_DISABLED); | ||
154 | |||
155 | if (result) { | ||
156 | dev_dbg(&dev->core, "%s:%d: usb_add_hcd failed (%d)\n", | ||
157 | __func__, __LINE__, result); | ||
158 | goto fail_add_hcd; | ||
159 | } | ||
160 | |||
161 | return result; | ||
162 | |||
163 | fail_add_hcd: | ||
164 | iounmap(hcd->regs); | ||
165 | fail_ioremap: | ||
166 | usb_put_hcd(hcd); | ||
167 | fail_create_hcd: | ||
168 | ps3_free_io_irq(virq); | ||
169 | fail_irq: | ||
170 | ps3_free_mmio_region(dev->m_region); | ||
171 | fail_mmio: | ||
172 | fail_start: | ||
173 | return result; | ||
174 | } | ||
175 | |||
176 | static int ps3_ohci_sb_remove (struct ps3_system_bus_device *dev) | ||
177 | { | ||
178 | struct usb_hcd *hcd = | ||
179 | (struct usb_hcd *)ps3_system_bus_get_driver_data(dev); | ||
180 | |||
181 | usb_put_hcd(hcd); | ||
182 | ps3_system_bus_set_driver_data(dev, NULL); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | MODULE_ALIAS("ps3-ohci"); | ||
188 | |||
189 | static struct ps3_system_bus_driver ps3_ohci_sb_driver = { | ||
190 | .match_id = PS3_MATCH_ID_OHCI, | ||
191 | .core = { | ||
192 | .name = "ps3-ohci-driver", | ||
193 | }, | ||
194 | .probe = ps3_ohci_sb_probe, | ||
195 | .remove = ps3_ohci_sb_remove, | ||
196 | }; | ||
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 3bbea844a9e3..f1563dc319d3 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
@@ -369,19 +369,3 @@ static struct platform_driver ohci_hcd_pxa27x_driver = { | |||
369 | }, | 369 | }, |
370 | }; | 370 | }; |
371 | 371 | ||
372 | static int __init ohci_hcd_pxa27x_init (void) | ||
373 | { | ||
374 | pr_debug (DRIVER_INFO " (pxa27x)"); | ||
375 | pr_debug ("block sizes: ed %d td %d\n", | ||
376 | sizeof (struct ed), sizeof (struct td)); | ||
377 | |||
378 | return platform_driver_register(&ohci_hcd_pxa27x_driver); | ||
379 | } | ||
380 | |||
381 | static void __exit ohci_hcd_pxa27x_cleanup (void) | ||
382 | { | ||
383 | platform_driver_unregister(&ohci_hcd_pxa27x_driver); | ||
384 | } | ||
385 | |||
386 | module_init (ohci_hcd_pxa27x_init); | ||
387 | module_exit (ohci_hcd_pxa27x_cleanup); | ||
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index b350d45033e7..6829814b7aaf 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c | |||
@@ -501,15 +501,3 @@ static struct platform_driver ohci_hcd_s3c2410_driver = { | |||
501 | }, | 501 | }, |
502 | }; | 502 | }; |
503 | 503 | ||
504 | static int __init ohci_hcd_s3c2410_init (void) | ||
505 | { | ||
506 | return platform_driver_register(&ohci_hcd_s3c2410_driver); | ||
507 | } | ||
508 | |||
509 | static void __exit ohci_hcd_s3c2410_cleanup (void) | ||
510 | { | ||
511 | platform_driver_unregister(&ohci_hcd_s3c2410_driver); | ||
512 | } | ||
513 | |||
514 | module_init (ohci_hcd_s3c2410_init); | ||
515 | module_exit (ohci_hcd_s3c2410_cleanup); | ||
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index fe0090e33675..0f48f2d99226 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c | |||
@@ -269,19 +269,3 @@ static struct sa1111_driver ohci_hcd_sa1111_driver = { | |||
269 | .remove = ohci_hcd_sa1111_drv_remove, | 269 | .remove = ohci_hcd_sa1111_drv_remove, |
270 | }; | 270 | }; |
271 | 271 | ||
272 | static int __init ohci_hcd_sa1111_init (void) | ||
273 | { | ||
274 | dbg (DRIVER_INFO " (SA-1111)"); | ||
275 | dbg ("block sizes: ed %d td %d", | ||
276 | sizeof (struct ed), sizeof (struct td)); | ||
277 | |||
278 | return sa1111_driver_register(&ohci_hcd_sa1111_driver); | ||
279 | } | ||
280 | |||
281 | static void __exit ohci_hcd_sa1111_cleanup (void) | ||
282 | { | ||
283 | sa1111_driver_unregister(&ohci_hcd_sa1111_driver); | ||
284 | } | ||
285 | |||
286 | module_init (ohci_hcd_sa1111_init); | ||
287 | module_exit (ohci_hcd_sa1111_cleanup); | ||
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 405257f3e853..c2b5ecfe5e9f 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -394,8 +394,9 @@ struct ohci_hcd { | |||
394 | #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ | 394 | #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ |
395 | #define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */ | 395 | #define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */ |
396 | #define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */ | 396 | #define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */ |
397 | #define OHCI_BIG_ENDIAN 0x08 /* big endian HC */ | 397 | #define OHCI_QUIRK_BE_DESC 0x08 /* BE descriptors */ |
398 | #define OHCI_QUIRK_ZFMICRO 0x10 /* Compaq ZFMicro chipset*/ | 398 | #define OHCI_QUIRK_BE_MMIO 0x10 /* BE registers */ |
399 | #define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/ | ||
399 | // there are also chip quirks/bugs in init logic | 400 | // there are also chip quirks/bugs in init logic |
400 | 401 | ||
401 | }; | 402 | }; |
@@ -439,117 +440,164 @@ static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci) | |||
439 | * a minority (notably the IBM STB04XXX and the Motorola MPC5200 | 440 | * a minority (notably the IBM STB04XXX and the Motorola MPC5200 |
440 | * processors) implement them in big endian format. | 441 | * processors) implement them in big endian format. |
441 | * | 442 | * |
443 | * In addition some more exotic implementations like the Toshiba | ||
444 | * Spider (aka SCC) cell southbridge are "mixed" endian, that is, | ||
445 | * they have a different endianness for registers vs. in-memory | ||
446 | * descriptors. | ||
447 | * | ||
442 | * This attempts to support either format at compile time without a | 448 | * This attempts to support either format at compile time without a |
443 | * runtime penalty, or both formats with the additional overhead | 449 | * runtime penalty, or both formats with the additional overhead |
444 | * of checking a flag bit. | 450 | * of checking a flag bit. |
451 | * | ||
452 | * That leads to some tricky Kconfig rules howevber. There are | ||
453 | * different defaults based on some arch/ppc platforms, though | ||
454 | * the basic rules are: | ||
455 | * | ||
456 | * Controller type Kconfig options needed | ||
457 | * --------------- ---------------------- | ||
458 | * little endian CONFIG_USB_OHCI_LITTLE_ENDIAN | ||
459 | * | ||
460 | * fully big endian CONFIG_USB_OHCI_BIG_ENDIAN_DESC _and_ | ||
461 | * CONFIG_USB_OHCI_BIG_ENDIAN_MMIO | ||
462 | * | ||
463 | * mixed endian CONFIG_USB_OHCI_LITTLE_ENDIAN _and_ | ||
464 | * CONFIG_USB_OHCI_BIG_ENDIAN_{MMIO,DESC} | ||
465 | * | ||
466 | * (If you have a mixed endian controller, you -must- also define | ||
467 | * CONFIG_USB_OHCI_LITTLE_ENDIAN or things will not work when building | ||
468 | * both your mixed endian and a fully big endian controller support in | ||
469 | * the same kernel image). | ||
445 | */ | 470 | */ |
446 | 471 | ||
447 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN | 472 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_DESC |
473 | #ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN | ||
474 | #define big_endian_desc(ohci) (ohci->flags & OHCI_QUIRK_BE_DESC) | ||
475 | #else | ||
476 | #define big_endian_desc(ohci) 1 /* only big endian */ | ||
477 | #endif | ||
478 | #else | ||
479 | #define big_endian_desc(ohci) 0 /* only little endian */ | ||
480 | #endif | ||
448 | 481 | ||
482 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO | ||
449 | #ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN | 483 | #ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN |
450 | #define big_endian(ohci) (ohci->flags & OHCI_BIG_ENDIAN) /* either */ | 484 | #define big_endian_mmio(ohci) (ohci->flags & OHCI_QUIRK_BE_MMIO) |
451 | #else | 485 | #else |
452 | #define big_endian(ohci) 1 /* only big endian */ | 486 | #define big_endian_mmio(ohci) 1 /* only big endian */ |
487 | #endif | ||
488 | #else | ||
489 | #define big_endian_mmio(ohci) 0 /* only little endian */ | ||
453 | #endif | 490 | #endif |
454 | 491 | ||
455 | /* | 492 | /* |
456 | * Big-endian read/write functions are arch-specific. | 493 | * Big-endian read/write functions are arch-specific. |
457 | * Other arches can be added if/when they're needed. | 494 | * Other arches can be added if/when they're needed. |
495 | * | ||
496 | * REVISIT: arch/powerpc now has readl/writel_be, so the | ||
497 | * definition below can die once the STB04xxx support is | ||
498 | * finally ported over. | ||
458 | */ | 499 | */ |
459 | #if defined(CONFIG_PPC) | 500 | #if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE) |
460 | #define readl_be(addr) in_be32((__force unsigned *)addr) | 501 | #define readl_be(addr) in_be32((__force unsigned *)addr) |
461 | #define writel_be(val, addr) out_be32((__force unsigned *)addr, val) | 502 | #define writel_be(val, addr) out_be32((__force unsigned *)addr, val) |
462 | #endif | 503 | #endif |
463 | 504 | ||
464 | static inline unsigned int ohci_readl (const struct ohci_hcd *ohci, | 505 | static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci, |
465 | __hc32 __iomem * regs) | 506 | __hc32 __iomem * regs) |
466 | { | 507 | { |
467 | return big_endian(ohci) ? readl_be (regs) : readl ((__force u32 *)regs); | 508 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO |
509 | return big_endian_mmio(ohci) ? | ||
510 | readl_be (regs) : | ||
511 | readl (regs); | ||
512 | #else | ||
513 | return readl (regs); | ||
514 | #endif | ||
468 | } | 515 | } |
469 | 516 | ||
470 | static inline void ohci_writel (const struct ohci_hcd *ohci, | 517 | static inline void _ohci_writel (const struct ohci_hcd *ohci, |
471 | const unsigned int val, __hc32 __iomem *regs) | 518 | const unsigned int val, __hc32 __iomem *regs) |
472 | { | 519 | { |
473 | big_endian(ohci) ? writel_be (val, regs) : | 520 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO |
474 | writel (val, (__force u32 *)regs); | 521 | big_endian_mmio(ohci) ? |
522 | writel_be (val, regs) : | ||
523 | writel (val, regs); | ||
524 | #else | ||
525 | writel (val, regs); | ||
526 | #endif | ||
475 | } | 527 | } |
476 | 528 | ||
477 | #else /* !CONFIG_USB_OHCI_BIG_ENDIAN */ | ||
478 | |||
479 | #define big_endian(ohci) 0 /* only little endian */ | ||
480 | |||
481 | #ifdef CONFIG_ARCH_LH7A404 | 529 | #ifdef CONFIG_ARCH_LH7A404 |
482 | /* Marc Singer: at the time this code was written, the LH7A404 | 530 | /* Marc Singer: at the time this code was written, the LH7A404 |
483 | * had a problem reading the USB host registers. This | 531 | * had a problem reading the USB host registers. This |
484 | * implementation of the ohci_readl function performs the read | 532 | * implementation of the ohci_readl function performs the read |
485 | * twice as a work-around. | 533 | * twice as a work-around. |
486 | */ | 534 | */ |
487 | static inline unsigned int | 535 | #define ohci_readl(o,r) (_ohci_readl(o,r),_ohci_readl(o,r)) |
488 | ohci_readl (const struct ohci_hcd *ohci, const __hc32 *regs) | 536 | #define ohci_writel(o,v,r) _ohci_writel(o,v,r) |
489 | { | ||
490 | *(volatile __force unsigned int*) regs; | ||
491 | return *(volatile __force unsigned int*) regs; | ||
492 | } | ||
493 | #else | 537 | #else |
494 | /* Standard version of ohci_readl uses standard, platform | 538 | #define ohci_readl(o,r) _ohci_readl(o,r) |
495 | * specific implementation. */ | 539 | #define ohci_writel(o,v,r) _ohci_writel(o,v,r) |
496 | static inline unsigned int | ||
497 | ohci_readl (const struct ohci_hcd *ohci, __hc32 __iomem * regs) | ||
498 | { | ||
499 | return readl(regs); | ||
500 | } | ||
501 | #endif | 540 | #endif |
502 | 541 | ||
503 | static inline void ohci_writel (const struct ohci_hcd *ohci, | ||
504 | const unsigned int val, __hc32 __iomem *regs) | ||
505 | { | ||
506 | writel (val, regs); | ||
507 | } | ||
508 | |||
509 | #endif /* !CONFIG_USB_OHCI_BIG_ENDIAN */ | ||
510 | 542 | ||
511 | /*-------------------------------------------------------------------------*/ | 543 | /*-------------------------------------------------------------------------*/ |
512 | 544 | ||
513 | /* cpu to ohci */ | 545 | /* cpu to ohci */ |
514 | static inline __hc16 cpu_to_hc16 (const struct ohci_hcd *ohci, const u16 x) | 546 | static inline __hc16 cpu_to_hc16 (const struct ohci_hcd *ohci, const u16 x) |
515 | { | 547 | { |
516 | return big_endian(ohci) ? (__force __hc16)cpu_to_be16(x) : (__force __hc16)cpu_to_le16(x); | 548 | return big_endian_desc(ohci) ? |
549 | (__force __hc16)cpu_to_be16(x) : | ||
550 | (__force __hc16)cpu_to_le16(x); | ||
517 | } | 551 | } |
518 | 552 | ||
519 | static inline __hc16 cpu_to_hc16p (const struct ohci_hcd *ohci, const u16 *x) | 553 | static inline __hc16 cpu_to_hc16p (const struct ohci_hcd *ohci, const u16 *x) |
520 | { | 554 | { |
521 | return big_endian(ohci) ? cpu_to_be16p(x) : cpu_to_le16p(x); | 555 | return big_endian_desc(ohci) ? |
556 | cpu_to_be16p(x) : | ||
557 | cpu_to_le16p(x); | ||
522 | } | 558 | } |
523 | 559 | ||
524 | static inline __hc32 cpu_to_hc32 (const struct ohci_hcd *ohci, const u32 x) | 560 | static inline __hc32 cpu_to_hc32 (const struct ohci_hcd *ohci, const u32 x) |
525 | { | 561 | { |
526 | return big_endian(ohci) ? (__force __hc32)cpu_to_be32(x) : (__force __hc32)cpu_to_le32(x); | 562 | return big_endian_desc(ohci) ? |
563 | (__force __hc32)cpu_to_be32(x) : | ||
564 | (__force __hc32)cpu_to_le32(x); | ||
527 | } | 565 | } |
528 | 566 | ||
529 | static inline __hc32 cpu_to_hc32p (const struct ohci_hcd *ohci, const u32 *x) | 567 | static inline __hc32 cpu_to_hc32p (const struct ohci_hcd *ohci, const u32 *x) |
530 | { | 568 | { |
531 | return big_endian(ohci) ? cpu_to_be32p(x) : cpu_to_le32p(x); | 569 | return big_endian_desc(ohci) ? |
570 | cpu_to_be32p(x) : | ||
571 | cpu_to_le32p(x); | ||
532 | } | 572 | } |
533 | 573 | ||
534 | /* ohci to cpu */ | 574 | /* ohci to cpu */ |
535 | static inline u16 hc16_to_cpu (const struct ohci_hcd *ohci, const __hc16 x) | 575 | static inline u16 hc16_to_cpu (const struct ohci_hcd *ohci, const __hc16 x) |
536 | { | 576 | { |
537 | return big_endian(ohci) ? be16_to_cpu((__force __be16)x) : le16_to_cpu((__force __le16)x); | 577 | return big_endian_desc(ohci) ? |
578 | be16_to_cpu((__force __be16)x) : | ||
579 | le16_to_cpu((__force __le16)x); | ||
538 | } | 580 | } |
539 | 581 | ||
540 | static inline u16 hc16_to_cpup (const struct ohci_hcd *ohci, const __hc16 *x) | 582 | static inline u16 hc16_to_cpup (const struct ohci_hcd *ohci, const __hc16 *x) |
541 | { | 583 | { |
542 | return big_endian(ohci) ? be16_to_cpup((__force __be16 *)x) : le16_to_cpup((__force __le16 *)x); | 584 | return big_endian_desc(ohci) ? |
585 | be16_to_cpup((__force __be16 *)x) : | ||
586 | le16_to_cpup((__force __le16 *)x); | ||
543 | } | 587 | } |
544 | 588 | ||
545 | static inline u32 hc32_to_cpu (const struct ohci_hcd *ohci, const __hc32 x) | 589 | static inline u32 hc32_to_cpu (const struct ohci_hcd *ohci, const __hc32 x) |
546 | { | 590 | { |
547 | return big_endian(ohci) ? be32_to_cpu((__force __be32)x) : le32_to_cpu((__force __le32)x); | 591 | return big_endian_desc(ohci) ? |
592 | be32_to_cpu((__force __be32)x) : | ||
593 | le32_to_cpu((__force __le32)x); | ||
548 | } | 594 | } |
549 | 595 | ||
550 | static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) | 596 | static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) |
551 | { | 597 | { |
552 | return big_endian(ohci) ? be32_to_cpup((__force __be32 *)x) : le32_to_cpup((__force __le32 *)x); | 598 | return big_endian_desc(ohci) ? |
599 | be32_to_cpup((__force __be32 *)x) : | ||
600 | le32_to_cpup((__force __le32 *)x); | ||
553 | } | 601 | } |
554 | 602 | ||
555 | /*-------------------------------------------------------------------------*/ | 603 | /*-------------------------------------------------------------------------*/ |
@@ -557,6 +605,9 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) | |||
557 | /* HCCA frame number is 16 bits, but is accessed as 32 bits since not all | 605 | /* HCCA frame number is 16 bits, but is accessed as 32 bits since not all |
558 | * hardware handles 16 bit reads. That creates a different confusion on | 606 | * hardware handles 16 bit reads. That creates a different confusion on |
559 | * some big-endian SOC implementations. Same thing happens with PSW access. | 607 | * some big-endian SOC implementations. Same thing happens with PSW access. |
608 | * | ||
609 | * FIXME: Deal with that as a runtime quirk when STB03xxx is ported over | ||
610 | * to arch/powerpc | ||
560 | */ | 611 | */ |
561 | 612 | ||
562 | #ifdef CONFIG_STB03xxx | 613 | #ifdef CONFIG_STB03xxx |
@@ -568,7 +619,7 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) | |||
568 | static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) | 619 | static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) |
569 | { | 620 | { |
570 | u32 tmp; | 621 | u32 tmp; |
571 | if (big_endian(ohci)) { | 622 | if (big_endian_desc(ohci)) { |
572 | tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); | 623 | tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); |
573 | tmp >>= OHCI_BE_FRAME_NO_SHIFT; | 624 | tmp >>= OHCI_BE_FRAME_NO_SHIFT; |
574 | } else | 625 | } else |
@@ -580,7 +631,7 @@ static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) | |||
580 | static inline __hc16 *ohci_hwPSWp(const struct ohci_hcd *ohci, | 631 | static inline __hc16 *ohci_hwPSWp(const struct ohci_hcd *ohci, |
581 | const struct td *td, int index) | 632 | const struct td *td, int index) |
582 | { | 633 | { |
583 | return (__hc16 *)(big_endian(ohci) ? | 634 | return (__hc16 *)(big_endian_desc(ohci) ? |
584 | &td->hwPSW[index ^ 1] : &td->hwPSW[index]); | 635 | &td->hwPSW[index ^ 1] : &td->hwPSW[index]); |
585 | } | 636 | } |
586 | 637 | ||
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index e345f15b7d87..5d6c06bc4524 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
@@ -168,9 +168,13 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) | |||
168 | space, "", qh, qtype, | 168 | space, "", qh, qtype, |
169 | le32_to_cpu(qh->link), le32_to_cpu(element)); | 169 | le32_to_cpu(qh->link), le32_to_cpu(element)); |
170 | if (qh->type == USB_ENDPOINT_XFER_ISOC) | 170 | if (qh->type == USB_ENDPOINT_XFER_ISOC) |
171 | out += sprintf(out, "%*s period %d frame %x desc [%p]\n", | 171 | out += sprintf(out, "%*s period %d phase %d load %d us, " |
172 | space, "", qh->period, qh->iso_frame, | 172 | "frame %x desc [%p]\n", |
173 | qh->iso_packet_desc); | 173 | space, "", qh->period, qh->phase, qh->load, |
174 | qh->iso_frame, qh->iso_packet_desc); | ||
175 | else if (qh->type == USB_ENDPOINT_XFER_INT) | ||
176 | out += sprintf(out, "%*s period %d phase %d load %d us\n", | ||
177 | space, "", qh->period, qh->phase, qh->load); | ||
174 | 178 | ||
175 | if (element & UHCI_PTR_QH) | 179 | if (element & UHCI_PTR_QH) |
176 | out += sprintf(out, "%*s Element points to QH (bug?)\n", space, ""); | 180 | out += sprintf(out, "%*s Element points to QH (bug?)\n", space, ""); |
@@ -208,7 +212,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) | |||
208 | space, "", nurbs); | 212 | space, "", nurbs); |
209 | } | 213 | } |
210 | 214 | ||
211 | if (qh->udev) { | 215 | if (qh->dummy_td) { |
212 | out += sprintf(out, "%*s Dummy TD\n", space, ""); | 216 | out += sprintf(out, "%*s Dummy TD\n", space, ""); |
213 | out += uhci_show_td(qh->dummy_td, out, len - (out - buf), 0); | 217 | out += uhci_show_td(qh->dummy_td, out, len - (out - buf), 0); |
214 | } | 218 | } |
@@ -347,31 +351,80 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
347 | struct uhci_qh *qh; | 351 | struct uhci_qh *qh; |
348 | struct uhci_td *td; | 352 | struct uhci_td *td; |
349 | struct list_head *tmp, *head; | 353 | struct list_head *tmp, *head; |
354 | int nframes, nerrs; | ||
350 | 355 | ||
351 | out += uhci_show_root_hub_state(uhci, out, len - (out - buf)); | 356 | out += uhci_show_root_hub_state(uhci, out, len - (out - buf)); |
352 | out += sprintf(out, "HC status\n"); | 357 | out += sprintf(out, "HC status\n"); |
353 | out += uhci_show_status(uhci, out, len - (out - buf)); | 358 | out += uhci_show_status(uhci, out, len - (out - buf)); |
359 | |||
360 | out += sprintf(out, "Periodic load table\n"); | ||
361 | for (i = 0; i < MAX_PHASE; ++i) { | ||
362 | out += sprintf(out, "\t%d", uhci->load[i]); | ||
363 | if (i % 8 == 7) | ||
364 | *out++ = '\n'; | ||
365 | } | ||
366 | out += sprintf(out, "Total: %d, #INT: %d, #ISO: %d\n", | ||
367 | uhci->total_load, | ||
368 | uhci_to_hcd(uhci)->self.bandwidth_int_reqs, | ||
369 | uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs); | ||
354 | if (debug <= 1) | 370 | if (debug <= 1) |
355 | return out - buf; | 371 | return out - buf; |
356 | 372 | ||
357 | out += sprintf(out, "Frame List\n"); | 373 | out += sprintf(out, "Frame List\n"); |
374 | nframes = 10; | ||
375 | nerrs = 0; | ||
358 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { | 376 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { |
377 | __le32 link, qh_dma; | ||
378 | |||
379 | j = 0; | ||
359 | td = uhci->frame_cpu[i]; | 380 | td = uhci->frame_cpu[i]; |
381 | link = uhci->frame[i]; | ||
360 | if (!td) | 382 | if (!td) |
361 | continue; | 383 | goto check_link; |
362 | 384 | ||
363 | out += sprintf(out, "- Frame %d\n", i); \ | 385 | if (nframes > 0) { |
364 | if (td->dma_handle != (dma_addr_t)uhci->frame[i]) | 386 | out += sprintf(out, "- Frame %d -> (%08x)\n", |
365 | out += sprintf(out, " frame list does not match td->dma_handle!\n"); | 387 | i, le32_to_cpu(link)); |
388 | j = 1; | ||
389 | } | ||
366 | 390 | ||
367 | head = &td->fl_list; | 391 | head = &td->fl_list; |
368 | tmp = head; | 392 | tmp = head; |
369 | do { | 393 | do { |
370 | td = list_entry(tmp, struct uhci_td, fl_list); | 394 | td = list_entry(tmp, struct uhci_td, fl_list); |
371 | tmp = tmp->next; | 395 | tmp = tmp->next; |
372 | out += uhci_show_td(td, out, len - (out - buf), 4); | 396 | if (cpu_to_le32(td->dma_handle) != link) { |
397 | if (nframes > 0) | ||
398 | out += sprintf(out, " link does " | ||
399 | "not match list entry!\n"); | ||
400 | else | ||
401 | ++nerrs; | ||
402 | } | ||
403 | if (nframes > 0) | ||
404 | out += uhci_show_td(td, out, | ||
405 | len - (out - buf), 4); | ||
406 | link = td->link; | ||
373 | } while (tmp != head); | 407 | } while (tmp != head); |
408 | |||
409 | check_link: | ||
410 | qh_dma = uhci_frame_skel_link(uhci, i); | ||
411 | if (link != qh_dma) { | ||
412 | if (nframes > 0) { | ||
413 | if (!j) { | ||
414 | out += sprintf(out, | ||
415 | "- Frame %d -> (%08x)\n", | ||
416 | i, le32_to_cpu(link)); | ||
417 | j = 1; | ||
418 | } | ||
419 | out += sprintf(out, " link does not match " | ||
420 | "QH (%08x)!\n", le32_to_cpu(qh_dma)); | ||
421 | } else | ||
422 | ++nerrs; | ||
423 | } | ||
424 | nframes -= j; | ||
374 | } | 425 | } |
426 | if (nerrs > 0) | ||
427 | out += sprintf(out, "Skipped %d bad links\n", nerrs); | ||
375 | 428 | ||
376 | out += sprintf(out, "Skeleton QHs\n"); | 429 | out += sprintf(out, "Skeleton QHs\n"); |
377 | 430 | ||
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index e0d4c2358b39..49b9d390b95f 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -92,6 +92,34 @@ static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state); | |||
92 | static void wakeup_rh(struct uhci_hcd *uhci); | 92 | static void wakeup_rh(struct uhci_hcd *uhci); |
93 | static void uhci_get_current_frame_number(struct uhci_hcd *uhci); | 93 | static void uhci_get_current_frame_number(struct uhci_hcd *uhci); |
94 | 94 | ||
95 | /* | ||
96 | * Calculate the link pointer DMA value for the first Skeleton QH in a frame. | ||
97 | */ | ||
98 | static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame) | ||
99 | { | ||
100 | int skelnum; | ||
101 | |||
102 | /* | ||
103 | * The interrupt queues will be interleaved as evenly as possible. | ||
104 | * There's not much to be done about period-1 interrupts; they have | ||
105 | * to occur in every frame. But we can schedule period-2 interrupts | ||
106 | * in odd-numbered frames, period-4 interrupts in frames congruent | ||
107 | * to 2 (mod 4), and so on. This way each frame only has two | ||
108 | * interrupt QHs, which will help spread out bandwidth utilization. | ||
109 | * | ||
110 | * ffs (Find First bit Set) does exactly what we need: | ||
111 | * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8], | ||
112 | * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc. | ||
113 | * ffs >= 7 => not on any high-period queue, so use | ||
114 | * skel_int1_qh = skelqh[9]. | ||
115 | * Add in UHCI_NUMFRAMES to insure at least one bit is set. | ||
116 | */ | ||
117 | skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES); | ||
118 | if (skelnum <= 1) | ||
119 | skelnum = 9; | ||
120 | return UHCI_PTR_QH | cpu_to_le32(uhci->skelqh[skelnum]->dma_handle); | ||
121 | } | ||
122 | |||
95 | #include "uhci-debug.c" | 123 | #include "uhci-debug.c" |
96 | #include "uhci-q.c" | 124 | #include "uhci-q.c" |
97 | #include "uhci-hub.c" | 125 | #include "uhci-hub.c" |
@@ -631,32 +659,11 @@ static int uhci_start(struct usb_hcd *hcd) | |||
631 | /* | 659 | /* |
632 | * Fill the frame list: make all entries point to the proper | 660 | * Fill the frame list: make all entries point to the proper |
633 | * interrupt queue. | 661 | * interrupt queue. |
634 | * | ||
635 | * The interrupt queues will be interleaved as evenly as possible. | ||
636 | * There's not much to be done about period-1 interrupts; they have | ||
637 | * to occur in every frame. But we can schedule period-2 interrupts | ||
638 | * in odd-numbered frames, period-4 interrupts in frames congruent | ||
639 | * to 2 (mod 4), and so on. This way each frame only has two | ||
640 | * interrupt QHs, which will help spread out bandwidth utilization. | ||
641 | */ | 662 | */ |
642 | for (i = 0; i < UHCI_NUMFRAMES; i++) { | 663 | for (i = 0; i < UHCI_NUMFRAMES; i++) { |
643 | int irq; | ||
644 | |||
645 | /* | ||
646 | * ffs (Find First bit Set) does exactly what we need: | ||
647 | * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8], | ||
648 | * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc. | ||
649 | * ffs >= 7 => not on any high-period queue, so use | ||
650 | * skel_int1_qh = skelqh[9]. | ||
651 | * Add UHCI_NUMFRAMES to insure at least one bit is set. | ||
652 | */ | ||
653 | irq = 8 - (int) __ffs(i + UHCI_NUMFRAMES); | ||
654 | if (irq <= 1) | ||
655 | irq = 9; | ||
656 | 664 | ||
657 | /* Only place we don't use the frame list routines */ | 665 | /* Only place we don't use the frame list routines */ |
658 | uhci->frame[i] = UHCI_PTR_QH | | 666 | uhci->frame[i] = uhci_frame_skel_link(uhci, i); |
659 | cpu_to_le32(uhci->skelqh[irq]->dma_handle); | ||
660 | } | 667 | } |
661 | 668 | ||
662 | /* | 669 | /* |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 108e3de2dc26..74469b5bcb61 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -83,6 +83,7 @@ | |||
83 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ | 83 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ |
84 | #define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames | 84 | #define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames |
85 | * can be scheduled */ | 85 | * can be scheduled */ |
86 | #define MAX_PHASE 32 /* Periodic scheduling length */ | ||
86 | 87 | ||
87 | /* When no queues need Full-Speed Bandwidth Reclamation, | 88 | /* When no queues need Full-Speed Bandwidth Reclamation, |
88 | * delay this long before turning FSBR off */ | 89 | * delay this long before turning FSBR off */ |
@@ -141,6 +142,8 @@ struct uhci_qh { | |||
141 | unsigned long advance_jiffies; /* Time of last queue advance */ | 142 | unsigned long advance_jiffies; /* Time of last queue advance */ |
142 | unsigned int unlink_frame; /* When the QH was unlinked */ | 143 | unsigned int unlink_frame; /* When the QH was unlinked */ |
143 | unsigned int period; /* For Interrupt and Isochronous QHs */ | 144 | unsigned int period; /* For Interrupt and Isochronous QHs */ |
145 | short phase; /* Between 0 and period-1 */ | ||
146 | short load; /* Periodic time requirement, in us */ | ||
144 | unsigned int iso_frame; /* Frame # for iso_packet_desc */ | 147 | unsigned int iso_frame; /* Frame # for iso_packet_desc */ |
145 | int iso_status; /* Status for Isochronous URBs */ | 148 | int iso_status; /* Status for Isochronous URBs */ |
146 | 149 | ||
@@ -153,6 +156,8 @@ struct uhci_qh { | |||
153 | unsigned int needs_fixup:1; /* Must fix the TD toggle values */ | 156 | unsigned int needs_fixup:1; /* Must fix the TD toggle values */ |
154 | unsigned int is_stopped:1; /* Queue was stopped by error/unlink */ | 157 | unsigned int is_stopped:1; /* Queue was stopped by error/unlink */ |
155 | unsigned int wait_expired:1; /* QH_WAIT_TIMEOUT has expired */ | 158 | unsigned int wait_expired:1; /* QH_WAIT_TIMEOUT has expired */ |
159 | unsigned int bandwidth_reserved:1; /* Periodic bandwidth has | ||
160 | * been allocated */ | ||
156 | } __attribute__((aligned(16))); | 161 | } __attribute__((aligned(16))); |
157 | 162 | ||
158 | /* | 163 | /* |
@@ -414,6 +419,9 @@ struct uhci_hcd { | |||
414 | 419 | ||
415 | wait_queue_head_t waitqh; /* endpoint_disable waiters */ | 420 | wait_queue_head_t waitqh; /* endpoint_disable waiters */ |
416 | int num_waiting; /* Number of waiters */ | 421 | int num_waiting; /* Number of waiters */ |
422 | |||
423 | int total_load; /* Sum of array values */ | ||
424 | short load[MAX_PHASE]; /* Periodic allocations */ | ||
417 | }; | 425 | }; |
418 | 426 | ||
419 | /* Convert between a usb_hcd pointer and the corresponding uhci_hcd */ | 427 | /* Convert between a usb_hcd pointer and the corresponding uhci_hcd */ |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 30b88459ac7d..2cbb239e63f8 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -248,16 +248,26 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, | |||
248 | INIT_LIST_HEAD(&qh->node); | 248 | INIT_LIST_HEAD(&qh->node); |
249 | 249 | ||
250 | if (udev) { /* Normal QH */ | 250 | if (udev) { /* Normal QH */ |
251 | qh->dummy_td = uhci_alloc_td(uhci); | 251 | qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; |
252 | if (!qh->dummy_td) { | 252 | if (qh->type != USB_ENDPOINT_XFER_ISOC) { |
253 | dma_pool_free(uhci->qh_pool, qh, dma_handle); | 253 | qh->dummy_td = uhci_alloc_td(uhci); |
254 | return NULL; | 254 | if (!qh->dummy_td) { |
255 | dma_pool_free(uhci->qh_pool, qh, dma_handle); | ||
256 | return NULL; | ||
257 | } | ||
255 | } | 258 | } |
256 | qh->state = QH_STATE_IDLE; | 259 | qh->state = QH_STATE_IDLE; |
257 | qh->hep = hep; | 260 | qh->hep = hep; |
258 | qh->udev = udev; | 261 | qh->udev = udev; |
259 | hep->hcpriv = qh; | 262 | hep->hcpriv = qh; |
260 | qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; | 263 | |
264 | if (qh->type == USB_ENDPOINT_XFER_INT || | ||
265 | qh->type == USB_ENDPOINT_XFER_ISOC) | ||
266 | qh->load = usb_calc_bus_time(udev->speed, | ||
267 | usb_endpoint_dir_in(&hep->desc), | ||
268 | qh->type == USB_ENDPOINT_XFER_ISOC, | ||
269 | le16_to_cpu(hep->desc.wMaxPacketSize)) | ||
270 | / 1000 + 1; | ||
261 | 271 | ||
262 | } else { /* Skeleton QH */ | 272 | } else { /* Skeleton QH */ |
263 | qh->state = QH_STATE_ACTIVE; | 273 | qh->state = QH_STATE_ACTIVE; |
@@ -275,7 +285,8 @@ static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
275 | list_del(&qh->node); | 285 | list_del(&qh->node); |
276 | if (qh->udev) { | 286 | if (qh->udev) { |
277 | qh->hep->hcpriv = NULL; | 287 | qh->hep->hcpriv = NULL; |
278 | uhci_free_td(uhci, qh->dummy_td); | 288 | if (qh->dummy_td) |
289 | uhci_free_td(uhci, qh->dummy_td); | ||
279 | } | 290 | } |
280 | dma_pool_free(uhci->qh_pool, qh, qh->dma_handle); | 291 | dma_pool_free(uhci->qh_pool, qh, qh->dma_handle); |
281 | } | 292 | } |
@@ -327,7 +338,7 @@ static int uhci_cleanup_queue(struct uhci_hcd *uhci, struct uhci_qh *qh, | |||
327 | goto done; | 338 | goto done; |
328 | qh->element = UHCI_PTR_TERM; | 339 | qh->element = UHCI_PTR_TERM; |
329 | 340 | ||
330 | /* Control pipes have to worry about toggles */ | 341 | /* Control pipes don't have to worry about toggles */ |
331 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) | 342 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) |
332 | goto done; | 343 | goto done; |
333 | 344 | ||
@@ -493,6 +504,121 @@ static void uhci_make_qh_idle(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
493 | wake_up_all(&uhci->waitqh); | 504 | wake_up_all(&uhci->waitqh); |
494 | } | 505 | } |
495 | 506 | ||
507 | /* | ||
508 | * Find the highest existing bandwidth load for a given phase and period. | ||
509 | */ | ||
510 | static int uhci_highest_load(struct uhci_hcd *uhci, int phase, int period) | ||
511 | { | ||
512 | int highest_load = uhci->load[phase]; | ||
513 | |||
514 | for (phase += period; phase < MAX_PHASE; phase += period) | ||
515 | highest_load = max_t(int, highest_load, uhci->load[phase]); | ||
516 | return highest_load; | ||
517 | } | ||
518 | |||
519 | /* | ||
520 | * Set qh->phase to the optimal phase for a periodic transfer and | ||
521 | * check whether the bandwidth requirement is acceptable. | ||
522 | */ | ||
523 | static int uhci_check_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh) | ||
524 | { | ||
525 | int minimax_load; | ||
526 | |||
527 | /* Find the optimal phase (unless it is already set) and get | ||
528 | * its load value. */ | ||
529 | if (qh->phase >= 0) | ||
530 | minimax_load = uhci_highest_load(uhci, qh->phase, qh->period); | ||
531 | else { | ||
532 | int phase, load; | ||
533 | int max_phase = min_t(int, MAX_PHASE, qh->period); | ||
534 | |||
535 | qh->phase = 0; | ||
536 | minimax_load = uhci_highest_load(uhci, qh->phase, qh->period); | ||
537 | for (phase = 1; phase < max_phase; ++phase) { | ||
538 | load = uhci_highest_load(uhci, phase, qh->period); | ||
539 | if (load < minimax_load) { | ||
540 | minimax_load = load; | ||
541 | qh->phase = phase; | ||
542 | } | ||
543 | } | ||
544 | } | ||
545 | |||
546 | /* Maximum allowable periodic bandwidth is 90%, or 900 us per frame */ | ||
547 | if (minimax_load + qh->load > 900) { | ||
548 | dev_dbg(uhci_dev(uhci), "bandwidth allocation failed: " | ||
549 | "period %d, phase %d, %d + %d us\n", | ||
550 | qh->period, qh->phase, minimax_load, qh->load); | ||
551 | return -ENOSPC; | ||
552 | } | ||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | /* | ||
557 | * Reserve a periodic QH's bandwidth in the schedule | ||
558 | */ | ||
559 | static void uhci_reserve_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh) | ||
560 | { | ||
561 | int i; | ||
562 | int load = qh->load; | ||
563 | char *p = "??"; | ||
564 | |||
565 | for (i = qh->phase; i < MAX_PHASE; i += qh->period) { | ||
566 | uhci->load[i] += load; | ||
567 | uhci->total_load += load; | ||
568 | } | ||
569 | uhci_to_hcd(uhci)->self.bandwidth_allocated = | ||
570 | uhci->total_load / MAX_PHASE; | ||
571 | switch (qh->type) { | ||
572 | case USB_ENDPOINT_XFER_INT: | ||
573 | ++uhci_to_hcd(uhci)->self.bandwidth_int_reqs; | ||
574 | p = "INT"; | ||
575 | break; | ||
576 | case USB_ENDPOINT_XFER_ISOC: | ||
577 | ++uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs; | ||
578 | p = "ISO"; | ||
579 | break; | ||
580 | } | ||
581 | qh->bandwidth_reserved = 1; | ||
582 | dev_dbg(uhci_dev(uhci), | ||
583 | "%s dev %d ep%02x-%s, period %d, phase %d, %d us\n", | ||
584 | "reserve", qh->udev->devnum, | ||
585 | qh->hep->desc.bEndpointAddress, p, | ||
586 | qh->period, qh->phase, load); | ||
587 | } | ||
588 | |||
589 | /* | ||
590 | * Release a periodic QH's bandwidth reservation | ||
591 | */ | ||
592 | static void uhci_release_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh) | ||
593 | { | ||
594 | int i; | ||
595 | int load = qh->load; | ||
596 | char *p = "??"; | ||
597 | |||
598 | for (i = qh->phase; i < MAX_PHASE; i += qh->period) { | ||
599 | uhci->load[i] -= load; | ||
600 | uhci->total_load -= load; | ||
601 | } | ||
602 | uhci_to_hcd(uhci)->self.bandwidth_allocated = | ||
603 | uhci->total_load / MAX_PHASE; | ||
604 | switch (qh->type) { | ||
605 | case USB_ENDPOINT_XFER_INT: | ||
606 | --uhci_to_hcd(uhci)->self.bandwidth_int_reqs; | ||
607 | p = "INT"; | ||
608 | break; | ||
609 | case USB_ENDPOINT_XFER_ISOC: | ||
610 | --uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs; | ||
611 | p = "ISO"; | ||
612 | break; | ||
613 | } | ||
614 | qh->bandwidth_reserved = 0; | ||
615 | dev_dbg(uhci_dev(uhci), | ||
616 | "%s dev %d ep%02x-%s, period %d, phase %d, %d us\n", | ||
617 | "release", qh->udev->devnum, | ||
618 | qh->hep->desc.bEndpointAddress, p, | ||
619 | qh->period, qh->phase, load); | ||
620 | } | ||
621 | |||
496 | static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, | 622 | static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, |
497 | struct urb *urb) | 623 | struct urb *urb) |
498 | { | 624 | { |
@@ -796,7 +922,6 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
796 | wmb(); | 922 | wmb(); |
797 | qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); | 923 | qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); |
798 | qh->dummy_td = td; | 924 | qh->dummy_td = td; |
799 | qh->period = urb->interval; | ||
800 | 925 | ||
801 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), | 926 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), |
802 | usb_pipeout(urb->pipe), toggle); | 927 | usb_pipeout(urb->pipe), toggle); |
@@ -827,28 +952,42 @@ static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, | |||
827 | static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, | 952 | static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, |
828 | struct uhci_qh *qh) | 953 | struct uhci_qh *qh) |
829 | { | 954 | { |
830 | int exponent; | 955 | int ret; |
831 | 956 | ||
832 | /* USB 1.1 interrupt transfers only involve one packet per interval. | 957 | /* USB 1.1 interrupt transfers only involve one packet per interval. |
833 | * Drivers can submit URBs of any length, but longer ones will need | 958 | * Drivers can submit URBs of any length, but longer ones will need |
834 | * multiple intervals to complete. | 959 | * multiple intervals to complete. |
835 | */ | 960 | */ |
836 | 961 | ||
837 | /* Figure out which power-of-two queue to use */ | 962 | if (!qh->bandwidth_reserved) { |
838 | for (exponent = 7; exponent >= 0; --exponent) { | 963 | int exponent; |
839 | if ((1 << exponent) <= urb->interval) | ||
840 | break; | ||
841 | } | ||
842 | if (exponent < 0) | ||
843 | return -EINVAL; | ||
844 | urb->interval = 1 << exponent; | ||
845 | 964 | ||
846 | if (qh->period == 0) | 965 | /* Figure out which power-of-two queue to use */ |
966 | for (exponent = 7; exponent >= 0; --exponent) { | ||
967 | if ((1 << exponent) <= urb->interval) | ||
968 | break; | ||
969 | } | ||
970 | if (exponent < 0) | ||
971 | return -EINVAL; | ||
972 | qh->period = 1 << exponent; | ||
847 | qh->skel = uhci->skelqh[UHCI_SKEL_INDEX(exponent)]; | 973 | qh->skel = uhci->skelqh[UHCI_SKEL_INDEX(exponent)]; |
848 | else if (qh->period != urb->interval) | ||
849 | return -EINVAL; /* Can't change the period */ | ||
850 | 974 | ||
851 | return uhci_submit_common(uhci, urb, qh); | 975 | /* For now, interrupt phase is fixed by the layout |
976 | * of the QH lists. */ | ||
977 | qh->phase = (qh->period / 2) & (MAX_PHASE - 1); | ||
978 | ret = uhci_check_bandwidth(uhci, qh); | ||
979 | if (ret) | ||
980 | return ret; | ||
981 | } else if (qh->period > urb->interval) | ||
982 | return -EINVAL; /* Can't decrease the period */ | ||
983 | |||
984 | ret = uhci_submit_common(uhci, urb, qh); | ||
985 | if (ret == 0) { | ||
986 | urb->interval = qh->period; | ||
987 | if (!qh->bandwidth_reserved) | ||
988 | uhci_reserve_bandwidth(uhci, qh); | ||
989 | } | ||
990 | return ret; | ||
852 | } | 991 | } |
853 | 992 | ||
854 | /* | 993 | /* |
@@ -995,15 +1134,32 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, | |||
995 | return -EFBIG; | 1134 | return -EFBIG; |
996 | 1135 | ||
997 | /* Check the period and figure out the starting frame number */ | 1136 | /* Check the period and figure out the starting frame number */ |
998 | if (qh->period == 0) { | 1137 | if (!qh->bandwidth_reserved) { |
1138 | qh->period = urb->interval; | ||
999 | if (urb->transfer_flags & URB_ISO_ASAP) { | 1139 | if (urb->transfer_flags & URB_ISO_ASAP) { |
1140 | qh->phase = -1; /* Find the best phase */ | ||
1141 | i = uhci_check_bandwidth(uhci, qh); | ||
1142 | if (i) | ||
1143 | return i; | ||
1144 | |||
1145 | /* Allow a little time to allocate the TDs */ | ||
1000 | uhci_get_current_frame_number(uhci); | 1146 | uhci_get_current_frame_number(uhci); |
1001 | urb->start_frame = uhci->frame_number + 10; | 1147 | frame = uhci->frame_number + 10; |
1148 | |||
1149 | /* Move forward to the first frame having the | ||
1150 | * correct phase */ | ||
1151 | urb->start_frame = frame + ((qh->phase - frame) & | ||
1152 | (qh->period - 1)); | ||
1002 | } else { | 1153 | } else { |
1003 | i = urb->start_frame - uhci->last_iso_frame; | 1154 | i = urb->start_frame - uhci->last_iso_frame; |
1004 | if (i <= 0 || i >= UHCI_NUMFRAMES) | 1155 | if (i <= 0 || i >= UHCI_NUMFRAMES) |
1005 | return -EINVAL; | 1156 | return -EINVAL; |
1157 | qh->phase = urb->start_frame & (qh->period - 1); | ||
1158 | i = uhci_check_bandwidth(uhci, qh); | ||
1159 | if (i) | ||
1160 | return i; | ||
1006 | } | 1161 | } |
1162 | |||
1007 | } else if (qh->period != urb->interval) { | 1163 | } else if (qh->period != urb->interval) { |
1008 | return -EINVAL; /* Can't change the period */ | 1164 | return -EINVAL; /* Can't change the period */ |
1009 | 1165 | ||
@@ -1049,9 +1205,6 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, | |||
1049 | /* Set the interrupt-on-completion flag on the last packet. */ | 1205 | /* Set the interrupt-on-completion flag on the last packet. */ |
1050 | td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); | 1206 | td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); |
1051 | 1207 | ||
1052 | qh->skel = uhci->skel_iso_qh; | ||
1053 | qh->period = urb->interval; | ||
1054 | |||
1055 | /* Add the TDs to the frame list */ | 1208 | /* Add the TDs to the frame list */ |
1056 | frame = urb->start_frame; | 1209 | frame = urb->start_frame; |
1057 | list_for_each_entry(td, &urbp->td_list, list) { | 1210 | list_for_each_entry(td, &urbp->td_list, list) { |
@@ -1065,6 +1218,9 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, | |||
1065 | qh->iso_status = 0; | 1218 | qh->iso_status = 0; |
1066 | } | 1219 | } |
1067 | 1220 | ||
1221 | qh->skel = uhci->skel_iso_qh; | ||
1222 | if (!qh->bandwidth_reserved) | ||
1223 | uhci_reserve_bandwidth(uhci, qh); | ||
1068 | return 0; | 1224 | return 0; |
1069 | } | 1225 | } |
1070 | 1226 | ||
@@ -1119,7 +1275,6 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, | |||
1119 | unsigned long flags; | 1275 | unsigned long flags; |
1120 | struct urb_priv *urbp; | 1276 | struct urb_priv *urbp; |
1121 | struct uhci_qh *qh; | 1277 | struct uhci_qh *qh; |
1122 | int bustime; | ||
1123 | 1278 | ||
1124 | spin_lock_irqsave(&uhci->lock, flags); | 1279 | spin_lock_irqsave(&uhci->lock, flags); |
1125 | 1280 | ||
@@ -1149,35 +1304,11 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, | |||
1149 | ret = uhci_submit_bulk(uhci, urb, qh); | 1304 | ret = uhci_submit_bulk(uhci, urb, qh); |
1150 | break; | 1305 | break; |
1151 | case USB_ENDPOINT_XFER_INT: | 1306 | case USB_ENDPOINT_XFER_INT: |
1152 | if (list_empty(&qh->queue)) { | 1307 | ret = uhci_submit_interrupt(uhci, urb, qh); |
1153 | bustime = usb_check_bandwidth(urb->dev, urb); | ||
1154 | if (bustime < 0) | ||
1155 | ret = bustime; | ||
1156 | else { | ||
1157 | ret = uhci_submit_interrupt(uhci, urb, qh); | ||
1158 | if (ret == 0) | ||
1159 | usb_claim_bandwidth(urb->dev, urb, bustime, 0); | ||
1160 | } | ||
1161 | } else { /* inherit from parent */ | ||
1162 | struct urb_priv *eurbp; | ||
1163 | |||
1164 | eurbp = list_entry(qh->queue.prev, struct urb_priv, | ||
1165 | node); | ||
1166 | urb->bandwidth = eurbp->urb->bandwidth; | ||
1167 | ret = uhci_submit_interrupt(uhci, urb, qh); | ||
1168 | } | ||
1169 | break; | 1308 | break; |
1170 | case USB_ENDPOINT_XFER_ISOC: | 1309 | case USB_ENDPOINT_XFER_ISOC: |
1171 | urb->error_count = 0; | 1310 | urb->error_count = 0; |
1172 | bustime = usb_check_bandwidth(urb->dev, urb); | ||
1173 | if (bustime < 0) { | ||
1174 | ret = bustime; | ||
1175 | break; | ||
1176 | } | ||
1177 | |||
1178 | ret = uhci_submit_isochronous(uhci, urb, qh); | 1311 | ret = uhci_submit_isochronous(uhci, urb, qh); |
1179 | if (ret == 0) | ||
1180 | usb_claim_bandwidth(urb->dev, urb, bustime, 1); | ||
1181 | break; | 1312 | break; |
1182 | } | 1313 | } |
1183 | if (ret != 0) | 1314 | if (ret != 0) |
@@ -1274,24 +1405,6 @@ __acquires(uhci->lock) | |||
1274 | 1405 | ||
1275 | uhci_free_urb_priv(uhci, urbp); | 1406 | uhci_free_urb_priv(uhci, urbp); |
1276 | 1407 | ||
1277 | switch (qh->type) { | ||
1278 | case USB_ENDPOINT_XFER_ISOC: | ||
1279 | /* Release bandwidth for Interrupt or Isoc. transfers */ | ||
1280 | if (urb->bandwidth) | ||
1281 | usb_release_bandwidth(urb->dev, urb, 1); | ||
1282 | break; | ||
1283 | case USB_ENDPOINT_XFER_INT: | ||
1284 | /* Release bandwidth for Interrupt or Isoc. transfers */ | ||
1285 | /* Make sure we don't release if we have a queued URB */ | ||
1286 | if (list_empty(&qh->queue) && urb->bandwidth) | ||
1287 | usb_release_bandwidth(urb->dev, urb, 0); | ||
1288 | else | ||
1289 | /* bandwidth was passed on to queued URB, */ | ||
1290 | /* so don't let usb_unlink_urb() release it */ | ||
1291 | urb->bandwidth = 0; | ||
1292 | break; | ||
1293 | } | ||
1294 | |||
1295 | spin_unlock(&uhci->lock); | 1408 | spin_unlock(&uhci->lock); |
1296 | usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); | 1409 | usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); |
1297 | spin_lock(&uhci->lock); | 1410 | spin_lock(&uhci->lock); |
@@ -1300,9 +1413,8 @@ __acquires(uhci->lock) | |||
1300 | * reserved bandwidth. */ | 1413 | * reserved bandwidth. */ |
1301 | if (list_empty(&qh->queue)) { | 1414 | if (list_empty(&qh->queue)) { |
1302 | uhci_unlink_qh(uhci, qh); | 1415 | uhci_unlink_qh(uhci, qh); |
1303 | 1416 | if (qh->bandwidth_reserved) | |
1304 | /* Bandwidth stuff not yet implemented */ | 1417 | uhci_release_bandwidth(uhci, qh); |
1305 | qh->period = 0; | ||
1306 | } | 1418 | } |
1307 | } | 1419 | } |
1308 | 1420 | ||