diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 23:30:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 23:30:48 -0400 |
commit | 5cc103506289de7ee0a0b526ae0381541990cad4 (patch) | |
tree | ae8a4958e70c6d1295030b40e333dcc007b3c074 /drivers/usb/host | |
parent | 73ecf3a6e3f0206bf56a0fefe3b3eda042fb7034 (diff) | |
parent | 92ca0dc5ee022e4c0e488177e1d8865a0778c6c2 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (141 commits)
USB: mct_u232: fix broken close
USB: gadget: amd5536udc.c: fix error path
USB: imx21-hcd - fix off by one resource size calculation
usb: gadget: fix Kconfig warning
usb: r8a66597-udc: Add processing when USB was removed.
mxc_udc: add workaround for ENGcm09152 for i.MX35
USB: ftdi_sio: add device ids for ScienceScope
USB: musb: AM35x: Workaround for fifo read issue
USB: musb: add musb support for AM35x
USB: AM35x: Add musb support
usb: Fix linker errors with CONFIG_PM=n
USB: ohci-sh - use resource_size instead of defining its own resource_len macro
USB: isp1362-hcd - use resource_size instead of defining its own resource_len macro
USB: isp116x-hcd - use resource_size instead of defining its own resource_len macro
USB: xhci: Fix compile error when CONFIG_PM=n
USB: accept some invalid ep0-maxpacket values
USB: xHCI: PCI power management implementation
USB: xHCI: bus power management implementation
USB: xHCI: port remote wakeup implementation
USB: xHCI: port power management implementation
...
Manually fix up (non-data) conflict: the SCSI merge gad renamed the
'hw_sector_size' member to 'physical_block_size', and the USB tree
brought a new use of it.
Diffstat (limited to 'drivers/usb/host')
28 files changed, 1639 insertions, 241 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 2d926cec0725..bf2e7d234533 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -93,12 +93,14 @@ config USB_EHCI_TT_NEWSCHED | |||
93 | 93 | ||
94 | config USB_EHCI_BIG_ENDIAN_MMIO | 94 | config USB_EHCI_BIG_ENDIAN_MMIO |
95 | bool | 95 | bool |
96 | depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX) | 96 | depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX || \ |
97 | XPS_USB_HCD_XILINX || PPC_MPC512x) | ||
97 | default y | 98 | default y |
98 | 99 | ||
99 | config USB_EHCI_BIG_ENDIAN_DESC | 100 | config USB_EHCI_BIG_ENDIAN_DESC |
100 | bool | 101 | bool |
101 | depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX) | 102 | depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX || \ |
103 | PPC_MPC512x) | ||
102 | default y | 104 | default y |
103 | 105 | ||
104 | config XPS_USB_HCD_XILINX | 106 | config XPS_USB_HCD_XILINX |
@@ -112,10 +114,14 @@ config XPS_USB_HCD_XILINX | |||
112 | support both high speed and full speed devices, or high speed | 114 | support both high speed and full speed devices, or high speed |
113 | devices only. | 115 | devices only. |
114 | 116 | ||
117 | config USB_FSL_MPH_DR_OF | ||
118 | tristate | ||
119 | |||
115 | config USB_EHCI_FSL | 120 | config USB_EHCI_FSL |
116 | bool "Support for Freescale on-chip EHCI USB controller" | 121 | bool "Support for Freescale on-chip EHCI USB controller" |
117 | depends on USB_EHCI_HCD && FSL_SOC | 122 | depends on USB_EHCI_HCD && FSL_SOC |
118 | select USB_EHCI_ROOT_HUB_TT | 123 | select USB_EHCI_ROOT_HUB_TT |
124 | select USB_FSL_MPH_DR_OF | ||
119 | ---help--- | 125 | ---help--- |
120 | Variation of ARC USB block used in some Freescale chips. | 126 | Variation of ARC USB block used in some Freescale chips. |
121 | 127 | ||
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index b6315aa47f7a..91c5a1bd1026 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -2,17 +2,17 @@ | |||
2 | # Makefile for USB Host Controller Drivers | 2 | # Makefile for USB Host Controller Drivers |
3 | # | 3 | # |
4 | 4 | ||
5 | ifeq ($(CONFIG_USB_DEBUG),y) | 5 | ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG |
6 | EXTRA_CFLAGS += -DDEBUG | 6 | |
7 | endif | 7 | isp1760-y := isp1760-hcd.o isp1760-if.o |
8 | 8 | ||
9 | isp1760-objs := isp1760-hcd.o isp1760-if.o | 9 | fhci-y := fhci-hcd.o fhci-hub.o fhci-q.o |
10 | fhci-objs := fhci-hcd.o fhci-hub.o fhci-q.o fhci-mem.o \ | 10 | fhci-y += fhci-mem.o fhci-tds.o fhci-sched.o |
11 | fhci-tds.o fhci-sched.o | 11 | |
12 | ifeq ($(CONFIG_FHCI_DEBUG),y) | 12 | fhci-$(CONFIG_FHCI_DEBUG) += fhci-dbg.o |
13 | fhci-objs += fhci-dbg.o | 13 | |
14 | endif | 14 | xhci-hcd-y := xhci.o xhci-mem.o xhci-pci.o |
15 | xhci-hcd-objs := xhci.o xhci-mem.o xhci-pci.o xhci-ring.o xhci-hub.o xhci-dbg.o | 15 | xhci-hcd-y += xhci-ring.o xhci-hub.o xhci-dbg.o |
16 | 16 | ||
17 | obj-$(CONFIG_USB_WHCI_HCD) += whci/ | 17 | obj-$(CONFIG_USB_WHCI_HCD) += whci/ |
18 | 18 | ||
@@ -33,4 +33,4 @@ obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o | |||
33 | obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o | 33 | obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o |
34 | obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o | 34 | obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o |
35 | obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o | 35 | obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o |
36 | 36 | obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o | |
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index a416421abfa2..86e42892016d 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -116,13 +116,33 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, | |||
116 | goto err3; | 116 | goto err3; |
117 | } | 117 | } |
118 | 118 | ||
119 | /* Enable USB controller */ | 119 | pdata->regs = hcd->regs; |
120 | temp = in_be32(hcd->regs + 0x500); | ||
121 | out_be32(hcd->regs + 0x500, temp | 0x4); | ||
122 | 120 | ||
123 | /* Set to Host mode */ | 121 | /* |
124 | temp = in_le32(hcd->regs + 0x1a8); | 122 | * do platform specific init: check the clock, grab/config pins, etc. |
125 | out_le32(hcd->regs + 0x1a8, temp | 0x3); | 123 | */ |
124 | if (pdata->init && pdata->init(pdev)) { | ||
125 | retval = -ENODEV; | ||
126 | goto err3; | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * Check if it is MPC5121 SoC, otherwise set pdata->have_sysif_regs | ||
131 | * flag for 83xx or 8536 system interface registers. | ||
132 | */ | ||
133 | if (pdata->big_endian_mmio) | ||
134 | temp = in_be32(hcd->regs + FSL_SOC_USB_ID); | ||
135 | else | ||
136 | temp = in_le32(hcd->regs + FSL_SOC_USB_ID); | ||
137 | |||
138 | if ((temp & ID_MSK) != (~((temp & NID_MSK) >> 8) & ID_MSK)) | ||
139 | pdata->have_sysif_regs = 1; | ||
140 | |||
141 | /* Enable USB controller, 83xx or 8536 */ | ||
142 | if (pdata->have_sysif_regs) | ||
143 | setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4); | ||
144 | |||
145 | /* Don't need to set host mode here. It will be done by tdi_reset() */ | ||
126 | 146 | ||
127 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 147 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); |
128 | if (retval != 0) | 148 | if (retval != 0) |
@@ -137,6 +157,8 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, | |||
137 | usb_put_hcd(hcd); | 157 | usb_put_hcd(hcd); |
138 | err1: | 158 | err1: |
139 | dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval); | 159 | dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval); |
160 | if (pdata->exit) | ||
161 | pdata->exit(pdev); | ||
140 | return retval; | 162 | return retval; |
141 | } | 163 | } |
142 | 164 | ||
@@ -154,17 +176,30 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, | |||
154 | static void usb_hcd_fsl_remove(struct usb_hcd *hcd, | 176 | static void usb_hcd_fsl_remove(struct usb_hcd *hcd, |
155 | struct platform_device *pdev) | 177 | struct platform_device *pdev) |
156 | { | 178 | { |
179 | struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; | ||
180 | |||
157 | usb_remove_hcd(hcd); | 181 | usb_remove_hcd(hcd); |
182 | |||
183 | /* | ||
184 | * do platform specific un-initialization: | ||
185 | * release iomux pins, disable clock, etc. | ||
186 | */ | ||
187 | if (pdata->exit) | ||
188 | pdata->exit(pdev); | ||
158 | iounmap(hcd->regs); | 189 | iounmap(hcd->regs); |
159 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 190 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
160 | usb_put_hcd(hcd); | 191 | usb_put_hcd(hcd); |
161 | } | 192 | } |
162 | 193 | ||
163 | static void mpc83xx_setup_phy(struct ehci_hcd *ehci, | 194 | static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, |
164 | enum fsl_usb2_phy_modes phy_mode, | 195 | enum fsl_usb2_phy_modes phy_mode, |
165 | unsigned int port_offset) | 196 | unsigned int port_offset) |
166 | { | 197 | { |
167 | u32 portsc = 0; | 198 | u32 portsc; |
199 | |||
200 | portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); | ||
201 | portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); | ||
202 | |||
168 | switch (phy_mode) { | 203 | switch (phy_mode) { |
169 | case FSL_USB2_PHY_ULPI: | 204 | case FSL_USB2_PHY_ULPI: |
170 | portsc |= PORT_PTS_ULPI; | 205 | portsc |= PORT_PTS_ULPI; |
@@ -184,20 +219,21 @@ static void mpc83xx_setup_phy(struct ehci_hcd *ehci, | |||
184 | ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); | 219 | ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); |
185 | } | 220 | } |
186 | 221 | ||
187 | static void mpc83xx_usb_setup(struct usb_hcd *hcd) | 222 | static void ehci_fsl_usb_setup(struct ehci_hcd *ehci) |
188 | { | 223 | { |
189 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 224 | struct usb_hcd *hcd = ehci_to_hcd(ehci); |
190 | struct fsl_usb2_platform_data *pdata; | 225 | struct fsl_usb2_platform_data *pdata; |
191 | void __iomem *non_ehci = hcd->regs; | 226 | void __iomem *non_ehci = hcd->regs; |
192 | u32 temp; | 227 | u32 temp; |
193 | 228 | ||
194 | pdata = | 229 | pdata = hcd->self.controller->platform_data; |
195 | (struct fsl_usb2_platform_data *)hcd->self.controller-> | 230 | |
196 | platform_data; | ||
197 | /* Enable PHY interface in the control reg. */ | 231 | /* Enable PHY interface in the control reg. */ |
198 | temp = in_be32(non_ehci + FSL_SOC_USB_CTRL); | 232 | if (pdata->have_sysif_regs) { |
199 | out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | 0x00000004); | 233 | temp = in_be32(non_ehci + FSL_SOC_USB_CTRL); |
200 | out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b); | 234 | out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | 0x00000004); |
235 | out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b); | ||
236 | } | ||
201 | 237 | ||
202 | #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) | 238 | #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) |
203 | /* | 239 | /* |
@@ -214,7 +250,7 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd) | |||
214 | 250 | ||
215 | if ((pdata->operating_mode == FSL_USB2_DR_HOST) || | 251 | if ((pdata->operating_mode == FSL_USB2_DR_HOST) || |
216 | (pdata->operating_mode == FSL_USB2_DR_OTG)) | 252 | (pdata->operating_mode == FSL_USB2_DR_OTG)) |
217 | mpc83xx_setup_phy(ehci, pdata->phy_mode, 0); | 253 | ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0); |
218 | 254 | ||
219 | if (pdata->operating_mode == FSL_USB2_MPH_HOST) { | 255 | if (pdata->operating_mode == FSL_USB2_MPH_HOST) { |
220 | unsigned int chip, rev, svr; | 256 | unsigned int chip, rev, svr; |
@@ -228,27 +264,27 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd) | |||
228 | ehci->has_fsl_port_bug = 1; | 264 | ehci->has_fsl_port_bug = 1; |
229 | 265 | ||
230 | if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) | 266 | if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) |
231 | mpc83xx_setup_phy(ehci, pdata->phy_mode, 0); | 267 | ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0); |
232 | if (pdata->port_enables & FSL_USB2_PORT1_ENABLED) | 268 | if (pdata->port_enables & FSL_USB2_PORT1_ENABLED) |
233 | mpc83xx_setup_phy(ehci, pdata->phy_mode, 1); | 269 | ehci_fsl_setup_phy(ehci, pdata->phy_mode, 1); |
234 | } | 270 | } |
235 | 271 | ||
236 | /* put controller in host mode. */ | 272 | if (pdata->have_sysif_regs) { |
237 | ehci_writel(ehci, 0x00000003, non_ehci + FSL_SOC_USB_USBMODE); | ||
238 | #ifdef CONFIG_PPC_85xx | 273 | #ifdef CONFIG_PPC_85xx |
239 | out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x00000008); | 274 | out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x00000008); |
240 | out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000080); | 275 | out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000080); |
241 | #else | 276 | #else |
242 | out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c); | 277 | out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c); |
243 | out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040); | 278 | out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040); |
244 | #endif | 279 | #endif |
245 | out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001); | 280 | out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001); |
281 | } | ||
246 | } | 282 | } |
247 | 283 | ||
248 | /* called after powerup, by probe or system-pm "wakeup" */ | 284 | /* called after powerup, by probe or system-pm "wakeup" */ |
249 | static int ehci_fsl_reinit(struct ehci_hcd *ehci) | 285 | static int ehci_fsl_reinit(struct ehci_hcd *ehci) |
250 | { | 286 | { |
251 | mpc83xx_usb_setup(ehci_to_hcd(ehci)); | 287 | ehci_fsl_usb_setup(ehci); |
252 | ehci_port_power(ehci, 0); | 288 | ehci_port_power(ehci, 0); |
253 | 289 | ||
254 | return 0; | 290 | return 0; |
@@ -259,6 +295,11 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) | |||
259 | { | 295 | { |
260 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 296 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
261 | int retval; | 297 | int retval; |
298 | struct fsl_usb2_platform_data *pdata; | ||
299 | |||
300 | pdata = hcd->self.controller->platform_data; | ||
301 | ehci->big_endian_desc = pdata->big_endian_desc; | ||
302 | ehci->big_endian_mmio = pdata->big_endian_mmio; | ||
262 | 303 | ||
263 | /* EHCI registers start at offset 0x100 */ | 304 | /* EHCI registers start at offset 0x100 */ |
264 | ehci->caps = hcd->regs + 0x100; | 305 | ehci->caps = hcd->regs + 0x100; |
@@ -270,6 +311,8 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) | |||
270 | /* cache this readonly data; minimize chip reads */ | 311 | /* cache this readonly data; minimize chip reads */ |
271 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | 312 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
272 | 313 | ||
314 | hcd->has_tt = 1; | ||
315 | |||
273 | retval = ehci_halt(ehci); | 316 | retval = ehci_halt(ehci); |
274 | if (retval) | 317 | if (retval) |
275 | return retval; | 318 | return retval; |
@@ -279,8 +322,6 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) | |||
279 | if (retval) | 322 | if (retval) |
280 | return retval; | 323 | return retval; |
281 | 324 | ||
282 | hcd->has_tt = 1; | ||
283 | |||
284 | ehci->sbrn = 0x20; | 325 | ehci->sbrn = 0x20; |
285 | 326 | ||
286 | ehci_reset(ehci); | 327 | ehci_reset(ehci); |
@@ -372,7 +413,7 @@ static const struct hc_driver ehci_fsl_hc_driver = { | |||
372 | * generic hardware linkage | 413 | * generic hardware linkage |
373 | */ | 414 | */ |
374 | .irq = ehci_irq, | 415 | .irq = ehci_irq, |
375 | .flags = HCD_USB2, | 416 | .flags = HCD_USB2 | HCD_MEMORY, |
376 | 417 | ||
377 | /* | 418 | /* |
378 | * basic lifecycle operations | 419 | * basic lifecycle operations |
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h index b5e59db53347..2c8353795226 100644 --- a/drivers/usb/host/ehci-fsl.h +++ b/drivers/usb/host/ehci-fsl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Copyright (c) 2005 freescale semiconductor | 1 | /* Copyright (C) 2005-2010 Freescale Semiconductor, Inc. |
2 | * Copyright (c) 2005 MontaVista Software | 2 | * Copyright (c) 2005 MontaVista Software |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
@@ -19,6 +19,9 @@ | |||
19 | #define _EHCI_FSL_H | 19 | #define _EHCI_FSL_H |
20 | 20 | ||
21 | /* offsets for the non-ehci registers in the FSL SOC USB controller */ | 21 | /* offsets for the non-ehci registers in the FSL SOC USB controller */ |
22 | #define FSL_SOC_USB_ID 0x0 | ||
23 | #define ID_MSK 0x3f | ||
24 | #define NID_MSK 0x3f00 | ||
22 | #define FSL_SOC_USB_ULPIVP 0x170 | 25 | #define FSL_SOC_USB_ULPIVP 0x170 |
23 | #define FSL_SOC_USB_PORTSC1 0x184 | 26 | #define FSL_SOC_USB_PORTSC1 0x184 |
24 | #define PORT_PTS_MSK (3<<30) | 27 | #define PORT_PTS_MSK (3<<30) |
@@ -27,7 +30,14 @@ | |||
27 | #define PORT_PTS_SERIAL (3<<30) | 30 | #define PORT_PTS_SERIAL (3<<30) |
28 | #define PORT_PTS_PTW (1<<28) | 31 | #define PORT_PTS_PTW (1<<28) |
29 | #define FSL_SOC_USB_PORTSC2 0x188 | 32 | #define FSL_SOC_USB_PORTSC2 0x188 |
30 | #define FSL_SOC_USB_USBMODE 0x1a8 | 33 | |
34 | #define FSL_SOC_USB_USBGENCTRL 0x200 | ||
35 | #define USBGENCTRL_PPP (1 << 3) | ||
36 | #define USBGENCTRL_PFP (1 << 2) | ||
37 | #define FSL_SOC_USB_ISIPHYCTRL 0x204 | ||
38 | #define ISIPHYCTRL_PXE (1) | ||
39 | #define ISIPHYCTRL_PHYE (1 << 4) | ||
40 | |||
31 | #define FSL_SOC_USB_SNOOP1 0x400 /* NOTE: big-endian */ | 41 | #define FSL_SOC_USB_SNOOP1 0x400 /* NOTE: big-endian */ |
32 | #define FSL_SOC_USB_SNOOP2 0x404 /* NOTE: big-endian */ | 42 | #define FSL_SOC_USB_SNOOP2 0x404 /* NOTE: big-endian */ |
33 | #define FSL_SOC_USB_AGECNTTHRSH 0x408 /* NOTE: big-endian */ | 43 | #define FSL_SOC_USB_AGECNTTHRSH 0x408 /* NOTE: big-endian */ |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 34a928d3b7d2..15fe3ecd203b 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -194,6 +194,17 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr, | |||
194 | return -ETIMEDOUT; | 194 | return -ETIMEDOUT; |
195 | } | 195 | } |
196 | 196 | ||
197 | /* check TDI/ARC silicon is in host mode */ | ||
198 | static int tdi_in_host_mode (struct ehci_hcd *ehci) | ||
199 | { | ||
200 | u32 __iomem *reg_ptr; | ||
201 | u32 tmp; | ||
202 | |||
203 | reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + USBMODE); | ||
204 | tmp = ehci_readl(ehci, reg_ptr); | ||
205 | return (tmp & 3) == USBMODE_CM_HC; | ||
206 | } | ||
207 | |||
197 | /* force HC to halt state from unknown (EHCI spec section 2.3) */ | 208 | /* force HC to halt state from unknown (EHCI spec section 2.3) */ |
198 | static int ehci_halt (struct ehci_hcd *ehci) | 209 | static int ehci_halt (struct ehci_hcd *ehci) |
199 | { | 210 | { |
@@ -202,6 +213,10 @@ static int ehci_halt (struct ehci_hcd *ehci) | |||
202 | /* disable any irqs left enabled by previous code */ | 213 | /* disable any irqs left enabled by previous code */ |
203 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); | 214 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
204 | 215 | ||
216 | if (ehci_is_TDI(ehci) && tdi_in_host_mode(ehci) == 0) { | ||
217 | return 0; | ||
218 | } | ||
219 | |||
205 | if ((temp & STS_HALT) != 0) | 220 | if ((temp & STS_HALT) != 0) |
206 | return 0; | 221 | return 0; |
207 | 222 | ||
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 1f3f01eacaf0..d36e4e75e08d 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c | |||
@@ -40,7 +40,7 @@ static inline void ehci_qtd_init(struct ehci_hcd *ehci, struct ehci_qtd *qtd, | |||
40 | { | 40 | { |
41 | memset (qtd, 0, sizeof *qtd); | 41 | memset (qtd, 0, sizeof *qtd); |
42 | qtd->qtd_dma = dma; | 42 | qtd->qtd_dma = dma; |
43 | qtd->hw_token = cpu_to_le32 (QTD_STS_HALT); | 43 | qtd->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT); |
44 | qtd->hw_next = EHCI_LIST_END(ehci); | 44 | qtd->hw_next = EHCI_LIST_END(ehci); |
45 | qtd->hw_alt_next = EHCI_LIST_END(ehci); | 45 | qtd->hw_alt_next = EHCI_LIST_END(ehci); |
46 | INIT_LIST_HEAD (&qtd->qtd_list); | 46 | INIT_LIST_HEAD (&qtd->qtd_list); |
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index a8ad8ac120a2..ac9c4d7c44af 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c | |||
@@ -26,9 +26,6 @@ | |||
26 | #include <mach/mxc_ehci.h> | 26 | #include <mach/mxc_ehci.h> |
27 | 27 | ||
28 | #define ULPI_VIEWPORT_OFFSET 0x170 | 28 | #define ULPI_VIEWPORT_OFFSET 0x170 |
29 | #define PORTSC_OFFSET 0x184 | ||
30 | #define USBMODE_OFFSET 0x1a8 | ||
31 | #define USBMODE_CM_HOST 3 | ||
32 | 29 | ||
33 | struct ehci_mxc_priv { | 30 | struct ehci_mxc_priv { |
34 | struct clk *usbclk, *ahbclk; | 31 | struct clk *usbclk, *ahbclk; |
@@ -51,6 +48,8 @@ static int ehci_mxc_setup(struct usb_hcd *hcd) | |||
51 | /* cache this readonly data; minimize chip reads */ | 48 | /* cache this readonly data; minimize chip reads */ |
52 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | 49 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
53 | 50 | ||
51 | hcd->has_tt = 1; | ||
52 | |||
54 | retval = ehci_halt(ehci); | 53 | retval = ehci_halt(ehci); |
55 | if (retval) | 54 | if (retval) |
56 | return retval; | 55 | return retval; |
@@ -60,8 +59,6 @@ static int ehci_mxc_setup(struct usb_hcd *hcd) | |||
60 | if (retval) | 59 | if (retval) |
61 | return retval; | 60 | return retval; |
62 | 61 | ||
63 | hcd->has_tt = 1; | ||
64 | |||
65 | ehci->sbrn = 0x20; | 62 | ehci->sbrn = 0x20; |
66 | 63 | ||
67 | ehci_reset(ehci); | 64 | ehci_reset(ehci); |
@@ -191,12 +188,8 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) | |||
191 | clk_enable(priv->ahbclk); | 188 | clk_enable(priv->ahbclk); |
192 | } | 189 | } |
193 | 190 | ||
194 | /* set USBMODE to host mode */ | ||
195 | temp = readl(hcd->regs + USBMODE_OFFSET); | ||
196 | writel(temp | USBMODE_CM_HOST, hcd->regs + USBMODE_OFFSET); | ||
197 | |||
198 | /* set up the PORTSCx register */ | 191 | /* set up the PORTSCx register */ |
199 | writel(pdata->portsc, hcd->regs + PORTSC_OFFSET); | 192 | ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]); |
200 | mdelay(10); | 193 | mdelay(10); |
201 | 194 | ||
202 | /* setup specific usb hw */ | 195 | /* setup specific usb hw */ |
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c new file mode 100644 index 000000000000..574b99ea0700 --- /dev/null +++ b/drivers/usb/host/fsl-mph-dr-of.c | |||
@@ -0,0 +1,308 @@ | |||
1 | /* | ||
2 | * Setup platform devices needed by the Freescale multi-port host | ||
3 | * and/or dual-role USB controller modules based on the description | ||
4 | * in flat device tree. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/fsl_devices.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/of_platform.h> | ||
18 | #include <linux/clk.h> | ||
19 | |||
20 | struct fsl_usb2_dev_data { | ||
21 | char *dr_mode; /* controller mode */ | ||
22 | char *drivers[3]; /* drivers to instantiate for this mode */ | ||
23 | enum fsl_usb2_operating_modes op_mode; /* operating mode */ | ||
24 | }; | ||
25 | |||
26 | struct fsl_usb2_dev_data dr_mode_data[] __devinitdata = { | ||
27 | { | ||
28 | .dr_mode = "host", | ||
29 | .drivers = { "fsl-ehci", NULL, NULL, }, | ||
30 | .op_mode = FSL_USB2_DR_HOST, | ||
31 | }, | ||
32 | { | ||
33 | .dr_mode = "otg", | ||
34 | .drivers = { "fsl-usb2-otg", "fsl-ehci", "fsl-usb2-udc", }, | ||
35 | .op_mode = FSL_USB2_DR_OTG, | ||
36 | }, | ||
37 | { | ||
38 | .dr_mode = "peripheral", | ||
39 | .drivers = { "fsl-usb2-udc", NULL, NULL, }, | ||
40 | .op_mode = FSL_USB2_DR_DEVICE, | ||
41 | }, | ||
42 | }; | ||
43 | |||
44 | struct fsl_usb2_dev_data * __devinit get_dr_mode_data(struct device_node *np) | ||
45 | { | ||
46 | const unsigned char *prop; | ||
47 | int i; | ||
48 | |||
49 | prop = of_get_property(np, "dr_mode", NULL); | ||
50 | if (prop) { | ||
51 | for (i = 0; i < ARRAY_SIZE(dr_mode_data); i++) { | ||
52 | if (!strcmp(prop, dr_mode_data[i].dr_mode)) | ||
53 | return &dr_mode_data[i]; | ||
54 | } | ||
55 | } | ||
56 | pr_warn("%s: Invalid 'dr_mode' property, fallback to host mode\n", | ||
57 | np->full_name); | ||
58 | return &dr_mode_data[0]; /* mode not specified, use host */ | ||
59 | } | ||
60 | |||
61 | static enum fsl_usb2_phy_modes __devinit determine_usb_phy(const char *phy_type) | ||
62 | { | ||
63 | if (!phy_type) | ||
64 | return FSL_USB2_PHY_NONE; | ||
65 | if (!strcasecmp(phy_type, "ulpi")) | ||
66 | return FSL_USB2_PHY_ULPI; | ||
67 | if (!strcasecmp(phy_type, "utmi")) | ||
68 | return FSL_USB2_PHY_UTMI; | ||
69 | if (!strcasecmp(phy_type, "utmi_wide")) | ||
70 | return FSL_USB2_PHY_UTMI_WIDE; | ||
71 | if (!strcasecmp(phy_type, "serial")) | ||
72 | return FSL_USB2_PHY_SERIAL; | ||
73 | |||
74 | return FSL_USB2_PHY_NONE; | ||
75 | } | ||
76 | |||
77 | struct platform_device * __devinit fsl_usb2_device_register( | ||
78 | struct platform_device *ofdev, | ||
79 | struct fsl_usb2_platform_data *pdata, | ||
80 | const char *name, int id) | ||
81 | { | ||
82 | struct platform_device *pdev; | ||
83 | const struct resource *res = ofdev->resource; | ||
84 | unsigned int num = ofdev->num_resources; | ||
85 | int retval; | ||
86 | |||
87 | pdev = platform_device_alloc(name, id); | ||
88 | if (!pdev) { | ||
89 | retval = -ENOMEM; | ||
90 | goto error; | ||
91 | } | ||
92 | |||
93 | pdev->dev.parent = &ofdev->dev; | ||
94 | |||
95 | pdev->dev.coherent_dma_mask = ofdev->dev.coherent_dma_mask; | ||
96 | pdev->dev.dma_mask = &pdev->archdata.dma_mask; | ||
97 | *pdev->dev.dma_mask = *ofdev->dev.dma_mask; | ||
98 | |||
99 | retval = platform_device_add_data(pdev, pdata, sizeof(*pdata)); | ||
100 | if (retval) | ||
101 | goto error; | ||
102 | |||
103 | if (num) { | ||
104 | retval = platform_device_add_resources(pdev, res, num); | ||
105 | if (retval) | ||
106 | goto error; | ||
107 | } | ||
108 | |||
109 | retval = platform_device_add(pdev); | ||
110 | if (retval) | ||
111 | goto error; | ||
112 | |||
113 | return pdev; | ||
114 | |||
115 | error: | ||
116 | platform_device_put(pdev); | ||
117 | return ERR_PTR(retval); | ||
118 | } | ||
119 | |||
120 | static const struct of_device_id fsl_usb2_mph_dr_of_match[]; | ||
121 | |||
122 | static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) | ||
123 | { | ||
124 | struct device_node *np = ofdev->dev.of_node; | ||
125 | struct platform_device *usb_dev; | ||
126 | struct fsl_usb2_platform_data data, *pdata; | ||
127 | struct fsl_usb2_dev_data *dev_data; | ||
128 | const struct of_device_id *match; | ||
129 | const unsigned char *prop; | ||
130 | static unsigned int idx; | ||
131 | int i; | ||
132 | |||
133 | if (!of_device_is_available(np)) | ||
134 | return -ENODEV; | ||
135 | |||
136 | match = of_match_device(fsl_usb2_mph_dr_of_match, &ofdev->dev); | ||
137 | if (!match) | ||
138 | return -ENODEV; | ||
139 | |||
140 | pdata = &data; | ||
141 | if (match->data) | ||
142 | memcpy(pdata, match->data, sizeof(data)); | ||
143 | else | ||
144 | memset(pdata, 0, sizeof(data)); | ||
145 | |||
146 | dev_data = get_dr_mode_data(np); | ||
147 | |||
148 | if (of_device_is_compatible(np, "fsl-usb2-mph")) { | ||
149 | if (of_get_property(np, "port0", NULL)) | ||
150 | pdata->port_enables |= FSL_USB2_PORT0_ENABLED; | ||
151 | |||
152 | if (of_get_property(np, "port1", NULL)) | ||
153 | pdata->port_enables |= FSL_USB2_PORT1_ENABLED; | ||
154 | |||
155 | pdata->operating_mode = FSL_USB2_MPH_HOST; | ||
156 | } else { | ||
157 | if (of_get_property(np, "fsl,invert-drvvbus", NULL)) | ||
158 | pdata->invert_drvvbus = 1; | ||
159 | |||
160 | if (of_get_property(np, "fsl,invert-pwr-fault", NULL)) | ||
161 | pdata->invert_pwr_fault = 1; | ||
162 | |||
163 | /* setup mode selected in the device tree */ | ||
164 | pdata->operating_mode = dev_data->op_mode; | ||
165 | } | ||
166 | |||
167 | prop = of_get_property(np, "phy_type", NULL); | ||
168 | pdata->phy_mode = determine_usb_phy(prop); | ||
169 | |||
170 | for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) { | ||
171 | if (!dev_data->drivers[i]) | ||
172 | continue; | ||
173 | usb_dev = fsl_usb2_device_register(ofdev, pdata, | ||
174 | dev_data->drivers[i], idx); | ||
175 | if (IS_ERR(usb_dev)) { | ||
176 | dev_err(&ofdev->dev, "Can't register usb device\n"); | ||
177 | return PTR_ERR(usb_dev); | ||
178 | } | ||
179 | } | ||
180 | idx++; | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int __devexit __unregister_subdev(struct device *dev, void *d) | ||
185 | { | ||
186 | platform_device_unregister(to_platform_device(dev)); | ||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | static int __devexit fsl_usb2_mph_dr_of_remove(struct platform_device *ofdev) | ||
191 | { | ||
192 | device_for_each_child(&ofdev->dev, NULL, __unregister_subdev); | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | #ifdef CONFIG_PPC_MPC512x | ||
197 | |||
198 | #define USBGENCTRL 0x200 /* NOTE: big endian */ | ||
199 | #define GC_WU_INT_CLR (1 << 5) /* Wakeup int clear */ | ||
200 | #define GC_ULPI_SEL (1 << 4) /* ULPI i/f select (usb0 only)*/ | ||
201 | #define GC_PPP (1 << 3) /* Inv. Port Power Polarity */ | ||
202 | #define GC_PFP (1 << 2) /* Inv. Power Fault Polarity */ | ||
203 | #define GC_WU_ULPI_EN (1 << 1) /* Wakeup on ULPI event */ | ||
204 | #define GC_WU_IE (1 << 1) /* Wakeup interrupt enable */ | ||
205 | |||
206 | #define ISIPHYCTRL 0x204 /* NOTE: big endian */ | ||
207 | #define PHYCTRL_PHYE (1 << 4) /* On-chip UTMI PHY enable */ | ||
208 | #define PHYCTRL_BSENH (1 << 3) /* Bit Stuff Enable High */ | ||
209 | #define PHYCTRL_BSEN (1 << 2) /* Bit Stuff Enable */ | ||
210 | #define PHYCTRL_LSFE (1 << 1) /* Line State Filter Enable */ | ||
211 | #define PHYCTRL_PXE (1 << 0) /* PHY oscillator enable */ | ||
212 | |||
213 | int fsl_usb2_mpc5121_init(struct platform_device *pdev) | ||
214 | { | ||
215 | struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; | ||
216 | struct clk *clk; | ||
217 | char clk_name[10]; | ||
218 | int base, clk_num; | ||
219 | |||
220 | base = pdev->resource->start & 0xf000; | ||
221 | if (base == 0x3000) | ||
222 | clk_num = 1; | ||
223 | else if (base == 0x4000) | ||
224 | clk_num = 2; | ||
225 | else | ||
226 | return -ENODEV; | ||
227 | |||
228 | snprintf(clk_name, sizeof(clk_name), "usb%d_clk", clk_num); | ||
229 | clk = clk_get(&pdev->dev, clk_name); | ||
230 | if (IS_ERR(clk)) { | ||
231 | dev_err(&pdev->dev, "failed to get clk\n"); | ||
232 | return PTR_ERR(clk); | ||
233 | } | ||
234 | |||
235 | clk_enable(clk); | ||
236 | pdata->clk = clk; | ||
237 | |||
238 | if (pdata->phy_mode == FSL_USB2_PHY_UTMI_WIDE) { | ||
239 | u32 reg = 0; | ||
240 | |||
241 | if (pdata->invert_drvvbus) | ||
242 | reg |= GC_PPP; | ||
243 | |||
244 | if (pdata->invert_pwr_fault) | ||
245 | reg |= GC_PFP; | ||
246 | |||
247 | out_be32(pdata->regs + ISIPHYCTRL, PHYCTRL_PHYE | PHYCTRL_PXE); | ||
248 | out_be32(pdata->regs + USBGENCTRL, reg); | ||
249 | } | ||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | static void fsl_usb2_mpc5121_exit(struct platform_device *pdev) | ||
254 | { | ||
255 | struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; | ||
256 | |||
257 | pdata->regs = NULL; | ||
258 | |||
259 | if (pdata->clk) { | ||
260 | clk_disable(pdata->clk); | ||
261 | clk_put(pdata->clk); | ||
262 | } | ||
263 | } | ||
264 | |||
265 | struct fsl_usb2_platform_data fsl_usb2_mpc5121_pd = { | ||
266 | .big_endian_desc = 1, | ||
267 | .big_endian_mmio = 1, | ||
268 | .es = 1, | ||
269 | .le_setup_buf = 1, | ||
270 | .init = fsl_usb2_mpc5121_init, | ||
271 | .exit = fsl_usb2_mpc5121_exit, | ||
272 | }; | ||
273 | #endif /* CONFIG_PPC_MPC512x */ | ||
274 | |||
275 | static const struct of_device_id fsl_usb2_mph_dr_of_match[] = { | ||
276 | { .compatible = "fsl-usb2-mph", }, | ||
277 | { .compatible = "fsl-usb2-dr", }, | ||
278 | #ifdef CONFIG_PPC_MPC512x | ||
279 | { .compatible = "fsl,mpc5121-usb2-dr", .data = &fsl_usb2_mpc5121_pd, }, | ||
280 | #endif | ||
281 | {}, | ||
282 | }; | ||
283 | |||
284 | static struct platform_driver fsl_usb2_mph_dr_driver = { | ||
285 | .driver = { | ||
286 | .name = "fsl-usb2-mph-dr", | ||
287 | .owner = THIS_MODULE, | ||
288 | .of_match_table = fsl_usb2_mph_dr_of_match, | ||
289 | }, | ||
290 | .probe = fsl_usb2_mph_dr_of_probe, | ||
291 | .remove = __devexit_p(fsl_usb2_mph_dr_of_remove), | ||
292 | }; | ||
293 | |||
294 | static int __init fsl_usb2_mph_dr_init(void) | ||
295 | { | ||
296 | return platform_driver_register(&fsl_usb2_mph_dr_driver); | ||
297 | } | ||
298 | module_init(fsl_usb2_mph_dr_init); | ||
299 | |||
300 | static void __exit fsl_usb2_mph_dr_exit(void) | ||
301 | { | ||
302 | platform_driver_unregister(&fsl_usb2_mph_dr_driver); | ||
303 | } | ||
304 | module_exit(fsl_usb2_mph_dr_exit); | ||
305 | |||
306 | MODULE_DESCRIPTION("FSL MPH DR OF devices driver"); | ||
307 | MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>"); | ||
308 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index 3e5630369c31..1dfb2c8f7707 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/slab.h> | 57 | #include <linux/slab.h> |
58 | #include <linux/usb.h> | 58 | #include <linux/usb.h> |
59 | #include <linux/usb/hcd.h> | 59 | #include <linux/usb/hcd.h> |
60 | #include <linux/dma-mapping.h> | ||
60 | 61 | ||
61 | #include "imx21-hcd.h" | 62 | #include "imx21-hcd.h" |
62 | 63 | ||
@@ -136,9 +137,18 @@ static int imx21_hc_get_frame(struct usb_hcd *hcd) | |||
136 | return wrap_frame(readl(imx21->regs + USBH_FRMNUB)); | 137 | return wrap_frame(readl(imx21->regs + USBH_FRMNUB)); |
137 | } | 138 | } |
138 | 139 | ||
140 | static inline bool unsuitable_for_dma(dma_addr_t addr) | ||
141 | { | ||
142 | return (addr & 3) != 0; | ||
143 | } | ||
139 | 144 | ||
140 | #include "imx21-dbg.c" | 145 | #include "imx21-dbg.c" |
141 | 146 | ||
147 | static void nonisoc_urb_completed_for_etd( | ||
148 | struct imx21 *imx21, struct etd_priv *etd, int status); | ||
149 | static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb); | ||
150 | static void free_dmem(struct imx21 *imx21, struct etd_priv *etd); | ||
151 | |||
142 | /* =========================================== */ | 152 | /* =========================================== */ |
143 | /* ETD management */ | 153 | /* ETD management */ |
144 | /* =========================================== */ | 154 | /* =========================================== */ |
@@ -185,7 +195,8 @@ static void reset_etd(struct imx21 *imx21, int num) | |||
185 | etd_writel(imx21, num, i, 0); | 195 | etd_writel(imx21, num, i, 0); |
186 | etd->urb = NULL; | 196 | etd->urb = NULL; |
187 | etd->ep = NULL; | 197 | etd->ep = NULL; |
188 | etd->td = NULL;; | 198 | etd->td = NULL; |
199 | etd->bounce_buffer = NULL; | ||
189 | } | 200 | } |
190 | 201 | ||
191 | static void free_etd(struct imx21 *imx21, int num) | 202 | static void free_etd(struct imx21 *imx21, int num) |
@@ -221,26 +232,94 @@ static void setup_etd_dword0(struct imx21 *imx21, | |||
221 | ((u32) maxpacket << DW0_MAXPKTSIZ)); | 232 | ((u32) maxpacket << DW0_MAXPKTSIZ)); |
222 | } | 233 | } |
223 | 234 | ||
224 | static void activate_etd(struct imx21 *imx21, | 235 | /** |
225 | int etd_num, dma_addr_t dma, u8 dir) | 236 | * Copy buffer to data controller data memory. |
237 | * We cannot use memcpy_toio() because the hardware requires 32bit writes | ||
238 | */ | ||
239 | static void copy_to_dmem( | ||
240 | struct imx21 *imx21, int dmem_offset, void *src, int count) | ||
241 | { | ||
242 | void __iomem *dmem = imx21->regs + USBOTG_DMEM + dmem_offset; | ||
243 | u32 word = 0; | ||
244 | u8 *p = src; | ||
245 | int byte = 0; | ||
246 | int i; | ||
247 | |||
248 | for (i = 0; i < count; i++) { | ||
249 | byte = i % 4; | ||
250 | word += (*p++ << (byte * 8)); | ||
251 | if (byte == 3) { | ||
252 | writel(word, dmem); | ||
253 | dmem += 4; | ||
254 | word = 0; | ||
255 | } | ||
256 | } | ||
257 | |||
258 | if (count && byte != 3) | ||
259 | writel(word, dmem); | ||
260 | } | ||
261 | |||
262 | static void activate_etd(struct imx21 *imx21, int etd_num, u8 dir) | ||
226 | { | 263 | { |
227 | u32 etd_mask = 1 << etd_num; | 264 | u32 etd_mask = 1 << etd_num; |
228 | struct etd_priv *etd = &imx21->etd[etd_num]; | 265 | struct etd_priv *etd = &imx21->etd[etd_num]; |
229 | 266 | ||
267 | if (etd->dma_handle && unsuitable_for_dma(etd->dma_handle)) { | ||
268 | /* For non aligned isoc the condition below is always true */ | ||
269 | if (etd->len <= etd->dmem_size) { | ||
270 | /* Fits into data memory, use PIO */ | ||
271 | if (dir != TD_DIR_IN) { | ||
272 | copy_to_dmem(imx21, | ||
273 | etd->dmem_offset, | ||
274 | etd->cpu_buffer, etd->len); | ||
275 | } | ||
276 | etd->dma_handle = 0; | ||
277 | |||
278 | } else { | ||
279 | /* Too big for data memory, use bounce buffer */ | ||
280 | enum dma_data_direction dmadir; | ||
281 | |||
282 | if (dir == TD_DIR_IN) { | ||
283 | dmadir = DMA_FROM_DEVICE; | ||
284 | etd->bounce_buffer = kmalloc(etd->len, | ||
285 | GFP_ATOMIC); | ||
286 | } else { | ||
287 | dmadir = DMA_TO_DEVICE; | ||
288 | etd->bounce_buffer = kmemdup(etd->cpu_buffer, | ||
289 | etd->len, | ||
290 | GFP_ATOMIC); | ||
291 | } | ||
292 | if (!etd->bounce_buffer) { | ||
293 | dev_err(imx21->dev, "failed bounce alloc\n"); | ||
294 | goto err_bounce_alloc; | ||
295 | } | ||
296 | |||
297 | etd->dma_handle = | ||
298 | dma_map_single(imx21->dev, | ||
299 | etd->bounce_buffer, | ||
300 | etd->len, | ||
301 | dmadir); | ||
302 | if (dma_mapping_error(imx21->dev, etd->dma_handle)) { | ||
303 | dev_err(imx21->dev, "failed bounce map\n"); | ||
304 | goto err_bounce_map; | ||
305 | } | ||
306 | } | ||
307 | } | ||
308 | |||
230 | clear_toggle_bit(imx21, USBH_ETDDONESTAT, etd_mask); | 309 | clear_toggle_bit(imx21, USBH_ETDDONESTAT, etd_mask); |
231 | set_register_bits(imx21, USBH_ETDDONEEN, etd_mask); | 310 | set_register_bits(imx21, USBH_ETDDONEEN, etd_mask); |
232 | clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask); | 311 | clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask); |
233 | clear_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask); | 312 | clear_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask); |
234 | 313 | ||
235 | if (dma) { | 314 | if (etd->dma_handle) { |
236 | set_register_bits(imx21, USB_ETDDMACHANLCLR, etd_mask); | 315 | set_register_bits(imx21, USB_ETDDMACHANLCLR, etd_mask); |
237 | clear_toggle_bit(imx21, USBH_XBUFSTAT, etd_mask); | 316 | clear_toggle_bit(imx21, USBH_XBUFSTAT, etd_mask); |
238 | clear_toggle_bit(imx21, USBH_YBUFSTAT, etd_mask); | 317 | clear_toggle_bit(imx21, USBH_YBUFSTAT, etd_mask); |
239 | writel(dma, imx21->regs + USB_ETDSMSA(etd_num)); | 318 | writel(etd->dma_handle, imx21->regs + USB_ETDSMSA(etd_num)); |
240 | set_register_bits(imx21, USB_ETDDMAEN, etd_mask); | 319 | set_register_bits(imx21, USB_ETDDMAEN, etd_mask); |
241 | } else { | 320 | } else { |
242 | if (dir != TD_DIR_IN) { | 321 | if (dir != TD_DIR_IN) { |
243 | /* need to set for ZLP */ | 322 | /* need to set for ZLP and PIO */ |
244 | set_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask); | 323 | set_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask); |
245 | set_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask); | 324 | set_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask); |
246 | } | 325 | } |
@@ -263,6 +342,14 @@ static void activate_etd(struct imx21 *imx21, | |||
263 | 342 | ||
264 | etd->active_count = 1; | 343 | etd->active_count = 1; |
265 | writel(etd_mask, imx21->regs + USBH_ETDENSET); | 344 | writel(etd_mask, imx21->regs + USBH_ETDENSET); |
345 | return; | ||
346 | |||
347 | err_bounce_map: | ||
348 | kfree(etd->bounce_buffer); | ||
349 | |||
350 | err_bounce_alloc: | ||
351 | free_dmem(imx21, etd); | ||
352 | nonisoc_urb_completed_for_etd(imx21, etd, -ENOMEM); | ||
266 | } | 353 | } |
267 | 354 | ||
268 | /* =========================================== */ | 355 | /* =========================================== */ |
@@ -323,16 +410,23 @@ static void activate_queued_etd(struct imx21 *imx21, | |||
323 | etd_writel(imx21, etd_num, 1, | 410 | etd_writel(imx21, etd_num, 1, |
324 | ((dmem_offset + maxpacket) << DW1_YBUFSRTAD) | dmem_offset); | 411 | ((dmem_offset + maxpacket) << DW1_YBUFSRTAD) | dmem_offset); |
325 | 412 | ||
413 | etd->dmem_offset = dmem_offset; | ||
326 | urb_priv->active = 1; | 414 | urb_priv->active = 1; |
327 | activate_etd(imx21, etd_num, etd->dma_handle, dir); | 415 | activate_etd(imx21, etd_num, dir); |
328 | } | 416 | } |
329 | 417 | ||
330 | static void free_dmem(struct imx21 *imx21, int offset) | 418 | static void free_dmem(struct imx21 *imx21, struct etd_priv *etd) |
331 | { | 419 | { |
332 | struct imx21_dmem_area *area; | 420 | struct imx21_dmem_area *area; |
333 | struct etd_priv *etd, *tmp; | 421 | struct etd_priv *tmp; |
334 | int found = 0; | 422 | int found = 0; |
423 | int offset; | ||
335 | 424 | ||
425 | if (!etd->dmem_size) | ||
426 | return; | ||
427 | etd->dmem_size = 0; | ||
428 | |||
429 | offset = etd->dmem_offset; | ||
336 | list_for_each_entry(area, &imx21->dmem_list, list) { | 430 | list_for_each_entry(area, &imx21->dmem_list, list) { |
337 | if (area->offset == offset) { | 431 | if (area->offset == offset) { |
338 | debug_dmem_freed(imx21, area->size); | 432 | debug_dmem_freed(imx21, area->size); |
@@ -378,20 +472,23 @@ static void free_epdmem(struct imx21 *imx21, struct usb_host_endpoint *ep) | |||
378 | /* =========================================== */ | 472 | /* =========================================== */ |
379 | /* End handling */ | 473 | /* End handling */ |
380 | /* =========================================== */ | 474 | /* =========================================== */ |
381 | static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb); | ||
382 | 475 | ||
383 | /* Endpoint now idle - release it's ETD(s) or asssign to queued request */ | 476 | /* Endpoint now idle - release it's ETD(s) or asssign to queued request */ |
384 | static void ep_idle(struct imx21 *imx21, struct ep_priv *ep_priv) | 477 | static void ep_idle(struct imx21 *imx21, struct ep_priv *ep_priv) |
385 | { | 478 | { |
386 | int etd_num; | ||
387 | int i; | 479 | int i; |
388 | 480 | ||
389 | for (i = 0; i < NUM_ISO_ETDS; i++) { | 481 | for (i = 0; i < NUM_ISO_ETDS; i++) { |
390 | etd_num = ep_priv->etd[i]; | 482 | int etd_num = ep_priv->etd[i]; |
483 | struct etd_priv *etd; | ||
391 | if (etd_num < 0) | 484 | if (etd_num < 0) |
392 | continue; | 485 | continue; |
393 | 486 | ||
487 | etd = &imx21->etd[etd_num]; | ||
394 | ep_priv->etd[i] = -1; | 488 | ep_priv->etd[i] = -1; |
489 | |||
490 | free_dmem(imx21, etd); /* for isoc */ | ||
491 | |||
395 | if (list_empty(&imx21->queue_for_etd)) { | 492 | if (list_empty(&imx21->queue_for_etd)) { |
396 | free_etd(imx21, etd_num); | 493 | free_etd(imx21, etd_num); |
397 | continue; | 494 | continue; |
@@ -437,6 +534,24 @@ __acquires(imx21->lock) | |||
437 | ep_idle(imx21, ep_priv); | 534 | ep_idle(imx21, ep_priv); |
438 | } | 535 | } |
439 | 536 | ||
537 | static void nonisoc_urb_completed_for_etd( | ||
538 | struct imx21 *imx21, struct etd_priv *etd, int status) | ||
539 | { | ||
540 | struct usb_host_endpoint *ep = etd->ep; | ||
541 | |||
542 | urb_done(imx21->hcd, etd->urb, status); | ||
543 | etd->urb = NULL; | ||
544 | |||
545 | if (!list_empty(&ep->urb_list)) { | ||
546 | struct urb *urb = list_first_entry( | ||
547 | &ep->urb_list, struct urb, urb_list); | ||
548 | |||
549 | dev_vdbg(imx21->dev, "next URB %p\n", urb); | ||
550 | schedule_nonisoc_etd(imx21, urb); | ||
551 | } | ||
552 | } | ||
553 | |||
554 | |||
440 | /* =========================================== */ | 555 | /* =========================================== */ |
441 | /* ISOC Handling ... */ | 556 | /* ISOC Handling ... */ |
442 | /* =========================================== */ | 557 | /* =========================================== */ |
@@ -489,6 +604,8 @@ too_late: | |||
489 | etd->ep = td->ep; | 604 | etd->ep = td->ep; |
490 | etd->urb = td->urb; | 605 | etd->urb = td->urb; |
491 | etd->len = td->len; | 606 | etd->len = td->len; |
607 | etd->dma_handle = td->dma_handle; | ||
608 | etd->cpu_buffer = td->cpu_buffer; | ||
492 | 609 | ||
493 | debug_isoc_submitted(imx21, cur_frame, td); | 610 | debug_isoc_submitted(imx21, cur_frame, td); |
494 | 611 | ||
@@ -502,16 +619,17 @@ too_late: | |||
502 | (TD_NOTACCESSED << DW3_COMPCODE0) | | 619 | (TD_NOTACCESSED << DW3_COMPCODE0) | |
503 | (td->len << DW3_PKTLEN0)); | 620 | (td->len << DW3_PKTLEN0)); |
504 | 621 | ||
505 | activate_etd(imx21, etd_num, td->data, dir); | 622 | activate_etd(imx21, etd_num, dir); |
506 | } | 623 | } |
507 | } | 624 | } |
508 | 625 | ||
509 | static void isoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num) | 626 | static void isoc_etd_done(struct usb_hcd *hcd, int etd_num) |
510 | { | 627 | { |
511 | struct imx21 *imx21 = hcd_to_imx21(hcd); | 628 | struct imx21 *imx21 = hcd_to_imx21(hcd); |
512 | int etd_mask = 1 << etd_num; | 629 | int etd_mask = 1 << etd_num; |
513 | struct urb_priv *urb_priv = urb->hcpriv; | ||
514 | struct etd_priv *etd = imx21->etd + etd_num; | 630 | struct etd_priv *etd = imx21->etd + etd_num; |
631 | struct urb *urb = etd->urb; | ||
632 | struct urb_priv *urb_priv = urb->hcpriv; | ||
515 | struct td *td = etd->td; | 633 | struct td *td = etd->td; |
516 | struct usb_host_endpoint *ep = etd->ep; | 634 | struct usb_host_endpoint *ep = etd->ep; |
517 | int isoc_index = td->isoc_index; | 635 | int isoc_index = td->isoc_index; |
@@ -545,8 +663,13 @@ static void isoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num) | |||
545 | bytes_xfrd, td->len, urb, etd_num, isoc_index); | 663 | bytes_xfrd, td->len, urb, etd_num, isoc_index); |
546 | } | 664 | } |
547 | 665 | ||
548 | if (dir_in) | 666 | if (dir_in) { |
549 | clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask); | 667 | clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask); |
668 | if (!etd->dma_handle) | ||
669 | memcpy_fromio(etd->cpu_buffer, | ||
670 | imx21->regs + USBOTG_DMEM + etd->dmem_offset, | ||
671 | bytes_xfrd); | ||
672 | } | ||
550 | 673 | ||
551 | urb->actual_length += bytes_xfrd; | 674 | urb->actual_length += bytes_xfrd; |
552 | urb->iso_frame_desc[isoc_index].actual_length = bytes_xfrd; | 675 | urb->iso_frame_desc[isoc_index].actual_length = bytes_xfrd; |
@@ -569,30 +692,43 @@ static struct ep_priv *alloc_isoc_ep( | |||
569 | int i; | 692 | int i; |
570 | 693 | ||
571 | ep_priv = kzalloc(sizeof(struct ep_priv), GFP_ATOMIC); | 694 | ep_priv = kzalloc(sizeof(struct ep_priv), GFP_ATOMIC); |
572 | if (ep_priv == NULL) | 695 | if (!ep_priv) |
573 | return NULL; | 696 | return NULL; |
574 | 697 | ||
575 | /* Allocate the ETDs */ | 698 | for (i = 0; i < NUM_ISO_ETDS; i++) |
576 | for (i = 0; i < NUM_ISO_ETDS; i++) { | 699 | ep_priv->etd[i] = -1; |
577 | ep_priv->etd[i] = alloc_etd(imx21); | ||
578 | if (ep_priv->etd[i] < 0) { | ||
579 | int j; | ||
580 | dev_err(imx21->dev, "isoc: Couldn't allocate etd\n"); | ||
581 | for (j = 0; j < i; j++) | ||
582 | free_etd(imx21, ep_priv->etd[j]); | ||
583 | goto alloc_etd_failed; | ||
584 | } | ||
585 | imx21->etd[ep_priv->etd[i]].ep = ep; | ||
586 | } | ||
587 | 700 | ||
588 | INIT_LIST_HEAD(&ep_priv->td_list); | 701 | INIT_LIST_HEAD(&ep_priv->td_list); |
589 | ep_priv->ep = ep; | 702 | ep_priv->ep = ep; |
590 | ep->hcpriv = ep_priv; | 703 | ep->hcpriv = ep_priv; |
591 | return ep_priv; | 704 | return ep_priv; |
705 | } | ||
706 | |||
707 | static int alloc_isoc_etds(struct imx21 *imx21, struct ep_priv *ep_priv) | ||
708 | { | ||
709 | int i, j; | ||
710 | int etd_num; | ||
711 | |||
712 | /* Allocate the ETDs if required */ | ||
713 | for (i = 0; i < NUM_ISO_ETDS; i++) { | ||
714 | if (ep_priv->etd[i] < 0) { | ||
715 | etd_num = alloc_etd(imx21); | ||
716 | if (etd_num < 0) | ||
717 | goto alloc_etd_failed; | ||
718 | |||
719 | ep_priv->etd[i] = etd_num; | ||
720 | imx21->etd[etd_num].ep = ep_priv->ep; | ||
721 | } | ||
722 | } | ||
723 | return 0; | ||
592 | 724 | ||
593 | alloc_etd_failed: | 725 | alloc_etd_failed: |
594 | kfree(ep_priv); | 726 | dev_err(imx21->dev, "isoc: Couldn't allocate etd\n"); |
595 | return NULL; | 727 | for (j = 0; j < i; j++) { |
728 | free_etd(imx21, ep_priv->etd[j]); | ||
729 | ep_priv->etd[j] = -1; | ||
730 | } | ||
731 | return -ENOMEM; | ||
596 | } | 732 | } |
597 | 733 | ||
598 | static int imx21_hc_urb_enqueue_isoc(struct usb_hcd *hcd, | 734 | static int imx21_hc_urb_enqueue_isoc(struct usb_hcd *hcd, |
@@ -632,6 +768,10 @@ static int imx21_hc_urb_enqueue_isoc(struct usb_hcd *hcd, | |||
632 | ep_priv = ep->hcpriv; | 768 | ep_priv = ep->hcpriv; |
633 | } | 769 | } |
634 | 770 | ||
771 | ret = alloc_isoc_etds(imx21, ep_priv); | ||
772 | if (ret) | ||
773 | goto alloc_etd_failed; | ||
774 | |||
635 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | 775 | ret = usb_hcd_link_urb_to_ep(hcd, urb); |
636 | if (ret) | 776 | if (ret) |
637 | goto link_failed; | 777 | goto link_failed; |
@@ -688,12 +828,14 @@ static int imx21_hc_urb_enqueue_isoc(struct usb_hcd *hcd, | |||
688 | /* set up transfers */ | 828 | /* set up transfers */ |
689 | td = urb_priv->isoc_td; | 829 | td = urb_priv->isoc_td; |
690 | for (i = 0; i < urb->number_of_packets; i++, td++) { | 830 | for (i = 0; i < urb->number_of_packets; i++, td++) { |
831 | unsigned int offset = urb->iso_frame_desc[i].offset; | ||
691 | td->ep = ep; | 832 | td->ep = ep; |
692 | td->urb = urb; | 833 | td->urb = urb; |
693 | td->len = urb->iso_frame_desc[i].length; | 834 | td->len = urb->iso_frame_desc[i].length; |
694 | td->isoc_index = i; | 835 | td->isoc_index = i; |
695 | td->frame = wrap_frame(urb->start_frame + urb->interval * i); | 836 | td->frame = wrap_frame(urb->start_frame + urb->interval * i); |
696 | td->data = urb->transfer_dma + urb->iso_frame_desc[i].offset; | 837 | td->dma_handle = urb->transfer_dma + offset; |
838 | td->cpu_buffer = urb->transfer_buffer + offset; | ||
697 | list_add_tail(&td->list, &ep_priv->td_list); | 839 | list_add_tail(&td->list, &ep_priv->td_list); |
698 | } | 840 | } |
699 | 841 | ||
@@ -711,6 +853,7 @@ alloc_dmem_failed: | |||
711 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 853 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
712 | 854 | ||
713 | link_failed: | 855 | link_failed: |
856 | alloc_etd_failed: | ||
714 | alloc_ep_failed: | 857 | alloc_ep_failed: |
715 | spin_unlock_irqrestore(&imx21->lock, flags); | 858 | spin_unlock_irqrestore(&imx21->lock, flags); |
716 | kfree(urb_priv->isoc_td); | 859 | kfree(urb_priv->isoc_td); |
@@ -734,9 +877,7 @@ static void dequeue_isoc_urb(struct imx21 *imx21, | |||
734 | struct etd_priv *etd = imx21->etd + etd_num; | 877 | struct etd_priv *etd = imx21->etd + etd_num; |
735 | 878 | ||
736 | reset_etd(imx21, etd_num); | 879 | reset_etd(imx21, etd_num); |
737 | if (etd->dmem_size) | 880 | free_dmem(imx21, etd); |
738 | free_dmem(imx21, etd->dmem_offset); | ||
739 | etd->dmem_size = 0; | ||
740 | } | 881 | } |
741 | } | 882 | } |
742 | } | 883 | } |
@@ -761,7 +902,6 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb) | |||
761 | int state = urb_priv->state; | 902 | int state = urb_priv->state; |
762 | int etd_num = ep_priv->etd[0]; | 903 | int etd_num = ep_priv->etd[0]; |
763 | struct etd_priv *etd; | 904 | struct etd_priv *etd; |
764 | int dmem_offset; | ||
765 | u32 count; | 905 | u32 count; |
766 | u16 etd_buf_size; | 906 | u16 etd_buf_size; |
767 | u16 maxpacket; | 907 | u16 maxpacket; |
@@ -786,13 +926,15 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb) | |||
786 | if (usb_pipecontrol(pipe) && (state != US_CTRL_DATA)) { | 926 | if (usb_pipecontrol(pipe) && (state != US_CTRL_DATA)) { |
787 | if (state == US_CTRL_SETUP) { | 927 | if (state == US_CTRL_SETUP) { |
788 | dir = TD_DIR_SETUP; | 928 | dir = TD_DIR_SETUP; |
929 | if (unsuitable_for_dma(urb->setup_dma)) | ||
930 | unmap_urb_setup_for_dma(imx21->hcd, urb); | ||
789 | etd->dma_handle = urb->setup_dma; | 931 | etd->dma_handle = urb->setup_dma; |
932 | etd->cpu_buffer = urb->setup_packet; | ||
790 | bufround = 0; | 933 | bufround = 0; |
791 | count = 8; | 934 | count = 8; |
792 | datatoggle = TD_TOGGLE_DATA0; | 935 | datatoggle = TD_TOGGLE_DATA0; |
793 | } else { /* US_CTRL_ACK */ | 936 | } else { /* US_CTRL_ACK */ |
794 | dir = usb_pipeout(pipe) ? TD_DIR_IN : TD_DIR_OUT; | 937 | dir = usb_pipeout(pipe) ? TD_DIR_IN : TD_DIR_OUT; |
795 | etd->dma_handle = urb->transfer_dma; | ||
796 | bufround = 0; | 938 | bufround = 0; |
797 | count = 0; | 939 | count = 0; |
798 | datatoggle = TD_TOGGLE_DATA1; | 940 | datatoggle = TD_TOGGLE_DATA1; |
@@ -800,7 +942,11 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb) | |||
800 | } else { | 942 | } else { |
801 | dir = usb_pipeout(pipe) ? TD_DIR_OUT : TD_DIR_IN; | 943 | dir = usb_pipeout(pipe) ? TD_DIR_OUT : TD_DIR_IN; |
802 | bufround = (dir == TD_DIR_IN) ? 1 : 0; | 944 | bufround = (dir == TD_DIR_IN) ? 1 : 0; |
945 | if (unsuitable_for_dma(urb->transfer_dma)) | ||
946 | unmap_urb_for_dma(imx21->hcd, urb); | ||
947 | |||
803 | etd->dma_handle = urb->transfer_dma; | 948 | etd->dma_handle = urb->transfer_dma; |
949 | etd->cpu_buffer = urb->transfer_buffer; | ||
804 | if (usb_pipebulk(pipe) && (state == US_BULK0)) | 950 | if (usb_pipebulk(pipe) && (state == US_BULK0)) |
805 | count = 0; | 951 | count = 0; |
806 | else | 952 | else |
@@ -855,8 +1001,8 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb) | |||
855 | 1001 | ||
856 | /* allocate x and y buffer space at once */ | 1002 | /* allocate x and y buffer space at once */ |
857 | etd->dmem_size = (count > maxpacket) ? maxpacket * 2 : maxpacket; | 1003 | etd->dmem_size = (count > maxpacket) ? maxpacket * 2 : maxpacket; |
858 | dmem_offset = alloc_dmem(imx21, etd->dmem_size, urb_priv->ep); | 1004 | etd->dmem_offset = alloc_dmem(imx21, etd->dmem_size, urb_priv->ep); |
859 | if (dmem_offset < 0) { | 1005 | if (etd->dmem_offset < 0) { |
860 | /* Setup everything we can in HW and update when we get DMEM */ | 1006 | /* Setup everything we can in HW and update when we get DMEM */ |
861 | etd_writel(imx21, etd_num, 1, (u32)maxpacket << 16); | 1007 | etd_writel(imx21, etd_num, 1, (u32)maxpacket << 16); |
862 | 1008 | ||
@@ -867,26 +1013,26 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb) | |||
867 | } | 1013 | } |
868 | 1014 | ||
869 | etd_writel(imx21, etd_num, 1, | 1015 | etd_writel(imx21, etd_num, 1, |
870 | (((u32) dmem_offset + (u32) maxpacket) << DW1_YBUFSRTAD) | | 1016 | (((u32) etd->dmem_offset + (u32) maxpacket) << DW1_YBUFSRTAD) | |
871 | (u32) dmem_offset); | 1017 | (u32) etd->dmem_offset); |
872 | 1018 | ||
873 | urb_priv->active = 1; | 1019 | urb_priv->active = 1; |
874 | 1020 | ||
875 | /* enable the ETD to kick off transfer */ | 1021 | /* enable the ETD to kick off transfer */ |
876 | dev_vdbg(imx21->dev, "Activating etd %d for %d bytes %s\n", | 1022 | dev_vdbg(imx21->dev, "Activating etd %d for %d bytes %s\n", |
877 | etd_num, count, dir != TD_DIR_IN ? "out" : "in"); | 1023 | etd_num, count, dir != TD_DIR_IN ? "out" : "in"); |
878 | activate_etd(imx21, etd_num, etd->dma_handle, dir); | 1024 | activate_etd(imx21, etd_num, dir); |
879 | 1025 | ||
880 | } | 1026 | } |
881 | 1027 | ||
882 | static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num) | 1028 | static void nonisoc_etd_done(struct usb_hcd *hcd, int etd_num) |
883 | { | 1029 | { |
884 | struct imx21 *imx21 = hcd_to_imx21(hcd); | 1030 | struct imx21 *imx21 = hcd_to_imx21(hcd); |
885 | struct etd_priv *etd = &imx21->etd[etd_num]; | 1031 | struct etd_priv *etd = &imx21->etd[etd_num]; |
1032 | struct urb *urb = etd->urb; | ||
886 | u32 etd_mask = 1 << etd_num; | 1033 | u32 etd_mask = 1 << etd_num; |
887 | struct urb_priv *urb_priv = urb->hcpriv; | 1034 | struct urb_priv *urb_priv = urb->hcpriv; |
888 | int dir; | 1035 | int dir; |
889 | u16 xbufaddr; | ||
890 | int cc; | 1036 | int cc; |
891 | u32 bytes_xfrd; | 1037 | u32 bytes_xfrd; |
892 | int etd_done; | 1038 | int etd_done; |
@@ -894,7 +1040,6 @@ static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num) | |||
894 | disactivate_etd(imx21, etd_num); | 1040 | disactivate_etd(imx21, etd_num); |
895 | 1041 | ||
896 | dir = (etd_readl(imx21, etd_num, 0) >> DW0_DIRECT) & 0x3; | 1042 | dir = (etd_readl(imx21, etd_num, 0) >> DW0_DIRECT) & 0x3; |
897 | xbufaddr = etd_readl(imx21, etd_num, 1) & 0xffff; | ||
898 | cc = (etd_readl(imx21, etd_num, 2) >> DW2_COMPCODE) & 0xf; | 1043 | cc = (etd_readl(imx21, etd_num, 2) >> DW2_COMPCODE) & 0xf; |
899 | bytes_xfrd = etd->len - (etd_readl(imx21, etd_num, 3) & 0x1fffff); | 1044 | bytes_xfrd = etd->len - (etd_readl(imx21, etd_num, 3) & 0x1fffff); |
900 | 1045 | ||
@@ -906,8 +1051,21 @@ static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num) | |||
906 | if (dir == TD_DIR_IN) { | 1051 | if (dir == TD_DIR_IN) { |
907 | clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask); | 1052 | clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask); |
908 | clear_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask); | 1053 | clear_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask); |
1054 | |||
1055 | if (etd->bounce_buffer) { | ||
1056 | memcpy(etd->cpu_buffer, etd->bounce_buffer, bytes_xfrd); | ||
1057 | dma_unmap_single(imx21->dev, | ||
1058 | etd->dma_handle, etd->len, DMA_FROM_DEVICE); | ||
1059 | } else if (!etd->dma_handle && bytes_xfrd) {/* PIO */ | ||
1060 | memcpy_fromio(etd->cpu_buffer, | ||
1061 | imx21->regs + USBOTG_DMEM + etd->dmem_offset, | ||
1062 | bytes_xfrd); | ||
1063 | } | ||
909 | } | 1064 | } |
910 | free_dmem(imx21, xbufaddr); | 1065 | |
1066 | kfree(etd->bounce_buffer); | ||
1067 | etd->bounce_buffer = NULL; | ||
1068 | free_dmem(imx21, etd); | ||
911 | 1069 | ||
912 | urb->error_count = 0; | 1070 | urb->error_count = 0; |
913 | if (!(urb->transfer_flags & URB_SHORT_NOT_OK) | 1071 | if (!(urb->transfer_flags & URB_SHORT_NOT_OK) |
@@ -964,24 +1122,15 @@ static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num) | |||
964 | break; | 1122 | break; |
965 | } | 1123 | } |
966 | 1124 | ||
967 | if (!etd_done) { | 1125 | if (etd_done) |
1126 | nonisoc_urb_completed_for_etd(imx21, etd, cc_to_error[cc]); | ||
1127 | else { | ||
968 | dev_vdbg(imx21->dev, "next state=%d\n", urb_priv->state); | 1128 | dev_vdbg(imx21->dev, "next state=%d\n", urb_priv->state); |
969 | schedule_nonisoc_etd(imx21, urb); | 1129 | schedule_nonisoc_etd(imx21, urb); |
970 | } else { | ||
971 | struct usb_host_endpoint *ep = urb->ep; | ||
972 | |||
973 | urb_done(hcd, urb, cc_to_error[cc]); | ||
974 | etd->urb = NULL; | ||
975 | |||
976 | if (!list_empty(&ep->urb_list)) { | ||
977 | urb = list_first_entry(&ep->urb_list, | ||
978 | struct urb, urb_list); | ||
979 | dev_vdbg(imx21->dev, "next URB %p\n", urb); | ||
980 | schedule_nonisoc_etd(imx21, urb); | ||
981 | } | ||
982 | } | 1130 | } |
983 | } | 1131 | } |
984 | 1132 | ||
1133 | |||
985 | static struct ep_priv *alloc_ep(void) | 1134 | static struct ep_priv *alloc_ep(void) |
986 | { | 1135 | { |
987 | int i; | 1136 | int i; |
@@ -1007,7 +1156,6 @@ static int imx21_hc_urb_enqueue(struct usb_hcd *hcd, | |||
1007 | struct etd_priv *etd; | 1156 | struct etd_priv *etd; |
1008 | int ret; | 1157 | int ret; |
1009 | unsigned long flags; | 1158 | unsigned long flags; |
1010 | int new_ep = 0; | ||
1011 | 1159 | ||
1012 | dev_vdbg(imx21->dev, | 1160 | dev_vdbg(imx21->dev, |
1013 | "enqueue urb=%p ep=%p len=%d " | 1161 | "enqueue urb=%p ep=%p len=%d " |
@@ -1035,7 +1183,6 @@ static int imx21_hc_urb_enqueue(struct usb_hcd *hcd, | |||
1035 | } | 1183 | } |
1036 | ep->hcpriv = ep_priv; | 1184 | ep->hcpriv = ep_priv; |
1037 | ep_priv->ep = ep; | 1185 | ep_priv->ep = ep; |
1038 | new_ep = 1; | ||
1039 | } | 1186 | } |
1040 | 1187 | ||
1041 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | 1188 | ret = usb_hcd_link_urb_to_ep(hcd, urb); |
@@ -1124,9 +1271,13 @@ static int imx21_hc_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, | |||
1124 | } else if (urb_priv->active) { | 1271 | } else if (urb_priv->active) { |
1125 | int etd_num = ep_priv->etd[0]; | 1272 | int etd_num = ep_priv->etd[0]; |
1126 | if (etd_num != -1) { | 1273 | if (etd_num != -1) { |
1274 | struct etd_priv *etd = &imx21->etd[etd_num]; | ||
1275 | |||
1127 | disactivate_etd(imx21, etd_num); | 1276 | disactivate_etd(imx21, etd_num); |
1128 | free_dmem(imx21, etd_readl(imx21, etd_num, 1) & 0xffff); | 1277 | free_dmem(imx21, etd); |
1129 | imx21->etd[etd_num].urb = NULL; | 1278 | etd->urb = NULL; |
1279 | kfree(etd->bounce_buffer); | ||
1280 | etd->bounce_buffer = NULL; | ||
1130 | } | 1281 | } |
1131 | } | 1282 | } |
1132 | 1283 | ||
@@ -1226,9 +1377,9 @@ static void process_etds(struct usb_hcd *hcd, struct imx21 *imx21, int sof) | |||
1226 | } | 1377 | } |
1227 | 1378 | ||
1228 | if (usb_pipeisoc(etd->urb->pipe)) | 1379 | if (usb_pipeisoc(etd->urb->pipe)) |
1229 | isoc_etd_done(hcd, etd->urb, etd_num); | 1380 | isoc_etd_done(hcd, etd_num); |
1230 | else | 1381 | else |
1231 | nonisoc_etd_done(hcd, etd->urb, etd_num); | 1382 | nonisoc_etd_done(hcd, etd_num); |
1232 | } | 1383 | } |
1233 | 1384 | ||
1234 | /* only enable SOF interrupt if it may be needed for the kludge */ | 1385 | /* only enable SOF interrupt if it may be needed for the kludge */ |
@@ -1696,6 +1847,7 @@ static int imx21_probe(struct platform_device *pdev) | |||
1696 | } | 1847 | } |
1697 | 1848 | ||
1698 | imx21 = hcd_to_imx21(hcd); | 1849 | imx21 = hcd_to_imx21(hcd); |
1850 | imx21->hcd = hcd; | ||
1699 | imx21->dev = &pdev->dev; | 1851 | imx21->dev = &pdev->dev; |
1700 | imx21->pdata = pdev->dev.platform_data; | 1852 | imx21->pdata = pdev->dev.platform_data; |
1701 | if (!imx21->pdata) | 1853 | if (!imx21->pdata) |
@@ -1754,7 +1906,7 @@ failed_clock_set: | |||
1754 | failed_clock_get: | 1906 | failed_clock_get: |
1755 | iounmap(imx21->regs); | 1907 | iounmap(imx21->regs); |
1756 | failed_ioremap: | 1908 | failed_ioremap: |
1757 | release_mem_region(res->start, res->end - res->start); | 1909 | release_mem_region(res->start, resource_size(res)); |
1758 | failed_request_mem: | 1910 | failed_request_mem: |
1759 | remove_debug_files(imx21); | 1911 | remove_debug_files(imx21); |
1760 | usb_put_hcd(hcd); | 1912 | usb_put_hcd(hcd); |
diff --git a/drivers/usb/host/imx21-hcd.h b/drivers/usb/host/imx21-hcd.h index 1b0d913780a5..87b29fd971b4 100644 --- a/drivers/usb/host/imx21-hcd.h +++ b/drivers/usb/host/imx21-hcd.h | |||
@@ -250,6 +250,7 @@ | |||
250 | #define USBCTRL_USB_BYP (1 << 2) | 250 | #define USBCTRL_USB_BYP (1 << 2) |
251 | #define USBCTRL_HOST1_TXEN_OE (1 << 1) | 251 | #define USBCTRL_HOST1_TXEN_OE (1 << 1) |
252 | 252 | ||
253 | #define USBOTG_DMEM 0x1000 | ||
253 | 254 | ||
254 | /* Values in TD blocks */ | 255 | /* Values in TD blocks */ |
255 | #define TD_DIR_SETUP 0 | 256 | #define TD_DIR_SETUP 0 |
@@ -346,8 +347,8 @@ struct td { | |||
346 | struct list_head list; | 347 | struct list_head list; |
347 | struct urb *urb; | 348 | struct urb *urb; |
348 | struct usb_host_endpoint *ep; | 349 | struct usb_host_endpoint *ep; |
349 | dma_addr_t data; | 350 | dma_addr_t dma_handle; |
350 | unsigned long buf_addr; | 351 | void *cpu_buffer; |
351 | int len; | 352 | int len; |
352 | int frame; | 353 | int frame; |
353 | int isoc_index; | 354 | int isoc_index; |
@@ -360,6 +361,8 @@ struct etd_priv { | |||
360 | struct td *td; | 361 | struct td *td; |
361 | struct list_head queue; | 362 | struct list_head queue; |
362 | dma_addr_t dma_handle; | 363 | dma_addr_t dma_handle; |
364 | void *cpu_buffer; | ||
365 | void *bounce_buffer; | ||
363 | int alloc; | 366 | int alloc; |
364 | int len; | 367 | int len; |
365 | int dmem_size; | 368 | int dmem_size; |
@@ -412,6 +415,7 @@ struct debug_isoc_trace { | |||
412 | struct imx21 { | 415 | struct imx21 { |
413 | spinlock_t lock; | 416 | spinlock_t lock; |
414 | struct device *dev; | 417 | struct device *dev; |
418 | struct usb_hcd *hcd; | ||
415 | struct mx21_usbh_platform_data *pdata; | 419 | struct mx21_usbh_platform_data *pdata; |
416 | struct list_head dmem_list; | 420 | struct list_head dmem_list; |
417 | struct list_head queue_for_etd; /* eps queued due to etd shortage */ | 421 | struct list_head queue_for_etd; /* eps queued due to etd shortage */ |
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index d9e82123de2a..0da7fc05f453 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -1557,8 +1557,6 @@ static int isp116x_remove(struct platform_device *pdev) | |||
1557 | return 0; | 1557 | return 0; |
1558 | } | 1558 | } |
1559 | 1559 | ||
1560 | #define resource_len(r) (((r)->end - (r)->start) + 1) | ||
1561 | |||
1562 | static int __devinit isp116x_probe(struct platform_device *pdev) | 1560 | static int __devinit isp116x_probe(struct platform_device *pdev) |
1563 | { | 1561 | { |
1564 | struct usb_hcd *hcd; | 1562 | struct usb_hcd *hcd; |
@@ -1597,7 +1595,7 @@ static int __devinit isp116x_probe(struct platform_device *pdev) | |||
1597 | ret = -EBUSY; | 1595 | ret = -EBUSY; |
1598 | goto err1; | 1596 | goto err1; |
1599 | } | 1597 | } |
1600 | addr_reg = ioremap(addr->start, resource_len(addr)); | 1598 | addr_reg = ioremap(addr->start, resource_size(addr)); |
1601 | if (addr_reg == NULL) { | 1599 | if (addr_reg == NULL) { |
1602 | ret = -ENOMEM; | 1600 | ret = -ENOMEM; |
1603 | goto err2; | 1601 | goto err2; |
@@ -1606,7 +1604,7 @@ static int __devinit isp116x_probe(struct platform_device *pdev) | |||
1606 | ret = -EBUSY; | 1604 | ret = -EBUSY; |
1607 | goto err3; | 1605 | goto err3; |
1608 | } | 1606 | } |
1609 | data_reg = ioremap(data->start, resource_len(data)); | 1607 | data_reg = ioremap(data->start, resource_size(data)); |
1610 | if (data_reg == NULL) { | 1608 | if (data_reg == NULL) { |
1611 | ret = -ENOMEM; | 1609 | ret = -ENOMEM; |
1612 | goto err4; | 1610 | goto err4; |
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 0587ad4ce5c2..8196fa11fec4 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c | |||
@@ -1676,13 +1676,6 @@ static int isp1362_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
1676 | switch (wValue) { | 1676 | switch (wValue) { |
1677 | case USB_PORT_FEAT_SUSPEND: | 1677 | case USB_PORT_FEAT_SUSPEND: |
1678 | _DBG(0, "USB_PORT_FEAT_SUSPEND\n"); | 1678 | _DBG(0, "USB_PORT_FEAT_SUSPEND\n"); |
1679 | #ifdef CONFIG_USB_OTG | ||
1680 | if (ohci->hcd.self.otg_port == (wIndex + 1) && | ||
1681 | ohci->hcd.self.b_hnp_enable) { | ||
1682 | start_hnp(ohci); | ||
1683 | break; | ||
1684 | } | ||
1685 | #endif | ||
1686 | spin_lock_irqsave(&isp1362_hcd->lock, flags); | 1679 | spin_lock_irqsave(&isp1362_hcd->lock, flags); |
1687 | isp1362_write_reg32(isp1362_hcd, HCRHPORT1 + wIndex, RH_PS_PSS); | 1680 | isp1362_write_reg32(isp1362_hcd, HCRHPORT1 + wIndex, RH_PS_PSS); |
1688 | isp1362_hcd->rhport[wIndex] = | 1681 | isp1362_hcd->rhport[wIndex] = |
@@ -2656,8 +2649,6 @@ static struct hc_driver isp1362_hc_driver = { | |||
2656 | 2649 | ||
2657 | /*-------------------------------------------------------------------------*/ | 2650 | /*-------------------------------------------------------------------------*/ |
2658 | 2651 | ||
2659 | #define resource_len(r) (((r)->end - (r)->start) + 1) | ||
2660 | |||
2661 | static int __devexit isp1362_remove(struct platform_device *pdev) | 2652 | static int __devexit isp1362_remove(struct platform_device *pdev) |
2662 | { | 2653 | { |
2663 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 2654 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
@@ -2679,12 +2670,12 @@ static int __devexit isp1362_remove(struct platform_device *pdev) | |||
2679 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 2670 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
2680 | DBG(0, "%s: release mem_region: %08lx\n", __func__, (long unsigned int)res->start); | 2671 | DBG(0, "%s: release mem_region: %08lx\n", __func__, (long unsigned int)res->start); |
2681 | if (res) | 2672 | if (res) |
2682 | release_mem_region(res->start, resource_len(res)); | 2673 | release_mem_region(res->start, resource_size(res)); |
2683 | 2674 | ||
2684 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2675 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2685 | DBG(0, "%s: release mem_region: %08lx\n", __func__, (long unsigned int)res->start); | 2676 | DBG(0, "%s: release mem_region: %08lx\n", __func__, (long unsigned int)res->start); |
2686 | if (res) | 2677 | if (res) |
2687 | release_mem_region(res->start, resource_len(res)); | 2678 | release_mem_region(res->start, resource_size(res)); |
2688 | 2679 | ||
2689 | DBG(0, "%s: put_hcd\n", __func__); | 2680 | DBG(0, "%s: put_hcd\n", __func__); |
2690 | usb_put_hcd(hcd); | 2681 | usb_put_hcd(hcd); |
@@ -2730,21 +2721,21 @@ static int __init isp1362_probe(struct platform_device *pdev) | |||
2730 | goto err1; | 2721 | goto err1; |
2731 | } | 2722 | } |
2732 | 2723 | ||
2733 | if (!request_mem_region(addr->start, resource_len(addr), hcd_name)) { | 2724 | if (!request_mem_region(addr->start, resource_size(addr), hcd_name)) { |
2734 | retval = -EBUSY; | 2725 | retval = -EBUSY; |
2735 | goto err1; | 2726 | goto err1; |
2736 | } | 2727 | } |
2737 | addr_reg = ioremap(addr->start, resource_len(addr)); | 2728 | addr_reg = ioremap(addr->start, resource_size(addr)); |
2738 | if (addr_reg == NULL) { | 2729 | if (addr_reg == NULL) { |
2739 | retval = -ENOMEM; | 2730 | retval = -ENOMEM; |
2740 | goto err2; | 2731 | goto err2; |
2741 | } | 2732 | } |
2742 | 2733 | ||
2743 | if (!request_mem_region(data->start, resource_len(data), hcd_name)) { | 2734 | if (!request_mem_region(data->start, resource_size(data), hcd_name)) { |
2744 | retval = -EBUSY; | 2735 | retval = -EBUSY; |
2745 | goto err3; | 2736 | goto err3; |
2746 | } | 2737 | } |
2747 | data_reg = ioremap(data->start, resource_len(data)); | 2738 | data_reg = ioremap(data->start, resource_size(data)); |
2748 | if (data_reg == NULL) { | 2739 | if (data_reg == NULL) { |
2749 | retval = -ENOMEM; | 2740 | retval = -ENOMEM; |
2750 | goto err4; | 2741 | goto err4; |
@@ -2802,13 +2793,13 @@ static int __init isp1362_probe(struct platform_device *pdev) | |||
2802 | iounmap(data_reg); | 2793 | iounmap(data_reg); |
2803 | err4: | 2794 | err4: |
2804 | DBG(0, "%s: Releasing mem region %08lx\n", __func__, (long unsigned int)data->start); | 2795 | DBG(0, "%s: Releasing mem region %08lx\n", __func__, (long unsigned int)data->start); |
2805 | release_mem_region(data->start, resource_len(data)); | 2796 | release_mem_region(data->start, resource_size(data)); |
2806 | err3: | 2797 | err3: |
2807 | DBG(0, "%s: Unmapping addr_reg @ %p\n", __func__, addr_reg); | 2798 | DBG(0, "%s: Unmapping addr_reg @ %p\n", __func__, addr_reg); |
2808 | iounmap(addr_reg); | 2799 | iounmap(addr_reg); |
2809 | err2: | 2800 | err2: |
2810 | DBG(0, "%s: Releasing mem region %08lx\n", __func__, (long unsigned int)addr->start); | 2801 | DBG(0, "%s: Releasing mem region %08lx\n", __func__, (long unsigned int)addr->start); |
2811 | release_mem_region(addr->start, resource_len(addr)); | 2802 | release_mem_region(addr->start, resource_size(addr)); |
2812 | err1: | 2803 | err1: |
2813 | pr_err("%s: init error, %d\n", __func__, retval); | 2804 | pr_err("%s: init error, %d\n", __func__, retval); |
2814 | 2805 | ||
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index c3b4ccc7337b..3b5785032a10 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -398,7 +398,14 @@ ohci_shutdown (struct usb_hcd *hcd) | |||
398 | 398 | ||
399 | ohci = hcd_to_ohci (hcd); | 399 | ohci = hcd_to_ohci (hcd); |
400 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); | 400 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); |
401 | ohci_usb_reset (ohci); | 401 | ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); |
402 | |||
403 | /* If the SHUTDOWN quirk is set, don't put the controller in RESET */ | ||
404 | ohci->hc_control &= (ohci->flags & OHCI_QUIRK_SHUTDOWN ? | ||
405 | OHCI_CTRL_RWC | OHCI_CTRL_HCFS : | ||
406 | OHCI_CTRL_RWC); | ||
407 | ohci_writel(ohci, ohci->hc_control, &ohci->regs->control); | ||
408 | |||
402 | /* flush the writes */ | 409 | /* flush the writes */ |
403 | (void) ohci_readl (ohci, &ohci->regs->control); | 410 | (void) ohci_readl (ohci, &ohci->regs->control); |
404 | } | 411 | } |
@@ -1270,6 +1277,9 @@ static void __exit ohci_hcd_mod_exit(void) | |||
1270 | #ifdef PLATFORM_DRIVER | 1277 | #ifdef PLATFORM_DRIVER |
1271 | platform_driver_unregister(&PLATFORM_DRIVER); | 1278 | platform_driver_unregister(&PLATFORM_DRIVER); |
1272 | #endif | 1279 | #endif |
1280 | #ifdef OMAP3_PLATFORM_DRIVER | ||
1281 | platform_driver_unregister(&OMAP3_PLATFORM_DRIVER); | ||
1282 | #endif | ||
1273 | #ifdef PS3_SYSTEM_BUS_DRIVER | 1283 | #ifdef PS3_SYSTEM_BUS_DRIVER |
1274 | ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | 1284 | ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); |
1275 | #endif | 1285 | #endif |
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 6bdc8b25a6a1..36ee9a666e93 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -201,6 +201,20 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd) | |||
201 | return 0; | 201 | return 0; |
202 | } | 202 | } |
203 | 203 | ||
204 | /* nVidia controllers continue to drive Reset signalling on the bus | ||
205 | * even after system shutdown, wasting power. This flag tells the | ||
206 | * shutdown routine to leave the controller OPERATIONAL instead of RESET. | ||
207 | */ | ||
208 | static int ohci_quirk_nvidia_shutdown(struct usb_hcd *hcd) | ||
209 | { | ||
210 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
211 | |||
212 | ohci->flags |= OHCI_QUIRK_SHUTDOWN; | ||
213 | ohci_dbg(ohci, "enabled nVidia shutdown quirk\n"); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
204 | /* | 218 | /* |
205 | * The hardware normally enables the A-link power management feature, which | 219 | * The hardware normally enables the A-link power management feature, which |
206 | * lets the system lower the power consumption in idle states. | 220 | * lets the system lower the power consumption in idle states. |
@@ -332,6 +346,10 @@ static const struct pci_device_id ohci_pci_quirks[] = { | |||
332 | PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399), | 346 | PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399), |
333 | .driver_data = (unsigned long)ohci_quirk_amd700, | 347 | .driver_data = (unsigned long)ohci_quirk_amd700, |
334 | }, | 348 | }, |
349 | { | ||
350 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), | ||
351 | .driver_data = (unsigned long) ohci_quirk_nvidia_shutdown, | ||
352 | }, | ||
335 | 353 | ||
336 | /* FIXME for some of the early AMD 760 southbridges, OHCI | 354 | /* FIXME for some of the early AMD 760 southbridges, OHCI |
337 | * won't work at all. blacklist them. | 355 | * won't work at all. blacklist them. |
diff --git a/drivers/usb/host/ohci-sh.c b/drivers/usb/host/ohci-sh.c index 60f03cc7ec4f..0b35d22cc70e 100644 --- a/drivers/usb/host/ohci-sh.c +++ b/drivers/usb/host/ohci-sh.c | |||
@@ -77,7 +77,6 @@ static const struct hc_driver ohci_sh_hc_driver = { | |||
77 | 77 | ||
78 | /*-------------------------------------------------------------------------*/ | 78 | /*-------------------------------------------------------------------------*/ |
79 | 79 | ||
80 | #define resource_len(r) (((r)->end - (r)->start) + 1) | ||
81 | static int ohci_hcd_sh_probe(struct platform_device *pdev) | 80 | static int ohci_hcd_sh_probe(struct platform_device *pdev) |
82 | { | 81 | { |
83 | struct resource *res = NULL; | 82 | struct resource *res = NULL; |
@@ -109,7 +108,7 @@ static int ohci_hcd_sh_probe(struct platform_device *pdev) | |||
109 | 108 | ||
110 | hcd->regs = (void __iomem *)res->start; | 109 | hcd->regs = (void __iomem *)res->start; |
111 | hcd->rsrc_start = res->start; | 110 | hcd->rsrc_start = res->start; |
112 | hcd->rsrc_len = resource_len(res); | 111 | hcd->rsrc_len = resource_size(res); |
113 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 112 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); |
114 | if (ret != 0) { | 113 | if (ret != 0) { |
115 | err("Failed to add hcd"); | 114 | err("Failed to add hcd"); |
diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index cff23637cfcc..041d30f30c10 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c | |||
@@ -168,7 +168,7 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev) | |||
168 | 168 | ||
169 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 169 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); |
170 | if (retval) | 170 | if (retval) |
171 | goto err4; | 171 | goto err5; |
172 | 172 | ||
173 | /* enable power and unmask interrupts */ | 173 | /* enable power and unmask interrupts */ |
174 | 174 | ||
@@ -176,6 +176,8 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev) | |||
176 | sm501_modify_reg(dev->parent, SM501_IRQ_MASK, 1 << 6, 0); | 176 | sm501_modify_reg(dev->parent, SM501_IRQ_MASK, 1 << 6, 0); |
177 | 177 | ||
178 | return 0; | 178 | return 0; |
179 | err5: | ||
180 | iounmap(hcd->regs); | ||
179 | err4: | 181 | err4: |
180 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 182 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
181 | err3: | 183 | err3: |
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 5bf15fed0d9f..51facb985c84 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -403,6 +403,7 @@ struct ohci_hcd { | |||
403 | #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ | 403 | #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ |
404 | #define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/ | 404 | #define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/ |
405 | #define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ | 405 | #define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ |
406 | #define OHCI_QUIRK_SHUTDOWN 0x800 /* nVidia power bug */ | ||
406 | // there are also chip quirks/bugs in init logic | 407 | // there are also chip quirks/bugs in init logic |
407 | 408 | ||
408 | struct work_struct nec_work; /* Worker for NEC quirk */ | 409 | struct work_struct nec_work; /* Worker for NEC quirk */ |
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index d9c85a292737..d32c3eae99cb 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c | |||
@@ -3696,7 +3696,7 @@ static void oxu_configuration(struct platform_device *pdev, void *base) | |||
3696 | static int oxu_verify_id(struct platform_device *pdev, void *base) | 3696 | static int oxu_verify_id(struct platform_device *pdev, void *base) |
3697 | { | 3697 | { |
3698 | u32 id; | 3698 | u32 id; |
3699 | char *bo[] = { | 3699 | static const char * const bo[] = { |
3700 | "reserved", | 3700 | "reserved", |
3701 | "128-pin LQFP", | 3701 | "128-pin LQFP", |
3702 | "84-pin TFBGA", | 3702 | "84-pin TFBGA", |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 83b5f9cea85a..464ed977b45d 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -169,6 +169,7 @@ static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx) | |||
169 | static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | 169 | static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) |
170 | { | 170 | { |
171 | void __iomem *base; | 171 | void __iomem *base; |
172 | u32 control; | ||
172 | 173 | ||
173 | if (!mmio_resource_enabled(pdev, 0)) | 174 | if (!mmio_resource_enabled(pdev, 0)) |
174 | return; | 175 | return; |
@@ -177,10 +178,14 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
177 | if (base == NULL) | 178 | if (base == NULL) |
178 | return; | 179 | return; |
179 | 180 | ||
181 | control = readl(base + OHCI_CONTROL); | ||
182 | |||
180 | /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ | 183 | /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ |
181 | #ifndef __hppa__ | 184 | #ifdef __hppa__ |
182 | { | 185 | #define OHCI_CTRL_MASK (OHCI_CTRL_RWC | OHCI_CTRL_IR) |
183 | u32 control = readl(base + OHCI_CONTROL); | 186 | #else |
187 | #define OHCI_CTRL_MASK OHCI_CTRL_RWC | ||
188 | |||
184 | if (control & OHCI_CTRL_IR) { | 189 | if (control & OHCI_CTRL_IR) { |
185 | int wait_time = 500; /* arbitrary; 5 seconds */ | 190 | int wait_time = 500; /* arbitrary; 5 seconds */ |
186 | writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); | 191 | writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); |
@@ -194,13 +199,12 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
194 | dev_warn(&pdev->dev, "OHCI: BIOS handoff failed" | 199 | dev_warn(&pdev->dev, "OHCI: BIOS handoff failed" |
195 | " (BIOS bug?) %08x\n", | 200 | " (BIOS bug?) %08x\n", |
196 | readl(base + OHCI_CONTROL)); | 201 | readl(base + OHCI_CONTROL)); |
197 | |||
198 | /* reset controller, preserving RWC */ | ||
199 | writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL); | ||
200 | } | 202 | } |
201 | } | ||
202 | #endif | 203 | #endif |
203 | 204 | ||
205 | /* reset controller, preserving RWC (and possibly IR) */ | ||
206 | writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL); | ||
207 | |||
204 | /* | 208 | /* |
205 | * disable interrupts | 209 | * disable interrupts |
206 | */ | 210 | */ |
diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index 95d0f5adfdcf..25563e9a90bc 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h | |||
@@ -227,7 +227,7 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, | |||
227 | int odd = len & 0x0001; | 227 | int odd = len & 0x0001; |
228 | 228 | ||
229 | len = len / 2; | 229 | len = len / 2; |
230 | ioread16_rep(fifoaddr, buf, len); | 230 | iowrite16_rep(fifoaddr, buf, len); |
231 | if (unlikely(odd)) { | 231 | if (unlikely(odd)) { |
232 | buf = &buf[len]; | 232 | buf = &buf[len]; |
233 | iowrite8((unsigned char)*buf, fifoaddr); | 233 | iowrite8((unsigned char)*buf, fifoaddr); |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index d3ade4018487..2090b45eb606 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -917,10 +917,13 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
917 | unsigned long destination, status; | 917 | unsigned long destination, status; |
918 | int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); | 918 | int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); |
919 | int len = urb->transfer_buffer_length; | 919 | int len = urb->transfer_buffer_length; |
920 | dma_addr_t data = urb->transfer_dma; | 920 | int this_sg_len; |
921 | dma_addr_t data; | ||
921 | __le32 *plink; | 922 | __le32 *plink; |
922 | struct urb_priv *urbp = urb->hcpriv; | 923 | struct urb_priv *urbp = urb->hcpriv; |
923 | unsigned int toggle; | 924 | unsigned int toggle; |
925 | struct scatterlist *sg; | ||
926 | int i; | ||
924 | 927 | ||
925 | if (len < 0) | 928 | if (len < 0) |
926 | return -EINVAL; | 929 | return -EINVAL; |
@@ -937,12 +940,26 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
937 | if (usb_pipein(urb->pipe)) | 940 | if (usb_pipein(urb->pipe)) |
938 | status |= TD_CTRL_SPD; | 941 | status |= TD_CTRL_SPD; |
939 | 942 | ||
943 | i = urb->num_sgs; | ||
944 | if (len > 0 && i > 0) { | ||
945 | sg = urb->sg; | ||
946 | data = sg_dma_address(sg); | ||
947 | |||
948 | /* urb->transfer_buffer_length may be smaller than the | ||
949 | * size of the scatterlist (or vice versa) | ||
950 | */ | ||
951 | this_sg_len = min_t(int, sg_dma_len(sg), len); | ||
952 | } else { | ||
953 | sg = NULL; | ||
954 | data = urb->transfer_dma; | ||
955 | this_sg_len = len; | ||
956 | } | ||
940 | /* | 957 | /* |
941 | * Build the DATA TDs | 958 | * Build the DATA TDs |
942 | */ | 959 | */ |
943 | plink = NULL; | 960 | plink = NULL; |
944 | td = qh->dummy_td; | 961 | td = qh->dummy_td; |
945 | do { /* Allow zero length packets */ | 962 | for (;;) { /* Allow zero length packets */ |
946 | int pktsze = maxsze; | 963 | int pktsze = maxsze; |
947 | 964 | ||
948 | if (len <= pktsze) { /* The last packet */ | 965 | if (len <= pktsze) { /* The last packet */ |
@@ -965,10 +982,18 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
965 | plink = &td->link; | 982 | plink = &td->link; |
966 | status |= TD_CTRL_ACTIVE; | 983 | status |= TD_CTRL_ACTIVE; |
967 | 984 | ||
985 | toggle ^= 1; | ||
968 | data += pktsze; | 986 | data += pktsze; |
987 | this_sg_len -= pktsze; | ||
969 | len -= maxsze; | 988 | len -= maxsze; |
970 | toggle ^= 1; | 989 | if (this_sg_len <= 0) { |
971 | } while (len > 0); | 990 | if (--i <= 0 || len <= 0) |
991 | break; | ||
992 | sg = sg_next(sg); | ||
993 | data = sg_dma_address(sg); | ||
994 | this_sg_len = min_t(int, sg_dma_len(sg), len); | ||
995 | } | ||
996 | } | ||
972 | 997 | ||
973 | /* | 998 | /* |
974 | * URB_ZERO_PACKET means adding a 0-length packet, if direction | 999 | * URB_ZERO_PACKET means adding a 0-length packet, if direction |
diff --git a/drivers/usb/host/whci/Kbuild b/drivers/usb/host/whci/Kbuild index 11e5040b8337..26df0138079e 100644 --- a/drivers/usb/host/whci/Kbuild +++ b/drivers/usb/host/whci/Kbuild | |||
@@ -3,7 +3,7 @@ obj-$(CONFIG_USB_WHCI_HCD) += whci-hcd.o | |||
3 | whci-hcd-y := \ | 3 | whci-hcd-y := \ |
4 | asl.o \ | 4 | asl.o \ |
5 | debug.o \ | 5 | debug.o \ |
6 | hcd.o \ | 6 | hcd.o \ |
7 | hw.o \ | 7 | hw.o \ |
8 | init.o \ | 8 | init.o \ |
9 | int.o \ | 9 | int.o \ |
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index a1a7a9795536..fef5a1f9d483 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -24,6 +24,10 @@ | |||
24 | 24 | ||
25 | #include "xhci.h" | 25 | #include "xhci.h" |
26 | 26 | ||
27 | #define PORT_WAKE_BITS (PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E) | ||
28 | #define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \ | ||
29 | PORT_RC | PORT_PLC | PORT_PE) | ||
30 | |||
27 | static void xhci_hub_descriptor(struct xhci_hcd *xhci, | 31 | static void xhci_hub_descriptor(struct xhci_hcd *xhci, |
28 | struct usb_hub_descriptor *desc) | 32 | struct usb_hub_descriptor *desc) |
29 | { | 33 | { |
@@ -123,12 +127,105 @@ static unsigned int xhci_port_speed(unsigned int port_status) | |||
123 | * writing a 0 clears the bit and writing a 1 sets the bit (RWS). | 127 | * writing a 0 clears the bit and writing a 1 sets the bit (RWS). |
124 | * For all other types (RW1S, RW1CS, RW, and RZ), writing a '0' has no effect. | 128 | * For all other types (RW1S, RW1CS, RW, and RZ), writing a '0' has no effect. |
125 | */ | 129 | */ |
126 | static u32 xhci_port_state_to_neutral(u32 state) | 130 | u32 xhci_port_state_to_neutral(u32 state) |
127 | { | 131 | { |
128 | /* Save read-only status and port state */ | 132 | /* Save read-only status and port state */ |
129 | return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS); | 133 | return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS); |
130 | } | 134 | } |
131 | 135 | ||
136 | /* | ||
137 | * find slot id based on port number. | ||
138 | */ | ||
139 | int xhci_find_slot_id_by_port(struct xhci_hcd *xhci, u16 port) | ||
140 | { | ||
141 | int slot_id; | ||
142 | int i; | ||
143 | |||
144 | slot_id = 0; | ||
145 | for (i = 0; i < MAX_HC_SLOTS; i++) { | ||
146 | if (!xhci->devs[i]) | ||
147 | continue; | ||
148 | if (xhci->devs[i]->port == port) { | ||
149 | slot_id = i; | ||
150 | break; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | return slot_id; | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Stop device | ||
159 | * It issues stop endpoint command for EP 0 to 30. And wait the last command | ||
160 | * to complete. | ||
161 | * suspend will set to 1, if suspend bit need to set in command. | ||
162 | */ | ||
163 | static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) | ||
164 | { | ||
165 | struct xhci_virt_device *virt_dev; | ||
166 | struct xhci_command *cmd; | ||
167 | unsigned long flags; | ||
168 | int timeleft; | ||
169 | int ret; | ||
170 | int i; | ||
171 | |||
172 | ret = 0; | ||
173 | virt_dev = xhci->devs[slot_id]; | ||
174 | cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO); | ||
175 | if (!cmd) { | ||
176 | xhci_dbg(xhci, "Couldn't allocate command structure.\n"); | ||
177 | return -ENOMEM; | ||
178 | } | ||
179 | |||
180 | spin_lock_irqsave(&xhci->lock, flags); | ||
181 | for (i = LAST_EP_INDEX; i > 0; i--) { | ||
182 | if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) | ||
183 | xhci_queue_stop_endpoint(xhci, slot_id, i, suspend); | ||
184 | } | ||
185 | cmd->command_trb = xhci->cmd_ring->enqueue; | ||
186 | list_add_tail(&cmd->cmd_list, &virt_dev->cmd_list); | ||
187 | xhci_queue_stop_endpoint(xhci, slot_id, 0, suspend); | ||
188 | xhci_ring_cmd_db(xhci); | ||
189 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
190 | |||
191 | /* Wait for last stop endpoint command to finish */ | ||
192 | timeleft = wait_for_completion_interruptible_timeout( | ||
193 | cmd->completion, | ||
194 | USB_CTRL_SET_TIMEOUT); | ||
195 | if (timeleft <= 0) { | ||
196 | xhci_warn(xhci, "%s while waiting for stop endpoint command\n", | ||
197 | timeleft == 0 ? "Timeout" : "Signal"); | ||
198 | spin_lock_irqsave(&xhci->lock, flags); | ||
199 | /* The timeout might have raced with the event ring handler, so | ||
200 | * only delete from the list if the item isn't poisoned. | ||
201 | */ | ||
202 | if (cmd->cmd_list.next != LIST_POISON1) | ||
203 | list_del(&cmd->cmd_list); | ||
204 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
205 | ret = -ETIME; | ||
206 | goto command_cleanup; | ||
207 | } | ||
208 | |||
209 | command_cleanup: | ||
210 | xhci_free_command(xhci, cmd); | ||
211 | return ret; | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * Ring device, it rings the all doorbells unconditionally. | ||
216 | */ | ||
217 | void xhci_ring_device(struct xhci_hcd *xhci, int slot_id) | ||
218 | { | ||
219 | int i; | ||
220 | |||
221 | for (i = 0; i < LAST_EP_INDEX + 1; i++) | ||
222 | if (xhci->devs[slot_id]->eps[i].ring && | ||
223 | xhci->devs[slot_id]->eps[i].ring->dequeue) | ||
224 | xhci_ring_ep_doorbell(xhci, slot_id, i, 0); | ||
225 | |||
226 | return; | ||
227 | } | ||
228 | |||
132 | static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex, | 229 | static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex, |
133 | u32 __iomem *addr, u32 port_status) | 230 | u32 __iomem *addr, u32 port_status) |
134 | { | 231 | { |
@@ -162,6 +259,10 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue, | |||
162 | status = PORT_PEC; | 259 | status = PORT_PEC; |
163 | port_change_bit = "enable/disable"; | 260 | port_change_bit = "enable/disable"; |
164 | break; | 261 | break; |
262 | case USB_PORT_FEAT_C_SUSPEND: | ||
263 | status = PORT_PLC; | ||
264 | port_change_bit = "suspend/resume"; | ||
265 | break; | ||
165 | default: | 266 | default: |
166 | /* Should never happen */ | 267 | /* Should never happen */ |
167 | return; | 268 | return; |
@@ -179,9 +280,10 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
179 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 280 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
180 | int ports; | 281 | int ports; |
181 | unsigned long flags; | 282 | unsigned long flags; |
182 | u32 temp, status; | 283 | u32 temp, temp1, status; |
183 | int retval = 0; | 284 | int retval = 0; |
184 | u32 __iomem *addr; | 285 | u32 __iomem *addr; |
286 | int slot_id; | ||
185 | 287 | ||
186 | ports = HCS_MAX_PORTS(xhci->hcs_params1); | 288 | ports = HCS_MAX_PORTS(xhci->hcs_params1); |
187 | 289 | ||
@@ -211,9 +313,49 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
211 | if ((temp & PORT_OCC)) | 313 | if ((temp & PORT_OCC)) |
212 | status |= USB_PORT_STAT_C_OVERCURRENT << 16; | 314 | status |= USB_PORT_STAT_C_OVERCURRENT << 16; |
213 | /* | 315 | /* |
214 | * FIXME ignoring suspend, reset, and USB 2.1/3.0 specific | 316 | * FIXME ignoring reset and USB 2.1/3.0 specific |
215 | * changes | 317 | * changes |
216 | */ | 318 | */ |
319 | if ((temp & PORT_PLS_MASK) == XDEV_U3 | ||
320 | && (temp & PORT_POWER)) | ||
321 | status |= 1 << USB_PORT_FEAT_SUSPEND; | ||
322 | if ((temp & PORT_PLS_MASK) == XDEV_RESUME) { | ||
323 | if ((temp & PORT_RESET) || !(temp & PORT_PE)) | ||
324 | goto error; | ||
325 | if (!DEV_SUPERSPEED(temp) && time_after_eq(jiffies, | ||
326 | xhci->resume_done[wIndex])) { | ||
327 | xhci_dbg(xhci, "Resume USB2 port %d\n", | ||
328 | wIndex + 1); | ||
329 | xhci->resume_done[wIndex] = 0; | ||
330 | temp1 = xhci_port_state_to_neutral(temp); | ||
331 | temp1 &= ~PORT_PLS_MASK; | ||
332 | temp1 |= PORT_LINK_STROBE | XDEV_U0; | ||
333 | xhci_writel(xhci, temp1, addr); | ||
334 | |||
335 | xhci_dbg(xhci, "set port %d resume\n", | ||
336 | wIndex + 1); | ||
337 | slot_id = xhci_find_slot_id_by_port(xhci, | ||
338 | wIndex + 1); | ||
339 | if (!slot_id) { | ||
340 | xhci_dbg(xhci, "slot_id is zero\n"); | ||
341 | goto error; | ||
342 | } | ||
343 | xhci_ring_device(xhci, slot_id); | ||
344 | xhci->port_c_suspend[wIndex >> 5] |= | ||
345 | 1 << (wIndex & 31); | ||
346 | xhci->suspended_ports[wIndex >> 5] &= | ||
347 | ~(1 << (wIndex & 31)); | ||
348 | } | ||
349 | } | ||
350 | if ((temp & PORT_PLS_MASK) == XDEV_U0 | ||
351 | && (temp & PORT_POWER) | ||
352 | && (xhci->suspended_ports[wIndex >> 5] & | ||
353 | (1 << (wIndex & 31)))) { | ||
354 | xhci->suspended_ports[wIndex >> 5] &= | ||
355 | ~(1 << (wIndex & 31)); | ||
356 | xhci->port_c_suspend[wIndex >> 5] |= | ||
357 | 1 << (wIndex & 31); | ||
358 | } | ||
217 | if (temp & PORT_CONNECT) { | 359 | if (temp & PORT_CONNECT) { |
218 | status |= USB_PORT_STAT_CONNECTION; | 360 | status |= USB_PORT_STAT_CONNECTION; |
219 | status |= xhci_port_speed(temp); | 361 | status |= xhci_port_speed(temp); |
@@ -226,6 +368,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
226 | status |= USB_PORT_STAT_RESET; | 368 | status |= USB_PORT_STAT_RESET; |
227 | if (temp & PORT_POWER) | 369 | if (temp & PORT_POWER) |
228 | status |= USB_PORT_STAT_POWER; | 370 | status |= USB_PORT_STAT_POWER; |
371 | if (xhci->port_c_suspend[wIndex >> 5] & (1 << (wIndex & 31))) | ||
372 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | ||
229 | xhci_dbg(xhci, "Get port status returned 0x%x\n", status); | 373 | xhci_dbg(xhci, "Get port status returned 0x%x\n", status); |
230 | put_unaligned(cpu_to_le32(status), (__le32 *) buf); | 374 | put_unaligned(cpu_to_le32(status), (__le32 *) buf); |
231 | break; | 375 | break; |
@@ -238,6 +382,42 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
238 | temp = xhci_readl(xhci, addr); | 382 | temp = xhci_readl(xhci, addr); |
239 | temp = xhci_port_state_to_neutral(temp); | 383 | temp = xhci_port_state_to_neutral(temp); |
240 | switch (wValue) { | 384 | switch (wValue) { |
385 | case USB_PORT_FEAT_SUSPEND: | ||
386 | temp = xhci_readl(xhci, addr); | ||
387 | /* In spec software should not attempt to suspend | ||
388 | * a port unless the port reports that it is in the | ||
389 | * enabled (PED = ‘1’,PLS < ‘3’) state. | ||
390 | */ | ||
391 | if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) | ||
392 | || (temp & PORT_PLS_MASK) >= XDEV_U3) { | ||
393 | xhci_warn(xhci, "USB core suspending device " | ||
394 | "not in U0/U1/U2.\n"); | ||
395 | goto error; | ||
396 | } | ||
397 | |||
398 | slot_id = xhci_find_slot_id_by_port(xhci, wIndex + 1); | ||
399 | if (!slot_id) { | ||
400 | xhci_warn(xhci, "slot_id is zero\n"); | ||
401 | goto error; | ||
402 | } | ||
403 | /* unlock to execute stop endpoint commands */ | ||
404 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
405 | xhci_stop_device(xhci, slot_id, 1); | ||
406 | spin_lock_irqsave(&xhci->lock, flags); | ||
407 | |||
408 | temp = xhci_port_state_to_neutral(temp); | ||
409 | temp &= ~PORT_PLS_MASK; | ||
410 | temp |= PORT_LINK_STROBE | XDEV_U3; | ||
411 | xhci_writel(xhci, temp, addr); | ||
412 | |||
413 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
414 | msleep(10); /* wait device to enter */ | ||
415 | spin_lock_irqsave(&xhci->lock, flags); | ||
416 | |||
417 | temp = xhci_readl(xhci, addr); | ||
418 | xhci->suspended_ports[wIndex >> 5] |= | ||
419 | 1 << (wIndex & (31)); | ||
420 | break; | ||
241 | case USB_PORT_FEAT_POWER: | 421 | case USB_PORT_FEAT_POWER: |
242 | /* | 422 | /* |
243 | * Turn on ports, even if there isn't per-port switching. | 423 | * Turn on ports, even if there isn't per-port switching. |
@@ -271,6 +451,52 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
271 | temp = xhci_readl(xhci, addr); | 451 | temp = xhci_readl(xhci, addr); |
272 | temp = xhci_port_state_to_neutral(temp); | 452 | temp = xhci_port_state_to_neutral(temp); |
273 | switch (wValue) { | 453 | switch (wValue) { |
454 | case USB_PORT_FEAT_SUSPEND: | ||
455 | temp = xhci_readl(xhci, addr); | ||
456 | xhci_dbg(xhci, "clear USB_PORT_FEAT_SUSPEND\n"); | ||
457 | xhci_dbg(xhci, "PORTSC %04x\n", temp); | ||
458 | if (temp & PORT_RESET) | ||
459 | goto error; | ||
460 | if (temp & XDEV_U3) { | ||
461 | if ((temp & PORT_PE) == 0) | ||
462 | goto error; | ||
463 | if (DEV_SUPERSPEED(temp)) { | ||
464 | temp = xhci_port_state_to_neutral(temp); | ||
465 | temp &= ~PORT_PLS_MASK; | ||
466 | temp |= PORT_LINK_STROBE | XDEV_U0; | ||
467 | xhci_writel(xhci, temp, addr); | ||
468 | xhci_readl(xhci, addr); | ||
469 | } else { | ||
470 | temp = xhci_port_state_to_neutral(temp); | ||
471 | temp &= ~PORT_PLS_MASK; | ||
472 | temp |= PORT_LINK_STROBE | XDEV_RESUME; | ||
473 | xhci_writel(xhci, temp, addr); | ||
474 | |||
475 | spin_unlock_irqrestore(&xhci->lock, | ||
476 | flags); | ||
477 | msleep(20); | ||
478 | spin_lock_irqsave(&xhci->lock, flags); | ||
479 | |||
480 | temp = xhci_readl(xhci, addr); | ||
481 | temp = xhci_port_state_to_neutral(temp); | ||
482 | temp &= ~PORT_PLS_MASK; | ||
483 | temp |= PORT_LINK_STROBE | XDEV_U0; | ||
484 | xhci_writel(xhci, temp, addr); | ||
485 | } | ||
486 | xhci->port_c_suspend[wIndex >> 5] |= | ||
487 | 1 << (wIndex & 31); | ||
488 | } | ||
489 | |||
490 | slot_id = xhci_find_slot_id_by_port(xhci, wIndex + 1); | ||
491 | if (!slot_id) { | ||
492 | xhci_dbg(xhci, "slot_id is zero\n"); | ||
493 | goto error; | ||
494 | } | ||
495 | xhci_ring_device(xhci, slot_id); | ||
496 | break; | ||
497 | case USB_PORT_FEAT_C_SUSPEND: | ||
498 | xhci->port_c_suspend[wIndex >> 5] &= | ||
499 | ~(1 << (wIndex & 31)); | ||
274 | case USB_PORT_FEAT_C_RESET: | 500 | case USB_PORT_FEAT_C_RESET: |
275 | case USB_PORT_FEAT_C_CONNECTION: | 501 | case USB_PORT_FEAT_C_CONNECTION: |
276 | case USB_PORT_FEAT_C_OVER_CURRENT: | 502 | case USB_PORT_FEAT_C_OVER_CURRENT: |
@@ -306,6 +532,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
306 | { | 532 | { |
307 | unsigned long flags; | 533 | unsigned long flags; |
308 | u32 temp, status; | 534 | u32 temp, status; |
535 | u32 mask; | ||
309 | int i, retval; | 536 | int i, retval; |
310 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 537 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
311 | int ports; | 538 | int ports; |
@@ -318,13 +545,18 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
318 | memset(buf, 0, retval); | 545 | memset(buf, 0, retval); |
319 | status = 0; | 546 | status = 0; |
320 | 547 | ||
548 | mask = PORT_CSC | PORT_PEC | PORT_OCC; | ||
549 | |||
321 | spin_lock_irqsave(&xhci->lock, flags); | 550 | spin_lock_irqsave(&xhci->lock, flags); |
322 | /* For each port, did anything change? If so, set that bit in buf. */ | 551 | /* For each port, did anything change? If so, set that bit in buf. */ |
323 | for (i = 0; i < ports; i++) { | 552 | for (i = 0; i < ports; i++) { |
324 | addr = &xhci->op_regs->port_status_base + | 553 | addr = &xhci->op_regs->port_status_base + |
325 | NUM_PORT_REGS*i; | 554 | NUM_PORT_REGS*i; |
326 | temp = xhci_readl(xhci, addr); | 555 | temp = xhci_readl(xhci, addr); |
327 | if (temp & (PORT_CSC | PORT_PEC | PORT_OCC)) { | 556 | if ((temp & mask) != 0 || |
557 | (xhci->port_c_suspend[i >> 5] & 1 << (i & 31)) || | ||
558 | (xhci->resume_done[i] && time_after_eq( | ||
559 | jiffies, xhci->resume_done[i]))) { | ||
328 | buf[(i + 1) / 8] |= 1 << (i + 1) % 8; | 560 | buf[(i + 1) / 8] |= 1 << (i + 1) % 8; |
329 | status = 1; | 561 | status = 1; |
330 | } | 562 | } |
@@ -332,3 +564,182 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
332 | spin_unlock_irqrestore(&xhci->lock, flags); | 564 | spin_unlock_irqrestore(&xhci->lock, flags); |
333 | return status ? retval : 0; | 565 | return status ? retval : 0; |
334 | } | 566 | } |
567 | |||
568 | #ifdef CONFIG_PM | ||
569 | |||
570 | int xhci_bus_suspend(struct usb_hcd *hcd) | ||
571 | { | ||
572 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | ||
573 | int port; | ||
574 | unsigned long flags; | ||
575 | |||
576 | xhci_dbg(xhci, "suspend root hub\n"); | ||
577 | |||
578 | spin_lock_irqsave(&xhci->lock, flags); | ||
579 | |||
580 | if (hcd->self.root_hub->do_remote_wakeup) { | ||
581 | port = HCS_MAX_PORTS(xhci->hcs_params1); | ||
582 | while (port--) { | ||
583 | if (xhci->resume_done[port] != 0) { | ||
584 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
585 | xhci_dbg(xhci, "suspend failed because " | ||
586 | "port %d is resuming\n", | ||
587 | port + 1); | ||
588 | return -EBUSY; | ||
589 | } | ||
590 | } | ||
591 | } | ||
592 | |||
593 | port = HCS_MAX_PORTS(xhci->hcs_params1); | ||
594 | xhci->bus_suspended = 0; | ||
595 | while (port--) { | ||
596 | /* suspend the port if the port is not suspended */ | ||
597 | u32 __iomem *addr; | ||
598 | u32 t1, t2; | ||
599 | int slot_id; | ||
600 | |||
601 | addr = &xhci->op_regs->port_status_base + | ||
602 | NUM_PORT_REGS * (port & 0xff); | ||
603 | t1 = xhci_readl(xhci, addr); | ||
604 | t2 = xhci_port_state_to_neutral(t1); | ||
605 | |||
606 | if ((t1 & PORT_PE) && !(t1 & PORT_PLS_MASK)) { | ||
607 | xhci_dbg(xhci, "port %d not suspended\n", port); | ||
608 | slot_id = xhci_find_slot_id_by_port(xhci, port + 1); | ||
609 | if (slot_id) { | ||
610 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
611 | xhci_stop_device(xhci, slot_id, 1); | ||
612 | spin_lock_irqsave(&xhci->lock, flags); | ||
613 | } | ||
614 | t2 &= ~PORT_PLS_MASK; | ||
615 | t2 |= PORT_LINK_STROBE | XDEV_U3; | ||
616 | set_bit(port, &xhci->bus_suspended); | ||
617 | } | ||
618 | if (hcd->self.root_hub->do_remote_wakeup) { | ||
619 | if (t1 & PORT_CONNECT) { | ||
620 | t2 |= PORT_WKOC_E | PORT_WKDISC_E; | ||
621 | t2 &= ~PORT_WKCONN_E; | ||
622 | } else { | ||
623 | t2 |= PORT_WKOC_E | PORT_WKCONN_E; | ||
624 | t2 &= ~PORT_WKDISC_E; | ||
625 | } | ||
626 | } else | ||
627 | t2 &= ~PORT_WAKE_BITS; | ||
628 | |||
629 | t1 = xhci_port_state_to_neutral(t1); | ||
630 | if (t1 != t2) | ||
631 | xhci_writel(xhci, t2, addr); | ||
632 | |||
633 | if (DEV_HIGHSPEED(t1)) { | ||
634 | /* enable remote wake up for USB 2.0 */ | ||
635 | u32 __iomem *addr; | ||
636 | u32 tmp; | ||
637 | |||
638 | addr = &xhci->op_regs->port_power_base + | ||
639 | NUM_PORT_REGS * (port & 0xff); | ||
640 | tmp = xhci_readl(xhci, addr); | ||
641 | tmp |= PORT_RWE; | ||
642 | xhci_writel(xhci, tmp, addr); | ||
643 | } | ||
644 | } | ||
645 | hcd->state = HC_STATE_SUSPENDED; | ||
646 | xhci->next_statechange = jiffies + msecs_to_jiffies(10); | ||
647 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
648 | return 0; | ||
649 | } | ||
650 | |||
651 | int xhci_bus_resume(struct usb_hcd *hcd) | ||
652 | { | ||
653 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | ||
654 | int port; | ||
655 | u32 temp; | ||
656 | unsigned long flags; | ||
657 | |||
658 | xhci_dbg(xhci, "resume root hub\n"); | ||
659 | |||
660 | if (time_before(jiffies, xhci->next_statechange)) | ||
661 | msleep(5); | ||
662 | |||
663 | spin_lock_irqsave(&xhci->lock, flags); | ||
664 | if (!HCD_HW_ACCESSIBLE(hcd)) { | ||
665 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
666 | return -ESHUTDOWN; | ||
667 | } | ||
668 | |||
669 | /* delay the irqs */ | ||
670 | temp = xhci_readl(xhci, &xhci->op_regs->command); | ||
671 | temp &= ~CMD_EIE; | ||
672 | xhci_writel(xhci, temp, &xhci->op_regs->command); | ||
673 | |||
674 | port = HCS_MAX_PORTS(xhci->hcs_params1); | ||
675 | while (port--) { | ||
676 | /* Check whether need resume ports. If needed | ||
677 | resume port and disable remote wakeup */ | ||
678 | u32 __iomem *addr; | ||
679 | u32 temp; | ||
680 | int slot_id; | ||
681 | |||
682 | addr = &xhci->op_regs->port_status_base + | ||
683 | NUM_PORT_REGS * (port & 0xff); | ||
684 | temp = xhci_readl(xhci, addr); | ||
685 | if (DEV_SUPERSPEED(temp)) | ||
686 | temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS); | ||
687 | else | ||
688 | temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); | ||
689 | if (test_bit(port, &xhci->bus_suspended) && | ||
690 | (temp & PORT_PLS_MASK)) { | ||
691 | if (DEV_SUPERSPEED(temp)) { | ||
692 | temp = xhci_port_state_to_neutral(temp); | ||
693 | temp &= ~PORT_PLS_MASK; | ||
694 | temp |= PORT_LINK_STROBE | XDEV_U0; | ||
695 | xhci_writel(xhci, temp, addr); | ||
696 | } else { | ||
697 | temp = xhci_port_state_to_neutral(temp); | ||
698 | temp &= ~PORT_PLS_MASK; | ||
699 | temp |= PORT_LINK_STROBE | XDEV_RESUME; | ||
700 | xhci_writel(xhci, temp, addr); | ||
701 | |||
702 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
703 | msleep(20); | ||
704 | spin_lock_irqsave(&xhci->lock, flags); | ||
705 | |||
706 | temp = xhci_readl(xhci, addr); | ||
707 | temp = xhci_port_state_to_neutral(temp); | ||
708 | temp &= ~PORT_PLS_MASK; | ||
709 | temp |= PORT_LINK_STROBE | XDEV_U0; | ||
710 | xhci_writel(xhci, temp, addr); | ||
711 | } | ||
712 | slot_id = xhci_find_slot_id_by_port(xhci, port + 1); | ||
713 | if (slot_id) | ||
714 | xhci_ring_device(xhci, slot_id); | ||
715 | } else | ||
716 | xhci_writel(xhci, temp, addr); | ||
717 | |||
718 | if (DEV_HIGHSPEED(temp)) { | ||
719 | /* disable remote wake up for USB 2.0 */ | ||
720 | u32 __iomem *addr; | ||
721 | u32 tmp; | ||
722 | |||
723 | addr = &xhci->op_regs->port_power_base + | ||
724 | NUM_PORT_REGS * (port & 0xff); | ||
725 | tmp = xhci_readl(xhci, addr); | ||
726 | tmp &= ~PORT_RWE; | ||
727 | xhci_writel(xhci, tmp, addr); | ||
728 | } | ||
729 | } | ||
730 | |||
731 | (void) xhci_readl(xhci, &xhci->op_regs->command); | ||
732 | |||
733 | xhci->next_statechange = jiffies + msecs_to_jiffies(5); | ||
734 | hcd->state = HC_STATE_RUNNING; | ||
735 | /* re-enable irqs */ | ||
736 | temp = xhci_readl(xhci, &xhci->op_regs->command); | ||
737 | temp |= CMD_EIE; | ||
738 | xhci_writel(xhci, temp, &xhci->op_regs->command); | ||
739 | temp = xhci_readl(xhci, &xhci->op_regs->command); | ||
740 | |||
741 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
742 | return 0; | ||
743 | } | ||
744 | |||
745 | #endif /* CONFIG_PM */ | ||
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 4e51343ddffc..202770676da3 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -778,6 +778,7 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, | |||
778 | 778 | ||
779 | init_completion(&dev->cmd_completion); | 779 | init_completion(&dev->cmd_completion); |
780 | INIT_LIST_HEAD(&dev->cmd_list); | 780 | INIT_LIST_HEAD(&dev->cmd_list); |
781 | dev->udev = udev; | ||
781 | 782 | ||
782 | /* Point to output device context in dcbaa. */ | 783 | /* Point to output device context in dcbaa. */ |
783 | xhci->dcbaa->dev_context_ptrs[slot_id] = dev->out_ctx->dma; | 784 | xhci->dcbaa->dev_context_ptrs[slot_id] = dev->out_ctx->dma; |
@@ -866,6 +867,7 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud | |||
866 | top_dev = top_dev->parent) | 867 | top_dev = top_dev->parent) |
867 | /* Found device below root hub */; | 868 | /* Found device below root hub */; |
868 | slot_ctx->dev_info2 |= (u32) ROOT_HUB_PORT(top_dev->portnum); | 869 | slot_ctx->dev_info2 |= (u32) ROOT_HUB_PORT(top_dev->portnum); |
870 | dev->port = top_dev->portnum; | ||
869 | xhci_dbg(xhci, "Set root hub portnum to %d\n", top_dev->portnum); | 871 | xhci_dbg(xhci, "Set root hub portnum to %d\n", top_dev->portnum); |
870 | 872 | ||
871 | /* Is this a LS/FS device under a HS hub? */ | 873 | /* Is this a LS/FS device under a HS hub? */ |
@@ -1443,6 +1445,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
1443 | scratchpad_free(xhci); | 1445 | scratchpad_free(xhci); |
1444 | xhci->page_size = 0; | 1446 | xhci->page_size = 0; |
1445 | xhci->page_shift = 0; | 1447 | xhci->page_shift = 0; |
1448 | xhci->bus_suspended = 0; | ||
1446 | } | 1449 | } |
1447 | 1450 | ||
1448 | static int xhci_test_trb_in_td(struct xhci_hcd *xhci, | 1451 | static int xhci_test_trb_in_td(struct xhci_hcd *xhci, |
@@ -1801,6 +1804,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
1801 | init_completion(&xhci->addr_dev); | 1804 | init_completion(&xhci->addr_dev); |
1802 | for (i = 0; i < MAX_HC_SLOTS; ++i) | 1805 | for (i = 0; i < MAX_HC_SLOTS; ++i) |
1803 | xhci->devs[i] = NULL; | 1806 | xhci->devs[i] = NULL; |
1807 | for (i = 0; i < MAX_HC_PORTS; ++i) | ||
1808 | xhci->resume_done[i] = 0; | ||
1804 | 1809 | ||
1805 | if (scratchpad_alloc(xhci, flags)) | 1810 | if (scratchpad_alloc(xhci, flags)) |
1806 | goto fail; | 1811 | goto fail; |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index f7efe025beda..bb668a894ab9 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -116,6 +116,30 @@ static int xhci_pci_setup(struct usb_hcd *hcd) | |||
116 | return xhci_pci_reinit(xhci, pdev); | 116 | return xhci_pci_reinit(xhci, pdev); |
117 | } | 117 | } |
118 | 118 | ||
119 | #ifdef CONFIG_PM | ||
120 | static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) | ||
121 | { | ||
122 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | ||
123 | int retval = 0; | ||
124 | |||
125 | if (hcd->state != HC_STATE_SUSPENDED) | ||
126 | return -EINVAL; | ||
127 | |||
128 | retval = xhci_suspend(xhci); | ||
129 | |||
130 | return retval; | ||
131 | } | ||
132 | |||
133 | static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) | ||
134 | { | ||
135 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | ||
136 | int retval = 0; | ||
137 | |||
138 | retval = xhci_resume(xhci, hibernated); | ||
139 | return retval; | ||
140 | } | ||
141 | #endif /* CONFIG_PM */ | ||
142 | |||
119 | static const struct hc_driver xhci_pci_hc_driver = { | 143 | static const struct hc_driver xhci_pci_hc_driver = { |
120 | .description = hcd_name, | 144 | .description = hcd_name, |
121 | .product_desc = "xHCI Host Controller", | 145 | .product_desc = "xHCI Host Controller", |
@@ -132,7 +156,10 @@ static const struct hc_driver xhci_pci_hc_driver = { | |||
132 | */ | 156 | */ |
133 | .reset = xhci_pci_setup, | 157 | .reset = xhci_pci_setup, |
134 | .start = xhci_run, | 158 | .start = xhci_run, |
135 | /* suspend and resume implemented later */ | 159 | #ifdef CONFIG_PM |
160 | .pci_suspend = xhci_pci_suspend, | ||
161 | .pci_resume = xhci_pci_resume, | ||
162 | #endif | ||
136 | .stop = xhci_stop, | 163 | .stop = xhci_stop, |
137 | .shutdown = xhci_shutdown, | 164 | .shutdown = xhci_shutdown, |
138 | 165 | ||
@@ -152,7 +179,7 @@ static const struct hc_driver xhci_pci_hc_driver = { | |||
152 | .reset_bandwidth = xhci_reset_bandwidth, | 179 | .reset_bandwidth = xhci_reset_bandwidth, |
153 | .address_device = xhci_address_device, | 180 | .address_device = xhci_address_device, |
154 | .update_hub_device = xhci_update_hub_device, | 181 | .update_hub_device = xhci_update_hub_device, |
155 | .reset_device = xhci_reset_device, | 182 | .reset_device = xhci_discover_or_reset_device, |
156 | 183 | ||
157 | /* | 184 | /* |
158 | * scheduling support | 185 | * scheduling support |
@@ -162,6 +189,8 @@ static const struct hc_driver xhci_pci_hc_driver = { | |||
162 | /* Root hub support */ | 189 | /* Root hub support */ |
163 | .hub_control = xhci_hub_control, | 190 | .hub_control = xhci_hub_control, |
164 | .hub_status_data = xhci_hub_status_data, | 191 | .hub_status_data = xhci_hub_status_data, |
192 | .bus_suspend = xhci_bus_suspend, | ||
193 | .bus_resume = xhci_bus_resume, | ||
165 | }; | 194 | }; |
166 | 195 | ||
167 | /*-------------------------------------------------------------------------*/ | 196 | /*-------------------------------------------------------------------------*/ |
@@ -186,6 +215,11 @@ static struct pci_driver xhci_pci_driver = { | |||
186 | /* suspend and resume implemented later */ | 215 | /* suspend and resume implemented later */ |
187 | 216 | ||
188 | .shutdown = usb_hcd_pci_shutdown, | 217 | .shutdown = usb_hcd_pci_shutdown, |
218 | #ifdef CONFIG_PM_SLEEP | ||
219 | .driver = { | ||
220 | .pm = &usb_hcd_pci_pm_ops | ||
221 | }, | ||
222 | #endif | ||
189 | }; | 223 | }; |
190 | 224 | ||
191 | int xhci_register_pci(void) | 225 | int xhci_register_pci(void) |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 48e60d166ff0..9f3115e729b1 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -68,6 +68,10 @@ | |||
68 | #include <linux/slab.h> | 68 | #include <linux/slab.h> |
69 | #include "xhci.h" | 69 | #include "xhci.h" |
70 | 70 | ||
71 | static int handle_cmd_in_cmd_wait_list(struct xhci_hcd *xhci, | ||
72 | struct xhci_virt_device *virt_dev, | ||
73 | struct xhci_event_cmd *event); | ||
74 | |||
71 | /* | 75 | /* |
72 | * Returns zero if the TRB isn't in this segment, otherwise it returns the DMA | 76 | * Returns zero if the TRB isn't in this segment, otherwise it returns the DMA |
73 | * address of the TRB. | 77 | * address of the TRB. |
@@ -313,7 +317,7 @@ void xhci_ring_cmd_db(struct xhci_hcd *xhci) | |||
313 | xhci_readl(xhci, &xhci->dba->doorbell[0]); | 317 | xhci_readl(xhci, &xhci->dba->doorbell[0]); |
314 | } | 318 | } |
315 | 319 | ||
316 | static void ring_ep_doorbell(struct xhci_hcd *xhci, | 320 | void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, |
317 | unsigned int slot_id, | 321 | unsigned int slot_id, |
318 | unsigned int ep_index, | 322 | unsigned int ep_index, |
319 | unsigned int stream_id) | 323 | unsigned int stream_id) |
@@ -353,7 +357,7 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd *xhci, | |||
353 | /* A ring has pending URBs if its TD list is not empty */ | 357 | /* A ring has pending URBs if its TD list is not empty */ |
354 | if (!(ep->ep_state & EP_HAS_STREAMS)) { | 358 | if (!(ep->ep_state & EP_HAS_STREAMS)) { |
355 | if (!(list_empty(&ep->ring->td_list))) | 359 | if (!(list_empty(&ep->ring->td_list))) |
356 | ring_ep_doorbell(xhci, slot_id, ep_index, 0); | 360 | xhci_ring_ep_doorbell(xhci, slot_id, ep_index, 0); |
357 | return; | 361 | return; |
358 | } | 362 | } |
359 | 363 | ||
@@ -361,7 +365,8 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd *xhci, | |||
361 | stream_id++) { | 365 | stream_id++) { |
362 | struct xhci_stream_info *stream_info = ep->stream_info; | 366 | struct xhci_stream_info *stream_info = ep->stream_info; |
363 | if (!list_empty(&stream_info->stream_rings[stream_id]->td_list)) | 367 | if (!list_empty(&stream_info->stream_rings[stream_id]->td_list)) |
364 | ring_ep_doorbell(xhci, slot_id, ep_index, stream_id); | 368 | xhci_ring_ep_doorbell(xhci, slot_id, ep_index, |
369 | stream_id); | ||
365 | } | 370 | } |
366 | } | 371 | } |
367 | 372 | ||
@@ -626,10 +631,11 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, | |||
626 | * bit cleared) so that the HW will skip over them. | 631 | * bit cleared) so that the HW will skip over them. |
627 | */ | 632 | */ |
628 | static void handle_stopped_endpoint(struct xhci_hcd *xhci, | 633 | static void handle_stopped_endpoint(struct xhci_hcd *xhci, |
629 | union xhci_trb *trb) | 634 | union xhci_trb *trb, struct xhci_event_cmd *event) |
630 | { | 635 | { |
631 | unsigned int slot_id; | 636 | unsigned int slot_id; |
632 | unsigned int ep_index; | 637 | unsigned int ep_index; |
638 | struct xhci_virt_device *virt_dev; | ||
633 | struct xhci_ring *ep_ring; | 639 | struct xhci_ring *ep_ring; |
634 | struct xhci_virt_ep *ep; | 640 | struct xhci_virt_ep *ep; |
635 | struct list_head *entry; | 641 | struct list_head *entry; |
@@ -638,6 +644,21 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, | |||
638 | 644 | ||
639 | struct xhci_dequeue_state deq_state; | 645 | struct xhci_dequeue_state deq_state; |
640 | 646 | ||
647 | if (unlikely(TRB_TO_SUSPEND_PORT( | ||
648 | xhci->cmd_ring->dequeue->generic.field[3]))) { | ||
649 | slot_id = TRB_TO_SLOT_ID( | ||
650 | xhci->cmd_ring->dequeue->generic.field[3]); | ||
651 | virt_dev = xhci->devs[slot_id]; | ||
652 | if (virt_dev) | ||
653 | handle_cmd_in_cmd_wait_list(xhci, virt_dev, | ||
654 | event); | ||
655 | else | ||
656 | xhci_warn(xhci, "Stop endpoint command " | ||
657 | "completion for disabled slot %u\n", | ||
658 | slot_id); | ||
659 | return; | ||
660 | } | ||
661 | |||
641 | memset(&deq_state, 0, sizeof(deq_state)); | 662 | memset(&deq_state, 0, sizeof(deq_state)); |
642 | slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]); | 663 | slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]); |
643 | ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]); | 664 | ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]); |
@@ -1091,7 +1112,7 @@ bandwidth_change: | |||
1091 | complete(&xhci->addr_dev); | 1112 | complete(&xhci->addr_dev); |
1092 | break; | 1113 | break; |
1093 | case TRB_TYPE(TRB_STOP_RING): | 1114 | case TRB_TYPE(TRB_STOP_RING): |
1094 | handle_stopped_endpoint(xhci, xhci->cmd_ring->dequeue); | 1115 | handle_stopped_endpoint(xhci, xhci->cmd_ring->dequeue, event); |
1095 | break; | 1116 | break; |
1096 | case TRB_TYPE(TRB_SET_DEQ): | 1117 | case TRB_TYPE(TRB_SET_DEQ): |
1097 | handle_set_deq_completion(xhci, event, xhci->cmd_ring->dequeue); | 1118 | handle_set_deq_completion(xhci, event, xhci->cmd_ring->dequeue); |
@@ -1144,17 +1165,72 @@ static void handle_vendor_event(struct xhci_hcd *xhci, | |||
1144 | static void handle_port_status(struct xhci_hcd *xhci, | 1165 | static void handle_port_status(struct xhci_hcd *xhci, |
1145 | union xhci_trb *event) | 1166 | union xhci_trb *event) |
1146 | { | 1167 | { |
1168 | struct usb_hcd *hcd = xhci_to_hcd(xhci); | ||
1147 | u32 port_id; | 1169 | u32 port_id; |
1170 | u32 temp, temp1; | ||
1171 | u32 __iomem *addr; | ||
1172 | int ports; | ||
1173 | int slot_id; | ||
1148 | 1174 | ||
1149 | /* Port status change events always have a successful completion code */ | 1175 | /* Port status change events always have a successful completion code */ |
1150 | if (GET_COMP_CODE(event->generic.field[2]) != COMP_SUCCESS) { | 1176 | if (GET_COMP_CODE(event->generic.field[2]) != COMP_SUCCESS) { |
1151 | xhci_warn(xhci, "WARN: xHC returned failed port status event\n"); | 1177 | xhci_warn(xhci, "WARN: xHC returned failed port status event\n"); |
1152 | xhci->error_bitmask |= 1 << 8; | 1178 | xhci->error_bitmask |= 1 << 8; |
1153 | } | 1179 | } |
1154 | /* FIXME: core doesn't care about all port link state changes yet */ | ||
1155 | port_id = GET_PORT_ID(event->generic.field[0]); | 1180 | port_id = GET_PORT_ID(event->generic.field[0]); |
1156 | xhci_dbg(xhci, "Port Status Change Event for port %d\n", port_id); | 1181 | xhci_dbg(xhci, "Port Status Change Event for port %d\n", port_id); |
1157 | 1182 | ||
1183 | ports = HCS_MAX_PORTS(xhci->hcs_params1); | ||
1184 | if ((port_id <= 0) || (port_id > ports)) { | ||
1185 | xhci_warn(xhci, "Invalid port id %d\n", port_id); | ||
1186 | goto cleanup; | ||
1187 | } | ||
1188 | |||
1189 | addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS * (port_id - 1); | ||
1190 | temp = xhci_readl(xhci, addr); | ||
1191 | if ((temp & PORT_CONNECT) && (hcd->state == HC_STATE_SUSPENDED)) { | ||
1192 | xhci_dbg(xhci, "resume root hub\n"); | ||
1193 | usb_hcd_resume_root_hub(hcd); | ||
1194 | } | ||
1195 | |||
1196 | if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_RESUME) { | ||
1197 | xhci_dbg(xhci, "port resume event for port %d\n", port_id); | ||
1198 | |||
1199 | temp1 = xhci_readl(xhci, &xhci->op_regs->command); | ||
1200 | if (!(temp1 & CMD_RUN)) { | ||
1201 | xhci_warn(xhci, "xHC is not running.\n"); | ||
1202 | goto cleanup; | ||
1203 | } | ||
1204 | |||
1205 | if (DEV_SUPERSPEED(temp)) { | ||
1206 | xhci_dbg(xhci, "resume SS port %d\n", port_id); | ||
1207 | temp = xhci_port_state_to_neutral(temp); | ||
1208 | temp &= ~PORT_PLS_MASK; | ||
1209 | temp |= PORT_LINK_STROBE | XDEV_U0; | ||
1210 | xhci_writel(xhci, temp, addr); | ||
1211 | slot_id = xhci_find_slot_id_by_port(xhci, port_id); | ||
1212 | if (!slot_id) { | ||
1213 | xhci_dbg(xhci, "slot_id is zero\n"); | ||
1214 | goto cleanup; | ||
1215 | } | ||
1216 | xhci_ring_device(xhci, slot_id); | ||
1217 | xhci_dbg(xhci, "resume SS port %d finished\n", port_id); | ||
1218 | /* Clear PORT_PLC */ | ||
1219 | temp = xhci_readl(xhci, addr); | ||
1220 | temp = xhci_port_state_to_neutral(temp); | ||
1221 | temp |= PORT_PLC; | ||
1222 | xhci_writel(xhci, temp, addr); | ||
1223 | } else { | ||
1224 | xhci_dbg(xhci, "resume HS port %d\n", port_id); | ||
1225 | xhci->resume_done[port_id - 1] = jiffies + | ||
1226 | msecs_to_jiffies(20); | ||
1227 | mod_timer(&hcd->rh_timer, | ||
1228 | xhci->resume_done[port_id - 1]); | ||
1229 | /* Do the rest in GetPortStatus */ | ||
1230 | } | ||
1231 | } | ||
1232 | |||
1233 | cleanup: | ||
1158 | /* Update event ring dequeue pointer before dropping the lock */ | 1234 | /* Update event ring dequeue pointer before dropping the lock */ |
1159 | inc_deq(xhci, xhci->event_ring, true); | 1235 | inc_deq(xhci, xhci->event_ring, true); |
1160 | 1236 | ||
@@ -2347,7 +2423,7 @@ static void giveback_first_trb(struct xhci_hcd *xhci, int slot_id, | |||
2347 | */ | 2423 | */ |
2348 | wmb(); | 2424 | wmb(); |
2349 | start_trb->field[3] |= start_cycle; | 2425 | start_trb->field[3] |= start_cycle; |
2350 | ring_ep_doorbell(xhci, slot_id, ep_index, stream_id); | 2426 | xhci_ring_ep_doorbell(xhci, slot_id, ep_index, stream_id); |
2351 | } | 2427 | } |
2352 | 2428 | ||
2353 | /* | 2429 | /* |
@@ -2931,7 +3007,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
2931 | wmb(); | 3007 | wmb(); |
2932 | start_trb->field[3] |= start_cycle; | 3008 | start_trb->field[3] |= start_cycle; |
2933 | 3009 | ||
2934 | ring_ep_doorbell(xhci, slot_id, ep_index, urb->stream_id); | 3010 | xhci_ring_ep_doorbell(xhci, slot_id, ep_index, urb->stream_id); |
2935 | return 0; | 3011 | return 0; |
2936 | } | 3012 | } |
2937 | 3013 | ||
@@ -3108,15 +3184,20 @@ int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | |||
3108 | false); | 3184 | false); |
3109 | } | 3185 | } |
3110 | 3186 | ||
3187 | /* | ||
3188 | * Suspend is set to indicate "Stop Endpoint Command" is being issued to stop | ||
3189 | * activity on an endpoint that is about to be suspended. | ||
3190 | */ | ||
3111 | int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, | 3191 | int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, |
3112 | unsigned int ep_index) | 3192 | unsigned int ep_index, int suspend) |
3113 | { | 3193 | { |
3114 | u32 trb_slot_id = SLOT_ID_FOR_TRB(slot_id); | 3194 | u32 trb_slot_id = SLOT_ID_FOR_TRB(slot_id); |
3115 | u32 trb_ep_index = EP_ID_FOR_TRB(ep_index); | 3195 | u32 trb_ep_index = EP_ID_FOR_TRB(ep_index); |
3116 | u32 type = TRB_TYPE(TRB_STOP_RING); | 3196 | u32 type = TRB_TYPE(TRB_STOP_RING); |
3197 | u32 trb_suspend = SUSPEND_PORT_FOR_TRB(suspend); | ||
3117 | 3198 | ||
3118 | return queue_command(xhci, 0, 0, 0, | 3199 | return queue_command(xhci, 0, 0, 0, |
3119 | trb_slot_id | trb_ep_index | type, false); | 3200 | trb_slot_id | trb_ep_index | type | trb_suspend, false); |
3120 | } | 3201 | } |
3121 | 3202 | ||
3122 | /* Set Transfer Ring Dequeue Pointer command. | 3203 | /* Set Transfer Ring Dequeue Pointer command. |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index d5c550ea3e68..5d7d4e951ea4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -551,6 +551,218 @@ void xhci_shutdown(struct usb_hcd *hcd) | |||
551 | xhci_readl(xhci, &xhci->op_regs->status)); | 551 | xhci_readl(xhci, &xhci->op_regs->status)); |
552 | } | 552 | } |
553 | 553 | ||
554 | #ifdef CONFIG_PM | ||
555 | static void xhci_save_registers(struct xhci_hcd *xhci) | ||
556 | { | ||
557 | xhci->s3.command = xhci_readl(xhci, &xhci->op_regs->command); | ||
558 | xhci->s3.dev_nt = xhci_readl(xhci, &xhci->op_regs->dev_notification); | ||
559 | xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); | ||
560 | xhci->s3.config_reg = xhci_readl(xhci, &xhci->op_regs->config_reg); | ||
561 | xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); | ||
562 | xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control); | ||
563 | xhci->s3.erst_size = xhci_readl(xhci, &xhci->ir_set->erst_size); | ||
564 | xhci->s3.erst_base = xhci_read_64(xhci, &xhci->ir_set->erst_base); | ||
565 | xhci->s3.erst_dequeue = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); | ||
566 | } | ||
567 | |||
568 | static void xhci_restore_registers(struct xhci_hcd *xhci) | ||
569 | { | ||
570 | xhci_writel(xhci, xhci->s3.command, &xhci->op_regs->command); | ||
571 | xhci_writel(xhci, xhci->s3.dev_nt, &xhci->op_regs->dev_notification); | ||
572 | xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr); | ||
573 | xhci_writel(xhci, xhci->s3.config_reg, &xhci->op_regs->config_reg); | ||
574 | xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending); | ||
575 | xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control); | ||
576 | xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size); | ||
577 | xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); | ||
578 | } | ||
579 | |||
580 | /* | ||
581 | * Stop HC (not bus-specific) | ||
582 | * | ||
583 | * This is called when the machine transition into S3/S4 mode. | ||
584 | * | ||
585 | */ | ||
586 | int xhci_suspend(struct xhci_hcd *xhci) | ||
587 | { | ||
588 | int rc = 0; | ||
589 | struct usb_hcd *hcd = xhci_to_hcd(xhci); | ||
590 | u32 command; | ||
591 | |||
592 | spin_lock_irq(&xhci->lock); | ||
593 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
594 | /* step 1: stop endpoint */ | ||
595 | /* skipped assuming that port suspend has done */ | ||
596 | |||
597 | /* step 2: clear Run/Stop bit */ | ||
598 | command = xhci_readl(xhci, &xhci->op_regs->command); | ||
599 | command &= ~CMD_RUN; | ||
600 | xhci_writel(xhci, command, &xhci->op_regs->command); | ||
601 | if (handshake(xhci, &xhci->op_regs->status, | ||
602 | STS_HALT, STS_HALT, 100*100)) { | ||
603 | xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n"); | ||
604 | spin_unlock_irq(&xhci->lock); | ||
605 | return -ETIMEDOUT; | ||
606 | } | ||
607 | |||
608 | /* step 3: save registers */ | ||
609 | xhci_save_registers(xhci); | ||
610 | |||
611 | /* step 4: set CSS flag */ | ||
612 | command = xhci_readl(xhci, &xhci->op_regs->command); | ||
613 | command |= CMD_CSS; | ||
614 | xhci_writel(xhci, command, &xhci->op_regs->command); | ||
615 | if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10*100)) { | ||
616 | xhci_warn(xhci, "WARN: xHC CMD_CSS timeout\n"); | ||
617 | spin_unlock_irq(&xhci->lock); | ||
618 | return -ETIMEDOUT; | ||
619 | } | ||
620 | /* step 5: remove core well power */ | ||
621 | xhci_cleanup_msix(xhci); | ||
622 | spin_unlock_irq(&xhci->lock); | ||
623 | |||
624 | return rc; | ||
625 | } | ||
626 | |||
627 | /* | ||
628 | * start xHC (not bus-specific) | ||
629 | * | ||
630 | * This is called when the machine transition from S3/S4 mode. | ||
631 | * | ||
632 | */ | ||
633 | int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | ||
634 | { | ||
635 | u32 command, temp = 0; | ||
636 | struct usb_hcd *hcd = xhci_to_hcd(xhci); | ||
637 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | ||
638 | u64 val_64; | ||
639 | int old_state, retval; | ||
640 | |||
641 | old_state = hcd->state; | ||
642 | if (time_before(jiffies, xhci->next_statechange)) | ||
643 | msleep(100); | ||
644 | |||
645 | spin_lock_irq(&xhci->lock); | ||
646 | |||
647 | if (!hibernated) { | ||
648 | /* step 1: restore register */ | ||
649 | xhci_restore_registers(xhci); | ||
650 | /* step 2: initialize command ring buffer */ | ||
651 | val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); | ||
652 | val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) | | ||
653 | (xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, | ||
654 | xhci->cmd_ring->dequeue) & | ||
655 | (u64) ~CMD_RING_RSVD_BITS) | | ||
656 | xhci->cmd_ring->cycle_state; | ||
657 | xhci_dbg(xhci, "// Setting command ring address to 0x%llx\n", | ||
658 | (long unsigned long) val_64); | ||
659 | xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring); | ||
660 | /* step 3: restore state and start state*/ | ||
661 | /* step 3: set CRS flag */ | ||
662 | command = xhci_readl(xhci, &xhci->op_regs->command); | ||
663 | command |= CMD_CRS; | ||
664 | xhci_writel(xhci, command, &xhci->op_regs->command); | ||
665 | if (handshake(xhci, &xhci->op_regs->status, | ||
666 | STS_RESTORE, 0, 10*100)) { | ||
667 | xhci_dbg(xhci, "WARN: xHC CMD_CSS timeout\n"); | ||
668 | spin_unlock_irq(&xhci->lock); | ||
669 | return -ETIMEDOUT; | ||
670 | } | ||
671 | temp = xhci_readl(xhci, &xhci->op_regs->status); | ||
672 | } | ||
673 | |||
674 | /* If restore operation fails, re-initialize the HC during resume */ | ||
675 | if ((temp & STS_SRE) || hibernated) { | ||
676 | usb_root_hub_lost_power(hcd->self.root_hub); | ||
677 | |||
678 | xhci_dbg(xhci, "Stop HCD\n"); | ||
679 | xhci_halt(xhci); | ||
680 | xhci_reset(xhci); | ||
681 | if (hibernated) | ||
682 | xhci_cleanup_msix(xhci); | ||
683 | spin_unlock_irq(&xhci->lock); | ||
684 | |||
685 | #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING | ||
686 | /* Tell the event ring poll function not to reschedule */ | ||
687 | xhci->zombie = 1; | ||
688 | del_timer_sync(&xhci->event_ring_timer); | ||
689 | #endif | ||
690 | |||
691 | xhci_dbg(xhci, "// Disabling event ring interrupts\n"); | ||
692 | temp = xhci_readl(xhci, &xhci->op_regs->status); | ||
693 | xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); | ||
694 | temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); | ||
695 | xhci_writel(xhci, ER_IRQ_DISABLE(temp), | ||
696 | &xhci->ir_set->irq_pending); | ||
697 | xhci_print_ir_set(xhci, xhci->ir_set, 0); | ||
698 | |||
699 | xhci_dbg(xhci, "cleaning up memory\n"); | ||
700 | xhci_mem_cleanup(xhci); | ||
701 | xhci_dbg(xhci, "xhci_stop completed - status = %x\n", | ||
702 | xhci_readl(xhci, &xhci->op_regs->status)); | ||
703 | |||
704 | xhci_dbg(xhci, "Initialize the HCD\n"); | ||
705 | retval = xhci_init(hcd); | ||
706 | if (retval) | ||
707 | return retval; | ||
708 | |||
709 | xhci_dbg(xhci, "Start the HCD\n"); | ||
710 | retval = xhci_run(hcd); | ||
711 | if (!retval) | ||
712 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
713 | hcd->state = HC_STATE_SUSPENDED; | ||
714 | return retval; | ||
715 | } | ||
716 | |||
717 | /* Re-setup MSI-X */ | ||
718 | if (hcd->irq) | ||
719 | free_irq(hcd->irq, hcd); | ||
720 | hcd->irq = -1; | ||
721 | |||
722 | retval = xhci_setup_msix(xhci); | ||
723 | if (retval) | ||
724 | /* fall back to msi*/ | ||
725 | retval = xhci_setup_msi(xhci); | ||
726 | |||
727 | if (retval) { | ||
728 | /* fall back to legacy interrupt*/ | ||
729 | retval = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, | ||
730 | hcd->irq_descr, hcd); | ||
731 | if (retval) { | ||
732 | xhci_err(xhci, "request interrupt %d failed\n", | ||
733 | pdev->irq); | ||
734 | return retval; | ||
735 | } | ||
736 | hcd->irq = pdev->irq; | ||
737 | } | ||
738 | |||
739 | /* step 4: set Run/Stop bit */ | ||
740 | command = xhci_readl(xhci, &xhci->op_regs->command); | ||
741 | command |= CMD_RUN; | ||
742 | xhci_writel(xhci, command, &xhci->op_regs->command); | ||
743 | handshake(xhci, &xhci->op_regs->status, STS_HALT, | ||
744 | 0, 250 * 1000); | ||
745 | |||
746 | /* step 5: walk topology and initialize portsc, | ||
747 | * portpmsc and portli | ||
748 | */ | ||
749 | /* this is done in bus_resume */ | ||
750 | |||
751 | /* step 6: restart each of the previously | ||
752 | * Running endpoints by ringing their doorbells | ||
753 | */ | ||
754 | |||
755 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
756 | if (!hibernated) | ||
757 | hcd->state = old_state; | ||
758 | else | ||
759 | hcd->state = HC_STATE_SUSPENDED; | ||
760 | |||
761 | spin_unlock_irq(&xhci->lock); | ||
762 | return 0; | ||
763 | } | ||
764 | #endif /* CONFIG_PM */ | ||
765 | |||
554 | /*-------------------------------------------------------------------------*/ | 766 | /*-------------------------------------------------------------------------*/ |
555 | 767 | ||
556 | /** | 768 | /** |
@@ -607,7 +819,11 @@ unsigned int xhci_last_valid_endpoint(u32 added_ctxs) | |||
607 | * returns 0 this is a root hub; returns -EINVAL for NULL pointers. | 819 | * returns 0 this is a root hub; returns -EINVAL for NULL pointers. |
608 | */ | 820 | */ |
609 | int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, | 821 | int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, |
610 | struct usb_host_endpoint *ep, int check_ep, const char *func) { | 822 | struct usb_host_endpoint *ep, int check_ep, bool check_virt_dev, |
823 | const char *func) { | ||
824 | struct xhci_hcd *xhci; | ||
825 | struct xhci_virt_device *virt_dev; | ||
826 | |||
611 | if (!hcd || (check_ep && !ep) || !udev) { | 827 | if (!hcd || (check_ep && !ep) || !udev) { |
612 | printk(KERN_DEBUG "xHCI %s called with invalid args\n", | 828 | printk(KERN_DEBUG "xHCI %s called with invalid args\n", |
613 | func); | 829 | func); |
@@ -618,11 +834,24 @@ int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, | |||
618 | func); | 834 | func); |
619 | return 0; | 835 | return 0; |
620 | } | 836 | } |
621 | if (!udev->slot_id) { | 837 | |
622 | printk(KERN_DEBUG "xHCI %s called with unaddressed device\n", | 838 | if (check_virt_dev) { |
623 | func); | 839 | xhci = hcd_to_xhci(hcd); |
624 | return -EINVAL; | 840 | if (!udev->slot_id || !xhci->devs |
841 | || !xhci->devs[udev->slot_id]) { | ||
842 | printk(KERN_DEBUG "xHCI %s called with unaddressed " | ||
843 | "device\n", func); | ||
844 | return -EINVAL; | ||
845 | } | ||
846 | |||
847 | virt_dev = xhci->devs[udev->slot_id]; | ||
848 | if (virt_dev->udev != udev) { | ||
849 | printk(KERN_DEBUG "xHCI %s called with udev and " | ||
850 | "virt_dev does not match\n", func); | ||
851 | return -EINVAL; | ||
852 | } | ||
625 | } | 853 | } |
854 | |||
626 | return 1; | 855 | return 1; |
627 | } | 856 | } |
628 | 857 | ||
@@ -704,18 +933,13 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) | |||
704 | struct urb_priv *urb_priv; | 933 | struct urb_priv *urb_priv; |
705 | int size, i; | 934 | int size, i; |
706 | 935 | ||
707 | if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0) | 936 | if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, |
937 | true, true, __func__) <= 0) | ||
708 | return -EINVAL; | 938 | return -EINVAL; |
709 | 939 | ||
710 | slot_id = urb->dev->slot_id; | 940 | slot_id = urb->dev->slot_id; |
711 | ep_index = xhci_get_endpoint_index(&urb->ep->desc); | 941 | ep_index = xhci_get_endpoint_index(&urb->ep->desc); |
712 | 942 | ||
713 | if (!xhci->devs || !xhci->devs[slot_id]) { | ||
714 | if (!in_interrupt()) | ||
715 | dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n"); | ||
716 | ret = -EINVAL; | ||
717 | goto exit; | ||
718 | } | ||
719 | if (!HCD_HW_ACCESSIBLE(hcd)) { | 943 | if (!HCD_HW_ACCESSIBLE(hcd)) { |
720 | if (!in_interrupt()) | 944 | if (!in_interrupt()) |
721 | xhci_dbg(xhci, "urb submitted during PCI suspend\n"); | 945 | xhci_dbg(xhci, "urb submitted during PCI suspend\n"); |
@@ -956,7 +1180,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
956 | ep->stop_cmd_timer.expires = jiffies + | 1180 | ep->stop_cmd_timer.expires = jiffies + |
957 | XHCI_STOP_EP_CMD_TIMEOUT * HZ; | 1181 | XHCI_STOP_EP_CMD_TIMEOUT * HZ; |
958 | add_timer(&ep->stop_cmd_timer); | 1182 | add_timer(&ep->stop_cmd_timer); |
959 | xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index); | 1183 | xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index, 0); |
960 | xhci_ring_cmd_db(xhci); | 1184 | xhci_ring_cmd_db(xhci); |
961 | } | 1185 | } |
962 | done: | 1186 | done: |
@@ -991,7 +1215,7 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
991 | u32 new_add_flags, new_drop_flags, new_slot_info; | 1215 | u32 new_add_flags, new_drop_flags, new_slot_info; |
992 | int ret; | 1216 | int ret; |
993 | 1217 | ||
994 | ret = xhci_check_args(hcd, udev, ep, 1, __func__); | 1218 | ret = xhci_check_args(hcd, udev, ep, 1, true, __func__); |
995 | if (ret <= 0) | 1219 | if (ret <= 0) |
996 | return ret; | 1220 | return ret; |
997 | xhci = hcd_to_xhci(hcd); | 1221 | xhci = hcd_to_xhci(hcd); |
@@ -1004,12 +1228,6 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1004 | return 0; | 1228 | return 0; |
1005 | } | 1229 | } |
1006 | 1230 | ||
1007 | if (!xhci->devs || !xhci->devs[udev->slot_id]) { | ||
1008 | xhci_warn(xhci, "xHCI %s called with unaddressed device\n", | ||
1009 | __func__); | ||
1010 | return -EINVAL; | ||
1011 | } | ||
1012 | |||
1013 | in_ctx = xhci->devs[udev->slot_id]->in_ctx; | 1231 | in_ctx = xhci->devs[udev->slot_id]->in_ctx; |
1014 | out_ctx = xhci->devs[udev->slot_id]->out_ctx; | 1232 | out_ctx = xhci->devs[udev->slot_id]->out_ctx; |
1015 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | 1233 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); |
@@ -1078,7 +1296,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1078 | u32 new_add_flags, new_drop_flags, new_slot_info; | 1296 | u32 new_add_flags, new_drop_flags, new_slot_info; |
1079 | int ret = 0; | 1297 | int ret = 0; |
1080 | 1298 | ||
1081 | ret = xhci_check_args(hcd, udev, ep, 1, __func__); | 1299 | ret = xhci_check_args(hcd, udev, ep, 1, true, __func__); |
1082 | if (ret <= 0) { | 1300 | if (ret <= 0) { |
1083 | /* So we won't queue a reset ep command for a root hub */ | 1301 | /* So we won't queue a reset ep command for a root hub */ |
1084 | ep->hcpriv = NULL; | 1302 | ep->hcpriv = NULL; |
@@ -1098,12 +1316,6 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1098 | return 0; | 1316 | return 0; |
1099 | } | 1317 | } |
1100 | 1318 | ||
1101 | if (!xhci->devs || !xhci->devs[udev->slot_id]) { | ||
1102 | xhci_warn(xhci, "xHCI %s called with unaddressed device\n", | ||
1103 | __func__); | ||
1104 | return -EINVAL; | ||
1105 | } | ||
1106 | |||
1107 | in_ctx = xhci->devs[udev->slot_id]->in_ctx; | 1319 | in_ctx = xhci->devs[udev->slot_id]->in_ctx; |
1108 | out_ctx = xhci->devs[udev->slot_id]->out_ctx; | 1320 | out_ctx = xhci->devs[udev->slot_id]->out_ctx; |
1109 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | 1321 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); |
@@ -1346,16 +1558,11 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
1346 | struct xhci_input_control_ctx *ctrl_ctx; | 1558 | struct xhci_input_control_ctx *ctrl_ctx; |
1347 | struct xhci_slot_ctx *slot_ctx; | 1559 | struct xhci_slot_ctx *slot_ctx; |
1348 | 1560 | ||
1349 | ret = xhci_check_args(hcd, udev, NULL, 0, __func__); | 1561 | ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__); |
1350 | if (ret <= 0) | 1562 | if (ret <= 0) |
1351 | return ret; | 1563 | return ret; |
1352 | xhci = hcd_to_xhci(hcd); | 1564 | xhci = hcd_to_xhci(hcd); |
1353 | 1565 | ||
1354 | if (!udev->slot_id || !xhci->devs || !xhci->devs[udev->slot_id]) { | ||
1355 | xhci_warn(xhci, "xHCI %s called with unaddressed device\n", | ||
1356 | __func__); | ||
1357 | return -EINVAL; | ||
1358 | } | ||
1359 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); | 1566 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); |
1360 | virt_dev = xhci->devs[udev->slot_id]; | 1567 | virt_dev = xhci->devs[udev->slot_id]; |
1361 | 1568 | ||
@@ -1405,16 +1612,11 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) | |||
1405 | struct xhci_virt_device *virt_dev; | 1612 | struct xhci_virt_device *virt_dev; |
1406 | int i, ret; | 1613 | int i, ret; |
1407 | 1614 | ||
1408 | ret = xhci_check_args(hcd, udev, NULL, 0, __func__); | 1615 | ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__); |
1409 | if (ret <= 0) | 1616 | if (ret <= 0) |
1410 | return; | 1617 | return; |
1411 | xhci = hcd_to_xhci(hcd); | 1618 | xhci = hcd_to_xhci(hcd); |
1412 | 1619 | ||
1413 | if (!xhci->devs || !xhci->devs[udev->slot_id]) { | ||
1414 | xhci_warn(xhci, "xHCI %s called with unaddressed device\n", | ||
1415 | __func__); | ||
1416 | return; | ||
1417 | } | ||
1418 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); | 1620 | xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); |
1419 | virt_dev = xhci->devs[udev->slot_id]; | 1621 | virt_dev = xhci->devs[udev->slot_id]; |
1420 | /* Free any rings allocated for added endpoints */ | 1622 | /* Free any rings allocated for added endpoints */ |
@@ -1575,7 +1777,7 @@ static int xhci_check_streams_endpoint(struct xhci_hcd *xhci, | |||
1575 | 1777 | ||
1576 | if (!ep) | 1778 | if (!ep) |
1577 | return -EINVAL; | 1779 | return -EINVAL; |
1578 | ret = xhci_check_args(xhci_to_hcd(xhci), udev, ep, 1, __func__); | 1780 | ret = xhci_check_args(xhci_to_hcd(xhci), udev, ep, 1, true, __func__); |
1579 | if (ret <= 0) | 1781 | if (ret <= 0) |
1580 | return -EINVAL; | 1782 | return -EINVAL; |
1581 | if (ep->ss_ep_comp.bmAttributes == 0) { | 1783 | if (ep->ss_ep_comp.bmAttributes == 0) { |
@@ -1953,8 +2155,13 @@ int xhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev, | |||
1953 | * Wait for the Reset Device command to finish. Remove all structures | 2155 | * Wait for the Reset Device command to finish. Remove all structures |
1954 | * associated with the endpoints that were disabled. Clear the input device | 2156 | * associated with the endpoints that were disabled. Clear the input device |
1955 | * structure? Cache the rings? Reset the control endpoint 0 max packet size? | 2157 | * structure? Cache the rings? Reset the control endpoint 0 max packet size? |
2158 | * | ||
2159 | * If the virt_dev to be reset does not exist or does not match the udev, | ||
2160 | * it means the device is lost, possibly due to the xHC restore error and | ||
2161 | * re-initialization during S3/S4. In this case, call xhci_alloc_dev() to | ||
2162 | * re-allocate the device. | ||
1956 | */ | 2163 | */ |
1957 | int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | 2164 | int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) |
1958 | { | 2165 | { |
1959 | int ret, i; | 2166 | int ret, i; |
1960 | unsigned long flags; | 2167 | unsigned long flags; |
@@ -1965,16 +2172,35 @@ int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
1965 | int timeleft; | 2172 | int timeleft; |
1966 | int last_freed_endpoint; | 2173 | int last_freed_endpoint; |
1967 | 2174 | ||
1968 | ret = xhci_check_args(hcd, udev, NULL, 0, __func__); | 2175 | ret = xhci_check_args(hcd, udev, NULL, 0, false, __func__); |
1969 | if (ret <= 0) | 2176 | if (ret <= 0) |
1970 | return ret; | 2177 | return ret; |
1971 | xhci = hcd_to_xhci(hcd); | 2178 | xhci = hcd_to_xhci(hcd); |
1972 | slot_id = udev->slot_id; | 2179 | slot_id = udev->slot_id; |
1973 | virt_dev = xhci->devs[slot_id]; | 2180 | virt_dev = xhci->devs[slot_id]; |
1974 | if (!virt_dev) { | 2181 | if (!virt_dev) { |
1975 | xhci_dbg(xhci, "%s called with invalid slot ID %u\n", | 2182 | xhci_dbg(xhci, "The device to be reset with slot ID %u does " |
1976 | __func__, slot_id); | 2183 | "not exist. Re-allocate the device\n", slot_id); |
1977 | return -EINVAL; | 2184 | ret = xhci_alloc_dev(hcd, udev); |
2185 | if (ret == 1) | ||
2186 | return 0; | ||
2187 | else | ||
2188 | return -EINVAL; | ||
2189 | } | ||
2190 | |||
2191 | if (virt_dev->udev != udev) { | ||
2192 | /* If the virt_dev and the udev does not match, this virt_dev | ||
2193 | * may belong to another udev. | ||
2194 | * Re-allocate the device. | ||
2195 | */ | ||
2196 | xhci_dbg(xhci, "The device to be reset with slot ID %u does " | ||
2197 | "not match the udev. Re-allocate the device\n", | ||
2198 | slot_id); | ||
2199 | ret = xhci_alloc_dev(hcd, udev); | ||
2200 | if (ret == 1) | ||
2201 | return 0; | ||
2202 | else | ||
2203 | return -EINVAL; | ||
1978 | } | 2204 | } |
1979 | 2205 | ||
1980 | xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); | 2206 | xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); |
@@ -2077,13 +2303,13 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
2077 | struct xhci_virt_device *virt_dev; | 2303 | struct xhci_virt_device *virt_dev; |
2078 | unsigned long flags; | 2304 | unsigned long flags; |
2079 | u32 state; | 2305 | u32 state; |
2080 | int i; | 2306 | int i, ret; |
2081 | 2307 | ||
2082 | if (udev->slot_id == 0) | 2308 | ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__); |
2309 | if (ret <= 0) | ||
2083 | return; | 2310 | return; |
2311 | |||
2084 | virt_dev = xhci->devs[udev->slot_id]; | 2312 | virt_dev = xhci->devs[udev->slot_id]; |
2085 | if (!virt_dev) | ||
2086 | return; | ||
2087 | 2313 | ||
2088 | /* Stop any wayward timer functions (which may grab the lock) */ | 2314 | /* Stop any wayward timer functions (which may grab the lock) */ |
2089 | for (i = 0; i < 31; ++i) { | 2315 | for (i = 0; i < 31; ++i) { |
@@ -2191,12 +2417,17 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
2191 | 2417 | ||
2192 | virt_dev = xhci->devs[udev->slot_id]; | 2418 | virt_dev = xhci->devs[udev->slot_id]; |
2193 | 2419 | ||
2194 | /* If this is a Set Address to an unconfigured device, setup ep 0 */ | 2420 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); |
2195 | if (!udev->config) | 2421 | /* |
2422 | * If this is the first Set Address since device plug-in or | ||
2423 | * virt_device realloaction after a resume with an xHCI power loss, | ||
2424 | * then set up the slot context. | ||
2425 | */ | ||
2426 | if (!slot_ctx->dev_info) | ||
2196 | xhci_setup_addressable_virt_dev(xhci, udev); | 2427 | xhci_setup_addressable_virt_dev(xhci, udev); |
2428 | /* Otherwise, update the control endpoint ring enqueue pointer. */ | ||
2197 | else | 2429 | else |
2198 | xhci_copy_ep0_dequeue_into_input_ctx(xhci, udev); | 2430 | xhci_copy_ep0_dequeue_into_input_ctx(xhci, udev); |
2199 | /* Otherwise, assume the core has the device configured how it wants */ | ||
2200 | xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); | 2431 | xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); |
2201 | xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); | 2432 | xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); |
2202 | 2433 | ||
@@ -2268,15 +2499,15 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
2268 | * address given back to us by the HC. | 2499 | * address given back to us by the HC. |
2269 | */ | 2500 | */ |
2270 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); | 2501 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); |
2271 | udev->devnum = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1; | 2502 | /* Use kernel assigned address for devices; store xHC assigned |
2503 | * address locally. */ | ||
2504 | virt_dev->address = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1; | ||
2272 | /* Zero the input context control for later use */ | 2505 | /* Zero the input context control for later use */ |
2273 | ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); | 2506 | ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); |
2274 | ctrl_ctx->add_flags = 0; | 2507 | ctrl_ctx->add_flags = 0; |
2275 | ctrl_ctx->drop_flags = 0; | 2508 | ctrl_ctx->drop_flags = 0; |
2276 | 2509 | ||
2277 | xhci_dbg(xhci, "Device address = %d\n", udev->devnum); | 2510 | xhci_dbg(xhci, "Internal device address = %d\n", virt_dev->address); |
2278 | /* XXX Meh, not sure if anyone else but choose_address uses this. */ | ||
2279 | set_bit(udev->devnum, udev->bus->devmap.devicemap); | ||
2280 | 2511 | ||
2281 | return 0; | 2512 | return 0; |
2282 | } | 2513 | } |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 34a60d9f056a..93d3bf4d213c 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -191,7 +191,7 @@ struct xhci_op_regs { | |||
191 | /* bits 4:6 are reserved (and should be preserved on writes). */ | 191 | /* bits 4:6 are reserved (and should be preserved on writes). */ |
192 | /* light reset (port status stays unchanged) - reset completed when this is 0 */ | 192 | /* light reset (port status stays unchanged) - reset completed when this is 0 */ |
193 | #define CMD_LRESET (1 << 7) | 193 | #define CMD_LRESET (1 << 7) |
194 | /* FIXME: ignoring host controller save/restore state for now. */ | 194 | /* host controller save/restore state. */ |
195 | #define CMD_CSS (1 << 8) | 195 | #define CMD_CSS (1 << 8) |
196 | #define CMD_CRS (1 << 9) | 196 | #define CMD_CRS (1 << 9) |
197 | /* Enable Wrap Event - '1' means xHC generates an event when MFINDEX wraps. */ | 197 | /* Enable Wrap Event - '1' means xHC generates an event when MFINDEX wraps. */ |
@@ -269,6 +269,10 @@ struct xhci_op_regs { | |||
269 | * A read gives the current link PM state of the port, | 269 | * A read gives the current link PM state of the port, |
270 | * a write with Link State Write Strobe set sets the link state. | 270 | * a write with Link State Write Strobe set sets the link state. |
271 | */ | 271 | */ |
272 | #define PORT_PLS_MASK (0xf << 5) | ||
273 | #define XDEV_U0 (0x0 << 5) | ||
274 | #define XDEV_U3 (0x3 << 5) | ||
275 | #define XDEV_RESUME (0xf << 5) | ||
272 | /* true: port has power (see HCC_PPC) */ | 276 | /* true: port has power (see HCC_PPC) */ |
273 | #define PORT_POWER (1 << 9) | 277 | #define PORT_POWER (1 << 9) |
274 | /* bits 10:13 indicate device speed: | 278 | /* bits 10:13 indicate device speed: |
@@ -353,6 +357,8 @@ struct xhci_op_regs { | |||
353 | #define PORT_U2_TIMEOUT(p) (((p) & 0xff) << 8) | 357 | #define PORT_U2_TIMEOUT(p) (((p) & 0xff) << 8) |
354 | /* Bits 24:31 for port testing */ | 358 | /* Bits 24:31 for port testing */ |
355 | 359 | ||
360 | /* USB2 Protocol PORTSPMSC */ | ||
361 | #define PORT_RWE (1 << 0x3) | ||
356 | 362 | ||
357 | /** | 363 | /** |
358 | * struct xhci_intr_reg - Interrupt Register Set | 364 | * struct xhci_intr_reg - Interrupt Register Set |
@@ -510,6 +516,7 @@ struct xhci_slot_ctx { | |||
510 | #define MAX_EXIT (0xffff) | 516 | #define MAX_EXIT (0xffff) |
511 | /* Root hub port number that is needed to access the USB device */ | 517 | /* Root hub port number that is needed to access the USB device */ |
512 | #define ROOT_HUB_PORT(p) (((p) & 0xff) << 16) | 518 | #define ROOT_HUB_PORT(p) (((p) & 0xff) << 16) |
519 | #define DEVINFO_TO_ROOT_HUB_PORT(p) (((p) >> 16) & 0xff) | ||
513 | /* Maximum number of ports under a hub device */ | 520 | /* Maximum number of ports under a hub device */ |
514 | #define XHCI_MAX_PORTS(p) (((p) & 0xff) << 24) | 521 | #define XHCI_MAX_PORTS(p) (((p) & 0xff) << 24) |
515 | 522 | ||
@@ -731,6 +738,7 @@ struct xhci_virt_ep { | |||
731 | }; | 738 | }; |
732 | 739 | ||
733 | struct xhci_virt_device { | 740 | struct xhci_virt_device { |
741 | struct usb_device *udev; | ||
734 | /* | 742 | /* |
735 | * Commands to the hardware are passed an "input context" that | 743 | * Commands to the hardware are passed an "input context" that |
736 | * tells the hardware what to change in its data structures. | 744 | * tells the hardware what to change in its data structures. |
@@ -745,12 +753,15 @@ struct xhci_virt_device { | |||
745 | /* Rings saved to ensure old alt settings can be re-instated */ | 753 | /* Rings saved to ensure old alt settings can be re-instated */ |
746 | struct xhci_ring **ring_cache; | 754 | struct xhci_ring **ring_cache; |
747 | int num_rings_cached; | 755 | int num_rings_cached; |
756 | /* Store xHC assigned device address */ | ||
757 | int address; | ||
748 | #define XHCI_MAX_RINGS_CACHED 31 | 758 | #define XHCI_MAX_RINGS_CACHED 31 |
749 | struct xhci_virt_ep eps[31]; | 759 | struct xhci_virt_ep eps[31]; |
750 | struct completion cmd_completion; | 760 | struct completion cmd_completion; |
751 | /* Status of the last command issued for this device */ | 761 | /* Status of the last command issued for this device */ |
752 | u32 cmd_status; | 762 | u32 cmd_status; |
753 | struct list_head cmd_list; | 763 | struct list_head cmd_list; |
764 | u8 port; | ||
754 | }; | 765 | }; |
755 | 766 | ||
756 | 767 | ||
@@ -881,6 +892,10 @@ struct xhci_event_cmd { | |||
881 | #define TRB_TO_EP_INDEX(p) ((((p) & (0x1f << 16)) >> 16) - 1) | 892 | #define TRB_TO_EP_INDEX(p) ((((p) & (0x1f << 16)) >> 16) - 1) |
882 | #define EP_ID_FOR_TRB(p) ((((p) + 1) & 0x1f) << 16) | 893 | #define EP_ID_FOR_TRB(p) ((((p) + 1) & 0x1f) << 16) |
883 | 894 | ||
895 | #define SUSPEND_PORT_FOR_TRB(p) (((p) & 1) << 23) | ||
896 | #define TRB_TO_SUSPEND_PORT(p) (((p) & (1 << 23)) >> 23) | ||
897 | #define LAST_EP_INDEX 30 | ||
898 | |||
884 | /* Set TR Dequeue Pointer command TRB fields */ | 899 | /* Set TR Dequeue Pointer command TRB fields */ |
885 | #define TRB_TO_STREAM_ID(p) ((((p) & (0xffff << 16)) >> 16)) | 900 | #define TRB_TO_STREAM_ID(p) ((((p) & (0xffff << 16)) >> 16)) |
886 | #define STREAM_ID_FOR_TRB(p) ((((p)) & 0xffff) << 16) | 901 | #define STREAM_ID_FOR_TRB(p) ((((p)) & 0xffff) << 16) |
@@ -1115,6 +1130,17 @@ struct urb_priv { | |||
1115 | #define XHCI_STOP_EP_CMD_TIMEOUT 5 | 1130 | #define XHCI_STOP_EP_CMD_TIMEOUT 5 |
1116 | /* XXX: Make these module parameters */ | 1131 | /* XXX: Make these module parameters */ |
1117 | 1132 | ||
1133 | struct s3_save { | ||
1134 | u32 command; | ||
1135 | u32 dev_nt; | ||
1136 | u64 dcbaa_ptr; | ||
1137 | u32 config_reg; | ||
1138 | u32 irq_pending; | ||
1139 | u32 irq_control; | ||
1140 | u32 erst_size; | ||
1141 | u64 erst_base; | ||
1142 | u64 erst_dequeue; | ||
1143 | }; | ||
1118 | 1144 | ||
1119 | /* There is one ehci_hci structure per controller */ | 1145 | /* There is one ehci_hci structure per controller */ |
1120 | struct xhci_hcd { | 1146 | struct xhci_hcd { |
@@ -1178,6 +1204,12 @@ struct xhci_hcd { | |||
1178 | #endif | 1204 | #endif |
1179 | /* Host controller watchdog timer structures */ | 1205 | /* Host controller watchdog timer structures */ |
1180 | unsigned int xhc_state; | 1206 | unsigned int xhc_state; |
1207 | |||
1208 | unsigned long bus_suspended; | ||
1209 | unsigned long next_statechange; | ||
1210 | |||
1211 | u32 command; | ||
1212 | struct s3_save s3; | ||
1181 | /* Host controller is dying - not responding to commands. "I'm not dead yet!" | 1213 | /* Host controller is dying - not responding to commands. "I'm not dead yet!" |
1182 | * | 1214 | * |
1183 | * xHC interrupts have been disabled and a watchdog timer will (or has already) | 1215 | * xHC interrupts have been disabled and a watchdog timer will (or has already) |
@@ -1199,6 +1231,10 @@ struct xhci_hcd { | |||
1199 | #define XHCI_LINK_TRB_QUIRK (1 << 0) | 1231 | #define XHCI_LINK_TRB_QUIRK (1 << 0) |
1200 | #define XHCI_RESET_EP_QUIRK (1 << 1) | 1232 | #define XHCI_RESET_EP_QUIRK (1 << 1) |
1201 | #define XHCI_NEC_HOST (1 << 2) | 1233 | #define XHCI_NEC_HOST (1 << 2) |
1234 | u32 port_c_suspend[8]; /* port suspend change*/ | ||
1235 | u32 suspended_ports[8]; /* which ports are | ||
1236 | suspended */ | ||
1237 | unsigned long resume_done[MAX_HC_PORTS]; | ||
1202 | }; | 1238 | }; |
1203 | 1239 | ||
1204 | /* For testing purposes */ | 1240 | /* For testing purposes */ |
@@ -1369,6 +1405,15 @@ int xhci_init(struct usb_hcd *hcd); | |||
1369 | int xhci_run(struct usb_hcd *hcd); | 1405 | int xhci_run(struct usb_hcd *hcd); |
1370 | void xhci_stop(struct usb_hcd *hcd); | 1406 | void xhci_stop(struct usb_hcd *hcd); |
1371 | void xhci_shutdown(struct usb_hcd *hcd); | 1407 | void xhci_shutdown(struct usb_hcd *hcd); |
1408 | |||
1409 | #ifdef CONFIG_PM | ||
1410 | int xhci_suspend(struct xhci_hcd *xhci); | ||
1411 | int xhci_resume(struct xhci_hcd *xhci, bool hibernated); | ||
1412 | #else | ||
1413 | #define xhci_suspend NULL | ||
1414 | #define xhci_resume NULL | ||
1415 | #endif | ||
1416 | |||
1372 | int xhci_get_frame(struct usb_hcd *hcd); | 1417 | int xhci_get_frame(struct usb_hcd *hcd); |
1373 | irqreturn_t xhci_irq(struct usb_hcd *hcd); | 1418 | irqreturn_t xhci_irq(struct usb_hcd *hcd); |
1374 | irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd); | 1419 | irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd); |
@@ -1388,7 +1433,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status); | |||
1388 | int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); | 1433 | int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); |
1389 | int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); | 1434 | int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); |
1390 | void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep); | 1435 | void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep); |
1391 | int xhci_reset_device(struct usb_hcd *hcd, struct usb_device *udev); | 1436 | int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev); |
1392 | int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); | 1437 | int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); |
1393 | void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); | 1438 | void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); |
1394 | 1439 | ||
@@ -1406,7 +1451,7 @@ int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, | |||
1406 | int xhci_queue_vendor_command(struct xhci_hcd *xhci, | 1451 | int xhci_queue_vendor_command(struct xhci_hcd *xhci, |
1407 | u32 field1, u32 field2, u32 field3, u32 field4); | 1452 | u32 field1, u32 field2, u32 field3, u32 field4); |
1408 | int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, | 1453 | int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, |
1409 | unsigned int ep_index); | 1454 | unsigned int ep_index, int suspend); |
1410 | int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, | 1455 | int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, |
1411 | int slot_id, unsigned int ep_index); | 1456 | int slot_id, unsigned int ep_index); |
1412 | int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, | 1457 | int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, |
@@ -1436,12 +1481,26 @@ void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci, | |||
1436 | unsigned int slot_id, unsigned int ep_index, | 1481 | unsigned int slot_id, unsigned int ep_index, |
1437 | struct xhci_dequeue_state *deq_state); | 1482 | struct xhci_dequeue_state *deq_state); |
1438 | void xhci_stop_endpoint_command_watchdog(unsigned long arg); | 1483 | void xhci_stop_endpoint_command_watchdog(unsigned long arg); |
1484 | void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, | ||
1485 | unsigned int ep_index, unsigned int stream_id); | ||
1439 | 1486 | ||
1440 | /* xHCI roothub code */ | 1487 | /* xHCI roothub code */ |
1441 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, | 1488 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, |
1442 | char *buf, u16 wLength); | 1489 | char *buf, u16 wLength); |
1443 | int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); | 1490 | int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); |
1444 | 1491 | ||
1492 | #ifdef CONFIG_PM | ||
1493 | int xhci_bus_suspend(struct usb_hcd *hcd); | ||
1494 | int xhci_bus_resume(struct usb_hcd *hcd); | ||
1495 | #else | ||
1496 | #define xhci_bus_suspend NULL | ||
1497 | #define xhci_bus_resume NULL | ||
1498 | #endif /* CONFIG_PM */ | ||
1499 | |||
1500 | u32 xhci_port_state_to_neutral(u32 state); | ||
1501 | int xhci_find_slot_id_by_port(struct xhci_hcd *xhci, u16 port); | ||
1502 | void xhci_ring_device(struct xhci_hcd *xhci, int slot_id); | ||
1503 | |||
1445 | /* xHCI contexts */ | 1504 | /* xHCI contexts */ |
1446 | struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); | 1505 | struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); |
1447 | struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); | 1506 | struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); |