aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-22 18:25:26 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-22 18:25:26 -0400
commit09091a4d5f2dd378dcf71de50b48cdacc58a8ac0 (patch)
treed50e37ebb5591fa1e723f32bde077dbdf726b78b /drivers/usb/host
parent66f75a5d028beaf67c931435fdc3e7823125730c (diff)
parent3a1c2a82204f5376f484d82cb18189afc2145c77 (diff)
Merge 3.4-rc4 into usb-next.
This resolves the conflict in: drivers/usb/host/ehci-fsl.c And picks up loads of xhci bugfixes to make it easier for others to test with. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/Kconfig36
-rw-r--r--drivers/usb/host/Makefile2
-rw-r--r--drivers/usb/host/bcma-hcd.c334
-rw-r--r--drivers/usb/host/ehci-fsl.c36
-rw-r--r--drivers/usb/host/ehci-fsl.h13
-rw-r--r--drivers/usb/host/ehci-hcd.c13
-rw-r--r--drivers/usb/host/ehci-hub.c20
-rw-r--r--drivers/usb/host/ehci-platform.c4
-rw-r--r--drivers/usb/host/ehci-s5p.c4
-rw-r--r--drivers/usb/host/ehci-sead3.c266
-rw-r--r--drivers/usb/host/ehci-sh.c8
-rw-r--r--drivers/usb/host/ehci-spear.c36
-rw-r--r--drivers/usb/host/ehci-tegra.c67
-rw-r--r--drivers/usb/host/fhci-tds.c2
-rw-r--r--drivers/usb/host/fsl-mph-dr-of.c41
-rw-r--r--drivers/usb/host/isp1760-hcd.c9
-rw-r--r--drivers/usb/host/isp1760-if.c8
-rw-r--r--drivers/usb/host/ohci-hcd.c21
-rw-r--r--drivers/usb/host/ohci-platform.c4
-rw-r--r--drivers/usb/host/ohci-ppc-of.c2
-rw-r--r--drivers/usb/host/ohci-spear.c36
-rw-r--r--drivers/usb/host/ohci-ssb.c260
-rw-r--r--drivers/usb/host/oxu210hp-hcd.c5
-rw-r--r--drivers/usb/host/ssb-hcd.c279
24 files changed, 1127 insertions, 379 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index f788eb86707..896fc91c54a 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -110,13 +110,14 @@ config USB_EHCI_BIG_ENDIAN_MMIO
110 depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || \ 110 depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || \
111 ARCH_IXP4XX || XPS_USB_HCD_XILINX || \ 111 ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
112 PPC_MPC512x || CPU_CAVIUM_OCTEON || \ 112 PPC_MPC512x || CPU_CAVIUM_OCTEON || \
113 PMC_MSP || SPARC_LEON) 113 PMC_MSP || SPARC_LEON || MIPS_SEAD3)
114 default y 114 default y
115 115
116config USB_EHCI_BIG_ENDIAN_DESC 116config USB_EHCI_BIG_ENDIAN_DESC
117 bool 117 bool
118 depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX || \ 118 depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
119 PPC_MPC512x || PMC_MSP || SPARC_LEON) 119 PPC_MPC512x || PMC_MSP || SPARC_LEON || \
120 MIPS_SEAD3)
120 default y 121 default y
121 122
122config XPS_USB_HCD_XILINX 123config XPS_USB_HCD_XILINX
@@ -373,10 +374,15 @@ config USB_OHCI_HCD_PCI
373 If unsure, say Y. 374 If unsure, say Y.
374 375
375config USB_OHCI_HCD_SSB 376config USB_OHCI_HCD_SSB
376 bool "OHCI support for Broadcom SSB OHCI core" 377 bool "OHCI support for Broadcom SSB OHCI core (DEPRECATED)"
377 depends on USB_OHCI_HCD && (SSB = y || SSB = USB_OHCI_HCD) && EXPERIMENTAL 378 depends on USB_OHCI_HCD && (SSB = y || SSB = USB_OHCI_HCD) && EXPERIMENTAL
379 select USB_HCD_SSB
380 select USB_OHCI_HCD_PLATFORM
378 default n 381 default n
379 ---help--- 382 ---help---
383 This option is deprecated now and the driver was removed, use
384 USB_HCD_SSB and USB_OHCI_HCD_PLATFORM instead.
385
380 Support for the Sonics Silicon Backplane (SSB) attached 386 Support for the Sonics Silicon Backplane (SSB) attached
381 Broadcom USB OHCI core. 387 Broadcom USB OHCI core.
382 388
@@ -638,3 +644,27 @@ config USB_OCTEON_OHCI
638config USB_OCTEON2_COMMON 644config USB_OCTEON2_COMMON
639 bool 645 bool
640 default y if USB_OCTEON_EHCI || USB_OCTEON_OHCI 646 default y if USB_OCTEON_EHCI || USB_OCTEON_OHCI
647
648config USB_HCD_BCMA
649 tristate "BCMA usb host driver"
650 depends on BCMA && EXPERIMENTAL
651 select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
652 select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
653 help
654 Enbale support for the EHCI and OCHI host controller on an bcma bus.
655 It converts the bcma driver into two platform device drivers
656 for ehci and ohci.
657
658 If unsure, say N.
659
660config USB_HCD_SSB
661 tristate "SSB usb host driver"
662 depends on SSB && EXPERIMENTAL
663 select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
664 select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
665 help
666 Enbale support for the EHCI and OCHI host controller on an bcma bus.
667 It converts the bcma driver into two platform device drivers
668 for ehci and ohci.
669
670 If unsure, say N.
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 0982bcc140b..9e0a89ced15 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -41,3 +41,5 @@ obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o
41obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o 41obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o
42obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o 42obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o
43obj-$(CONFIG_MIPS_ALCHEMY) += alchemy-common.o 43obj-$(CONFIG_MIPS_ALCHEMY) += alchemy-common.o
44obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o
45obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o
diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
new file mode 100644
index 00000000000..0b35d422fa4
--- /dev/null
+++ b/drivers/usb/host/bcma-hcd.c
@@ -0,0 +1,334 @@
1/*
2 * Broadcom specific Advanced Microcontroller Bus
3 * Broadcom USB-core driver (BCMA bus glue)
4 *
5 * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
6 *
7 * Based on ssb-ohci driver
8 * Copyright 2007 Michael Buesch <m@bues.ch>
9 *
10 * Derived from the OHCI-PCI driver
11 * Copyright 1999 Roman Weissgaerber
12 * Copyright 2000-2002 David Brownell
13 * Copyright 1999 Linus Torvalds
14 * Copyright 1999 Gregory P. Smith
15 *
16 * Derived from the USBcore related parts of Broadcom-SB
17 * Copyright 2005-2011 Broadcom Corporation
18 *
19 * Licensed under the GNU/GPL. See COPYING for details.
20 */
21#include <linux/bcma/bcma.h>
22#include <linux/delay.h>
23#include <linux/platform_device.h>
24#include <linux/module.h>
25#include <linux/usb/ehci_pdriver.h>
26#include <linux/usb/ohci_pdriver.h>
27
28MODULE_AUTHOR("Hauke Mehrtens");
29MODULE_DESCRIPTION("Common USB driver for BCMA Bus");
30MODULE_LICENSE("GPL");
31
32struct bcma_hcd_device {
33 struct platform_device *ehci_dev;
34 struct platform_device *ohci_dev;
35};
36
37/* Wait for bitmask in a register to get set or cleared.
38 * timeout is in units of ten-microseconds.
39 */
40static int bcma_wait_bits(struct bcma_device *dev, u16 reg, u32 bitmask,
41 int timeout)
42{
43 int i;
44 u32 val;
45
46 for (i = 0; i < timeout; i++) {
47 val = bcma_read32(dev, reg);
48 if ((val & bitmask) == bitmask)
49 return 0;
50 udelay(10);
51 }
52
53 return -ETIMEDOUT;
54}
55
56static void __devinit bcma_hcd_4716wa(struct bcma_device *dev)
57{
58#ifdef CONFIG_BCMA_DRIVER_MIPS
59 /* Work around for 4716 failures. */
60 if (dev->bus->chipinfo.id == 0x4716) {
61 u32 tmp;
62
63 tmp = bcma_cpu_clock(&dev->bus->drv_mips);
64 if (tmp >= 480000000)
65 tmp = 0x1846b; /* set CDR to 0x11(fast) */
66 else if (tmp == 453000000)
67 tmp = 0x1046b; /* set CDR to 0x10(slow) */
68 else
69 tmp = 0;
70
71 /* Change Shim mdio control reg to fix host not acking at
72 * high frequencies
73 */
74 if (tmp) {
75 bcma_write32(dev, 0x524, 0x1); /* write sel to enable */
76 udelay(500);
77
78 bcma_write32(dev, 0x524, tmp);
79 udelay(500);
80 bcma_write32(dev, 0x524, 0x4ab);
81 udelay(500);
82 bcma_read32(dev, 0x528);
83 bcma_write32(dev, 0x528, 0x80000000);
84 }
85 }
86#endif /* CONFIG_BCMA_DRIVER_MIPS */
87}
88
89/* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
90static void __devinit bcma_hcd_init_chip(struct bcma_device *dev)
91{
92 u32 tmp;
93
94 /*
95 * USB 2.0 special considerations:
96 *
97 * 1. Since the core supports both OHCI and EHCI functions, it must
98 * only be reset once.
99 *
100 * 2. In addition to the standard SI reset sequence, the Host Control
101 * Register must be programmed to bring the USB core and various
102 * phy components out of reset.
103 */
104 if (!bcma_core_is_enabled(dev)) {
105 bcma_core_enable(dev, 0);
106 mdelay(10);
107 if (dev->id.rev >= 5) {
108 /* Enable Misc PLL */
109 tmp = bcma_read32(dev, 0x1e0);
110 tmp |= 0x100;
111 bcma_write32(dev, 0x1e0, tmp);
112 if (bcma_wait_bits(dev, 0x1e0, 1 << 24, 100))
113 printk(KERN_EMERG "Failed to enable misc PPL!\n");
114
115 /* Take out of resets */
116 bcma_write32(dev, 0x200, 0x4ff);
117 udelay(25);
118 bcma_write32(dev, 0x200, 0x6ff);
119 udelay(25);
120
121 /* Make sure digital and AFE are locked in USB PHY */
122 bcma_write32(dev, 0x524, 0x6b);
123 udelay(50);
124 tmp = bcma_read32(dev, 0x524);
125 udelay(50);
126 bcma_write32(dev, 0x524, 0xab);
127 udelay(50);
128 tmp = bcma_read32(dev, 0x524);
129 udelay(50);
130 bcma_write32(dev, 0x524, 0x2b);
131 udelay(50);
132 tmp = bcma_read32(dev, 0x524);
133 udelay(50);
134 bcma_write32(dev, 0x524, 0x10ab);
135 udelay(50);
136 tmp = bcma_read32(dev, 0x524);
137
138 if (bcma_wait_bits(dev, 0x528, 0xc000, 10000)) {
139 tmp = bcma_read32(dev, 0x528);
140 printk(KERN_EMERG
141 "USB20H mdio_rddata 0x%08x\n", tmp);
142 }
143 bcma_write32(dev, 0x528, 0x80000000);
144 tmp = bcma_read32(dev, 0x314);
145 udelay(265);
146 bcma_write32(dev, 0x200, 0x7ff);
147 udelay(10);
148
149 /* Take USB and HSIC out of non-driving modes */
150 bcma_write32(dev, 0x510, 0);
151 } else {
152 bcma_write32(dev, 0x200, 0x7ff);
153
154 udelay(1);
155 }
156
157 bcma_hcd_4716wa(dev);
158 }
159}
160
161static const struct usb_ehci_pdata ehci_pdata = {
162};
163
164static const struct usb_ohci_pdata ohci_pdata = {
165};
166
167static struct platform_device * __devinit
168bcma_hcd_create_pdev(struct bcma_device *dev, bool ohci, u32 addr)
169{
170 struct platform_device *hci_dev;
171 struct resource hci_res[2];
172 int ret = -ENOMEM;
173
174 memset(hci_res, 0, sizeof(hci_res));
175
176 hci_res[0].start = addr;
177 hci_res[0].end = hci_res[0].start + 0x1000 - 1;
178 hci_res[0].flags = IORESOURCE_MEM;
179
180 hci_res[1].start = dev->irq;
181 hci_res[1].flags = IORESOURCE_IRQ;
182
183 hci_dev = platform_device_alloc(ohci ? "ohci-platform" :
184 "ehci-platform" , 0);
185 if (!hci_dev)
186 return NULL;
187
188 hci_dev->dev.parent = &dev->dev;
189 hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask;
190
191 ret = platform_device_add_resources(hci_dev, hci_res,
192 ARRAY_SIZE(hci_res));
193 if (ret)
194 goto err_alloc;
195 if (ohci)
196 ret = platform_device_add_data(hci_dev, &ohci_pdata,
197 sizeof(ohci_pdata));
198 else
199 ret = platform_device_add_data(hci_dev, &ehci_pdata,
200 sizeof(ehci_pdata));
201 if (ret)
202 goto err_alloc;
203 ret = platform_device_add(hci_dev);
204 if (ret)
205 goto err_alloc;
206
207 return hci_dev;
208
209err_alloc:
210 platform_device_put(hci_dev);
211 return ERR_PTR(ret);
212}
213
214static int __devinit bcma_hcd_probe(struct bcma_device *dev)
215{
216 int err;
217 u16 chipid_top;
218 u32 ohci_addr;
219 struct bcma_hcd_device *usb_dev;
220 struct bcma_chipinfo *chipinfo;
221
222 chipinfo = &dev->bus->chipinfo;
223 /* USBcores are only connected on embedded devices. */
224 chipid_top = (chipinfo->id & 0xFF00);
225 if (chipid_top != 0x4700 && chipid_top != 0x5300)
226 return -ENODEV;
227
228 /* TODO: Probably need checks here; is the core connected? */
229
230 if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) ||
231 dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32)))
232 return -EOPNOTSUPP;
233
234 usb_dev = kzalloc(sizeof(struct bcma_hcd_device), GFP_KERNEL);
235 if (!usb_dev)
236 return -ENOMEM;
237
238 bcma_hcd_init_chip(dev);
239
240 /* In AI chips EHCI is addrspace 0, OHCI is 1 */
241 ohci_addr = dev->addr1;
242 if ((chipinfo->id == 0x5357 || chipinfo->id == 0x4749)
243 && chipinfo->rev == 0)
244 ohci_addr = 0x18009000;
245
246 usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, true, ohci_addr);
247 if (IS_ERR(usb_dev->ohci_dev)) {
248 err = PTR_ERR(usb_dev->ohci_dev);
249 goto err_free_usb_dev;
250 }
251
252 usb_dev->ehci_dev = bcma_hcd_create_pdev(dev, false, dev->addr);
253 if (IS_ERR(usb_dev->ehci_dev)) {
254 err = PTR_ERR(usb_dev->ehci_dev);
255 goto err_unregister_ohci_dev;
256 }
257
258 bcma_set_drvdata(dev, usb_dev);
259 return 0;
260
261err_unregister_ohci_dev:
262 platform_device_unregister(usb_dev->ohci_dev);
263err_free_usb_dev:
264 kfree(usb_dev);
265 return err;
266}
267
268static void __devexit bcma_hcd_remove(struct bcma_device *dev)
269{
270 struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
271 struct platform_device *ohci_dev = usb_dev->ohci_dev;
272 struct platform_device *ehci_dev = usb_dev->ehci_dev;
273
274 if (ohci_dev)
275 platform_device_unregister(ohci_dev);
276 if (ehci_dev)
277 platform_device_unregister(ehci_dev);
278
279 bcma_core_disable(dev, 0);
280}
281
282static void bcma_hcd_shutdown(struct bcma_device *dev)
283{
284 bcma_core_disable(dev, 0);
285}
286
287#ifdef CONFIG_PM
288
289static int bcma_hcd_suspend(struct bcma_device *dev)
290{
291 bcma_core_disable(dev, 0);
292
293 return 0;
294}
295
296static int bcma_hcd_resume(struct bcma_device *dev)
297{
298 bcma_core_enable(dev, 0);
299
300 return 0;
301}
302
303#else /* !CONFIG_PM */
304#define bcma_hcd_suspend NULL
305#define bcma_hcd_resume NULL
306#endif /* CONFIG_PM */
307
308static const struct bcma_device_id bcma_hcd_table[] __devinitconst = {
309 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS),
310 BCMA_CORETABLE_END
311};
312MODULE_DEVICE_TABLE(bcma, bcma_hcd_table);
313
314static struct bcma_driver bcma_hcd_driver = {
315 .name = KBUILD_MODNAME,
316 .id_table = bcma_hcd_table,
317 .probe = bcma_hcd_probe,
318 .remove = __devexit_p(bcma_hcd_remove),
319 .shutdown = bcma_hcd_shutdown,
320 .suspend = bcma_hcd_suspend,
321 .resume = bcma_hcd_resume,
322};
323
324static int __init bcma_hcd_init(void)
325{
326 return bcma_driver_register(&bcma_hcd_driver);
327}
328module_init(bcma_hcd_init);
329
330static void __exit bcma_hcd_exit(void)
331{
332 bcma_driver_unregister(&bcma_hcd_driver);
333}
334module_exit(bcma_hcd_exit);
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index d0a84bd3f3e..34acfcee740 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright 2005-2009 MontaVista Software, Inc. 2 * Copyright 2005-2009 MontaVista Software, Inc.
3 * Copyright 2008 Freescale Semiconductor, Inc. 3 * Copyright 2008,2012 Freescale Semiconductor, Inc.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the 6 * under the terms of the GNU General Public License as published by the
@@ -211,22 +211,32 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd,
211 usb_put_hcd(hcd); 211 usb_put_hcd(hcd);
212} 212}
213 213
214static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, 214static void ehci_fsl_setup_phy(struct usb_hcd *hcd,
215 enum fsl_usb2_phy_modes phy_mode, 215 enum fsl_usb2_phy_modes phy_mode,
216 unsigned int port_offset) 216 unsigned int port_offset)
217{ 217{
218 u32 portsc; 218 u32 portsc, temp;
219 struct usb_hcd *hcd = ehci_to_hcd(ehci); 219 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
220 void __iomem *non_ehci = hcd->regs; 220 void __iomem *non_ehci = hcd->regs;
221 struct fsl_usb2_platform_data *pdata; 221 struct device *dev = hcd->self.controller;
222 struct fsl_usb2_platform_data *pdata = dev->platform_data;
222 223
223 pdata = hcd->self.controller->platform_data; 224 if (pdata->controller_ver < 0) {
225 dev_warn(hcd->self.controller, "Could not get controller version\n");
226 return;
227 }
224 228
225 portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); 229 portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
226 portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); 230 portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
227 231
228 switch (phy_mode) { 232 switch (phy_mode) {
229 case FSL_USB2_PHY_ULPI: 233 case FSL_USB2_PHY_ULPI:
234 if (pdata->controller_ver) {
235 /* controller version 1.6 or above */
236 temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
237 out_be32(non_ehci + FSL_SOC_USB_CTRL, temp |
238 USB_CTRL_USB_EN | ULPI_PHY_CLK_SEL);
239 }
230 portsc |= PORT_PTS_ULPI; 240 portsc |= PORT_PTS_ULPI;
231 break; 241 break;
232 case FSL_USB2_PHY_SERIAL: 242 case FSL_USB2_PHY_SERIAL:
@@ -236,6 +246,14 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
236 portsc |= PORT_PTS_PTW; 246 portsc |= PORT_PTS_PTW;
237 /* fall through */ 247 /* fall through */
238 case FSL_USB2_PHY_UTMI: 248 case FSL_USB2_PHY_UTMI:
249 if (pdata->controller_ver) {
250 /* controller version 1.6 or above */
251 temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
252 out_be32(non_ehci + FSL_SOC_USB_CTRL, temp |
253 UTMI_PHY_EN | USB_CTRL_USB_EN);
254 mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI PHY CLK to
255 become stable - 10ms*/
256 }
239 /* enable UTMI PHY */ 257 /* enable UTMI PHY */
240 if (pdata->have_sysif_regs) 258 if (pdata->have_sysif_regs)
241 setbits32(non_ehci + FSL_SOC_USB_CTRL, 259 setbits32(non_ehci + FSL_SOC_USB_CTRL,
@@ -276,7 +294,7 @@ static void ehci_fsl_usb_setup(struct ehci_hcd *ehci)
276 294
277 if ((pdata->operating_mode == FSL_USB2_DR_HOST) || 295 if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
278 (pdata->operating_mode == FSL_USB2_DR_OTG)) 296 (pdata->operating_mode == FSL_USB2_DR_OTG))
279 ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0); 297 ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0);
280 298
281 if (pdata->operating_mode == FSL_USB2_MPH_HOST) { 299 if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
282 unsigned int chip, rev, svr; 300 unsigned int chip, rev, svr;
@@ -290,9 +308,9 @@ static void ehci_fsl_usb_setup(struct ehci_hcd *ehci)
290 ehci->has_fsl_port_bug = 1; 308 ehci->has_fsl_port_bug = 1;
291 309
292 if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) 310 if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
293 ehci_fsl_setup_phy(ehci, pdata->phy_mode, 0); 311 ehci_fsl_setup_phy(hcd, pdata->phy_mode, 0);
294 if (pdata->port_enables & FSL_USB2_PORT1_ENABLED) 312 if (pdata->port_enables & FSL_USB2_PORT1_ENABLED)
295 ehci_fsl_setup_phy(ehci, pdata->phy_mode, 1); 313 ehci_fsl_setup_phy(hcd, pdata->phy_mode, 1);
296 } 314 }
297 315
298 if (pdata->have_sysif_regs) { 316 if (pdata->have_sysif_regs) {
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h
index 863fb0c080d..88403684d10 100644
--- a/drivers/usb/host/ehci-fsl.h
+++ b/drivers/usb/host/ehci-fsl.h
@@ -1,4 +1,4 @@
1/* Copyright (C) 2005-2010 Freescale Semiconductor, Inc. 1/* Copyright (C) 2005-2010,2012 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
@@ -50,4 +50,15 @@
50#define CTRL_UTMI_PHY_EN (1<<9) 50#define CTRL_UTMI_PHY_EN (1<<9)
51#define CTRL_PHY_CLK_VALID (1 << 17) 51#define CTRL_PHY_CLK_VALID (1 << 17)
52#define SNOOP_SIZE_2GB 0x1e 52#define SNOOP_SIZE_2GB 0x1e
53
54/* control Register Bit Masks */
55#define ULPI_INT_EN (1<<0)
56#define WU_INT_EN (1<<1)
57#define USB_CTRL_USB_EN (1<<2)
58#define LINE_STATE_FILTER__EN (1<<3)
59#define KEEP_OTG_ON (1<<4)
60#define OTG_PORT (1<<5)
61#define PLL_RESET (1<<8)
62#define UTMI_PHY_EN (1<<9)
63#define ULPI_PHY_CLK_SEL (1<<10)
53#endif /* _EHCI_FSL_H */ 64#endif /* _EHCI_FSL_H */
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 4a3bc5b7a06..a87c0573c86 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -417,9 +417,6 @@ static void ehci_iaa_watchdog(unsigned long param)
417 * CMD_IAAD when it sets STS_IAA.) 417 * CMD_IAAD when it sets STS_IAA.)
418 */ 418 */
419 cmd = ehci_readl(ehci, &ehci->regs->command); 419 cmd = ehci_readl(ehci, &ehci->regs->command);
420 if (cmd & CMD_IAAD)
421 ehci_writel(ehci, cmd & ~CMD_IAAD,
422 &ehci->regs->command);
423 420
424 /* If IAA is set here it either legitimately triggered 421 /* If IAA is set here it either legitimately triggered
425 * before we cleared IAAD above (but _way_ late, so we'll 422 * before we cleared IAAD above (but _way_ late, so we'll
@@ -894,11 +891,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
894 /* complete the unlinking of some qh [4.15.2.3] */ 891 /* complete the unlinking of some qh [4.15.2.3] */
895 if (status & STS_IAA) { 892 if (status & STS_IAA) {
896 /* guard against (alleged) silicon errata */ 893 /* guard against (alleged) silicon errata */
897 if (cmd & CMD_IAAD) { 894 if (cmd & CMD_IAAD)
898 ehci_writel(ehci, cmd & ~CMD_IAAD,
899 &ehci->regs->command);
900 ehci_dbg(ehci, "IAA with IAAD still set?\n"); 895 ehci_dbg(ehci, "IAA with IAAD still set?\n");
901 }
902 if (ehci->reclaim) { 896 if (ehci->reclaim) {
903 COUNT(ehci->stats.reclaim); 897 COUNT(ehci->stats.reclaim);
904 end_unlink_async(ehci); 898 end_unlink_async(ehci);
@@ -1378,6 +1372,11 @@ MODULE_LICENSE ("GPL");
1378#define PLATFORM_DRIVER ehci_ls1x_driver 1372#define PLATFORM_DRIVER ehci_ls1x_driver
1379#endif 1373#endif
1380 1374
1375#ifdef CONFIG_MIPS_SEAD3
1376#include "ehci-sead3.c"
1377#define PLATFORM_DRIVER ehci_hcd_sead3_driver
1378#endif
1379
1381#ifdef CONFIG_USB_EHCI_HCD_PLATFORM 1380#ifdef CONFIG_USB_EHCI_HCD_PLATFORM
1382#include "ehci-platform.c" 1381#include "ehci-platform.c"
1383#define PLATFORM_DRIVER ehci_platform_driver 1382#define PLATFORM_DRIVER ehci_platform_driver
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 38fe0762315..402e766df2f 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -531,7 +531,8 @@ static int check_reset_complete (
531 if (ehci->has_amcc_usb23) 531 if (ehci->has_amcc_usb23)
532 set_ohci_hcfs(ehci, 1); 532 set_ohci_hcfs(ehci, 1);
533 } else { 533 } else {
534 ehci_dbg (ehci, "port %d high speed\n", index + 1); 534 ehci_dbg(ehci, "port %d reset complete, port enabled\n",
535 index + 1);
535 /* ensure 440EPx ohci controller state is suspended */ 536 /* ensure 440EPx ohci controller state is suspended */
536 if (ehci->has_amcc_usb23) 537 if (ehci->has_amcc_usb23)
537 set_ohci_hcfs(ehci, 0); 538 set_ohci_hcfs(ehci, 0);
@@ -699,6 +700,7 @@ static int ehci_hub_control (
699 goto error; 700 goto error;
700 wIndex--; 701 wIndex--;
701 temp = ehci_readl(ehci, status_reg); 702 temp = ehci_readl(ehci, status_reg);
703 temp &= ~PORT_RWC_BITS;
702 704
703 /* 705 /*
704 * Even if OWNER is set, so the port is owned by the 706 * Even if OWNER is set, so the port is owned by the
@@ -712,8 +714,7 @@ static int ehci_hub_control (
712 ehci_writel(ehci, temp & ~PORT_PE, status_reg); 714 ehci_writel(ehci, temp & ~PORT_PE, status_reg);
713 break; 715 break;
714 case USB_PORT_FEAT_C_ENABLE: 716 case USB_PORT_FEAT_C_ENABLE:
715 ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_PEC, 717 ehci_writel(ehci, temp | PORT_PEC, status_reg);
716 status_reg);
717 break; 718 break;
718 case USB_PORT_FEAT_SUSPEND: 719 case USB_PORT_FEAT_SUSPEND:
719 if (temp & PORT_RESET) 720 if (temp & PORT_RESET)
@@ -742,7 +743,7 @@ static int ehci_hub_control (
742 spin_lock_irqsave(&ehci->lock, flags); 743 spin_lock_irqsave(&ehci->lock, flags);
743 } 744 }
744 /* resume signaling for 20 msec */ 745 /* resume signaling for 20 msec */
745 temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); 746 temp &= ~PORT_WAKE_BITS;
746 ehci_writel(ehci, temp | PORT_RESUME, status_reg); 747 ehci_writel(ehci, temp | PORT_RESUME, status_reg);
747 ehci->reset_done[wIndex] = jiffies 748 ehci->reset_done[wIndex] = jiffies
748 + msecs_to_jiffies(20); 749 + msecs_to_jiffies(20);
@@ -752,9 +753,8 @@ static int ehci_hub_control (
752 break; 753 break;
753 case USB_PORT_FEAT_POWER: 754 case USB_PORT_FEAT_POWER:
754 if (HCS_PPC (ehci->hcs_params)) 755 if (HCS_PPC (ehci->hcs_params))
755 ehci_writel(ehci, 756 ehci_writel(ehci, temp & ~PORT_POWER,
756 temp & ~(PORT_RWC_BITS | PORT_POWER), 757 status_reg);
757 status_reg);
758 break; 758 break;
759 case USB_PORT_FEAT_C_CONNECTION: 759 case USB_PORT_FEAT_C_CONNECTION:
760 if (ehci->has_lpm) { 760 if (ehci->has_lpm) {
@@ -762,12 +762,10 @@ static int ehci_hub_control (
762 temp &= ~PORT_LPM; 762 temp &= ~PORT_LPM;
763 temp &= ~PORT_DEV_ADDR; 763 temp &= ~PORT_DEV_ADDR;
764 } 764 }
765 ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_CSC, 765 ehci_writel(ehci, temp | PORT_CSC, status_reg);
766 status_reg);
767 break; 766 break;
768 case USB_PORT_FEAT_C_OVER_CURRENT: 767 case USB_PORT_FEAT_C_OVER_CURRENT:
769 ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_OCC, 768 ehci_writel(ehci, temp | PORT_OCC, status_reg);
770 status_reg);
771 break; 769 break;
772 case USB_PORT_FEAT_C_RESET: 770 case USB_PORT_FEAT_C_RESET:
773 /* GetPortStatus clears reset */ 771 /* GetPortStatus clears reset */
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index d238b4e24bb..23c530ae5aa 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -94,12 +94,12 @@ static int __devinit ehci_platform_probe(struct platform_device *dev)
94 94
95 irq = platform_get_irq(dev, 0); 95 irq = platform_get_irq(dev, 0);
96 if (irq < 0) { 96 if (irq < 0) {
97 pr_err("no irq provieded"); 97 pr_err("no irq provided");
98 return irq; 98 return irq;
99 } 99 }
100 res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); 100 res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
101 if (!res_mem) { 101 if (!res_mem) {
102 pr_err("no memory recourse provieded"); 102 pr_err("no memory recourse provided");
103 return -ENXIO; 103 return -ENXIO;
104 } 104 }
105 105
diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
index f098e2a291a..c474cec064e 100644
--- a/drivers/usb/host/ehci-s5p.c
+++ b/drivers/usb/host/ehci-s5p.c
@@ -232,6 +232,8 @@ static int s5p_ehci_suspend(struct device *dev)
232 if (pdata && pdata->phy_exit) 232 if (pdata && pdata->phy_exit)
233 pdata->phy_exit(pdev, S5P_USB_PHY_HOST); 233 pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
234 234
235 clk_disable(s5p_ehci->clk);
236
235 return rc; 237 return rc;
236} 238}
237 239
@@ -243,6 +245,8 @@ static int s5p_ehci_resume(struct device *dev)
243 struct platform_device *pdev = to_platform_device(dev); 245 struct platform_device *pdev = to_platform_device(dev);
244 struct s5p_ehci_platdata *pdata = pdev->dev.platform_data; 246 struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
245 247
248 clk_enable(s5p_ehci->clk);
249
246 if (pdata && pdata->phy_init) 250 if (pdata && pdata->phy_init)
247 pdata->phy_init(pdev, S5P_USB_PHY_HOST); 251 pdata->phy_init(pdev, S5P_USB_PHY_HOST);
248 252
diff --git a/drivers/usb/host/ehci-sead3.c b/drivers/usb/host/ehci-sead3.c
new file mode 100644
index 00000000000..4c164308ed2
--- /dev/null
+++ b/drivers/usb/host/ehci-sead3.c
@@ -0,0 +1,266 @@
1/*
2 * MIPS CI13320A EHCI Host Controller driver
3 * Based on "ehci-au1xxx.c" by K.Boge <karsten.boge@amd.com>
4 *
5 * Copyright (C) 2012 MIPS Technologies, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software Foundation,
19 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/platform_device.h>
23
24static int ehci_sead3_setup(struct usb_hcd *hcd)
25{
26 int ret;
27 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
28
29 ehci->caps = hcd->regs + 0x100;
30
31 ret = ehci_setup(hcd);
32 if (ret)
33 return ret;
34
35 ehci->need_io_watchdog = 0;
36
37#ifdef __BIG_ENDIAN
38 ehci->big_endian_mmio = 1;
39 ehci->big_endian_desc = 1;
40#endif
41
42 /* Set burst length to 16 words. */
43 ehci_writel(ehci, 0x1010, &ehci->regs->reserved[1]);
44
45 return ret;
46}
47
48const struct hc_driver ehci_sead3_hc_driver = {
49 .description = hcd_name,
50 .product_desc = "SEAD-3 EHCI",
51 .hcd_priv_size = sizeof(struct ehci_hcd),
52
53 /*
54 * generic hardware linkage
55 */
56 .irq = ehci_irq,
57 .flags = HCD_MEMORY | HCD_USB2,
58
59 /*
60 * basic lifecycle operations
61 *
62 */
63 .reset = ehci_sead3_setup,
64 .start = ehci_run,
65 .stop = ehci_stop,
66 .shutdown = ehci_shutdown,
67
68 /*
69 * managing i/o requests and associated device resources
70 */
71 .urb_enqueue = ehci_urb_enqueue,
72 .urb_dequeue = ehci_urb_dequeue,
73 .endpoint_disable = ehci_endpoint_disable,
74 .endpoint_reset = ehci_endpoint_reset,
75
76 /*
77 * scheduling support
78 */
79 .get_frame_number = ehci_get_frame,
80
81 /*
82 * root hub support
83 */
84 .hub_status_data = ehci_hub_status_data,
85 .hub_control = ehci_hub_control,
86 .bus_suspend = ehci_bus_suspend,
87 .bus_resume = ehci_bus_resume,
88 .relinquish_port = ehci_relinquish_port,
89 .port_handed_over = ehci_port_handed_over,
90
91 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
92};
93
94static int ehci_hcd_sead3_drv_probe(struct platform_device *pdev)
95{
96 struct usb_hcd *hcd;
97 struct resource *res;
98 int ret;
99
100 if (usb_disabled())
101 return -ENODEV;
102
103 if (pdev->resource[1].flags != IORESOURCE_IRQ) {
104 pr_debug("resource[1] is not IORESOURCE_IRQ");
105 return -ENOMEM;
106 }
107 hcd = usb_create_hcd(&ehci_sead3_hc_driver, &pdev->dev, "SEAD-3");
108 if (!hcd)
109 return -ENOMEM;
110
111 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
112 hcd->rsrc_start = res->start;
113 hcd->rsrc_len = resource_size(res);
114
115 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
116 pr_debug("request_mem_region failed");
117 ret = -EBUSY;
118 goto err1;
119 }
120
121 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
122 if (!hcd->regs) {
123 pr_debug("ioremap failed");
124 ret = -ENOMEM;
125 goto err2;
126 }
127
128 /* Root hub has integrated TT. */
129 hcd->has_tt = 1;
130
131 ret = usb_add_hcd(hcd, pdev->resource[1].start,
132 IRQF_SHARED);
133 if (ret == 0) {
134 platform_set_drvdata(pdev, hcd);
135 return ret;
136 }
137
138 iounmap(hcd->regs);
139err2:
140 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
141err1:
142 usb_put_hcd(hcd);
143 return ret;
144}
145
146static int ehci_hcd_sead3_drv_remove(struct platform_device *pdev)
147{
148 struct usb_hcd *hcd = platform_get_drvdata(pdev);
149
150 usb_remove_hcd(hcd);
151 iounmap(hcd->regs);
152 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
153 usb_put_hcd(hcd);
154 platform_set_drvdata(pdev, NULL);
155
156 return 0;
157}
158
159#ifdef CONFIG_PM
160static int ehci_hcd_sead3_drv_suspend(struct device *dev)
161{
162 struct usb_hcd *hcd = dev_get_drvdata(dev);
163 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
164 unsigned long flags;
165 int rc = 0;
166
167 if (time_before(jiffies, ehci->next_statechange))
168 msleep(20);
169
170 /* Root hub was already suspended. Disable irq emission and
171 * mark HW unaccessible. The PM and USB cores make sure that
172 * the root hub is either suspended or stopped.
173 */
174 ehci_prepare_ports_for_controller_suspend(ehci, device_may_wakeup(dev));
175 spin_lock_irqsave(&ehci->lock, flags);
176 ehci_writel(ehci, 0, &ehci->regs->intr_enable);
177 (void)ehci_readl(ehci, &ehci->regs->intr_enable);
178
179 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
180 spin_unlock_irqrestore(&ehci->lock, flags);
181
182 /* could save FLADJ in case of Vaux power loss
183 * ... we'd only use it to handle clock skew
184 */
185
186 return rc;
187}
188
189static int ehci_hcd_sead3_drv_resume(struct device *dev)
190{
191 struct usb_hcd *hcd = dev_get_drvdata(dev);
192 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
193
194 /* maybe restore FLADJ. */
195
196 if (time_before(jiffies, ehci->next_statechange))
197 msleep(100);
198
199 /* Mark hardware accessible again as we are out of D3 state by now */
200 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
201
202 /* If CF is still set, we maintained PCI Vaux power.
203 * Just undo the effect of ehci_pci_suspend().
204 */
205 if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) {
206 int mask = INTR_MASK;
207
208 ehci_prepare_ports_for_controller_resume(ehci);
209 if (!hcd->self.root_hub->do_remote_wakeup)
210 mask &= ~STS_PCD;
211 ehci_writel(ehci, mask, &ehci->regs->intr_enable);
212 ehci_readl(ehci, &ehci->regs->intr_enable);
213 return 0;
214 }
215
216 ehci_dbg(ehci, "lost power, restarting\n");
217 usb_root_hub_lost_power(hcd->self.root_hub);
218
219 /* Else reset, to cope with power loss or flush-to-storage
220 * style "resume" having let BIOS kick in during reboot.
221 */
222 (void) ehci_halt(ehci);
223 (void) ehci_reset(ehci);
224
225 /* emptying the schedule aborts any urbs */
226 spin_lock_irq(&ehci->lock);
227 if (ehci->reclaim)
228 end_unlink_async(ehci);
229 ehci_work(ehci);
230 spin_unlock_irq(&ehci->lock);
231
232 ehci_writel(ehci, ehci->command, &ehci->regs->command);
233 ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
234 ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
235
236 /* here we "know" root ports should always stay powered */
237 ehci_port_power(ehci, 1);
238
239 ehci->rh_state = EHCI_RH_SUSPENDED;
240
241 return 0;
242}
243
244static const struct dev_pm_ops sead3_ehci_pmops = {
245 .suspend = ehci_hcd_sead3_drv_suspend,
246 .resume = ehci_hcd_sead3_drv_resume,
247};
248
249#define SEAD3_EHCI_PMOPS (&sead3_ehci_pmops)
250
251#else
252#define SEAD3_EHCI_PMOPS NULL
253#endif
254
255static struct platform_driver ehci_hcd_sead3_driver = {
256 .probe = ehci_hcd_sead3_drv_probe,
257 .remove = ehci_hcd_sead3_drv_remove,
258 .shutdown = usb_hcd_platform_shutdown,
259 .driver = {
260 .name = "sead3-ehci",
261 .owner = THIS_MODULE,
262 .pm = SEAD3_EHCI_PMOPS,
263 }
264};
265
266MODULE_ALIAS("platform:sead3-ehci");
diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c
index 9d9cf47d80d..ca819cdd0c5 100644
--- a/drivers/usb/host/ehci-sh.c
+++ b/drivers/usb/host/ehci-sh.c
@@ -11,6 +11,7 @@
11 */ 11 */
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <linux/clk.h> 13#include <linux/clk.h>
14#include <linux/platform_data/ehci-sh.h>
14 15
15struct ehci_sh_priv { 16struct ehci_sh_priv {
16 struct clk *iclk, *fclk; 17 struct clk *iclk, *fclk;
@@ -100,6 +101,7 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev)
100 const struct hc_driver *driver = &ehci_sh_hc_driver; 101 const struct hc_driver *driver = &ehci_sh_hc_driver;
101 struct resource *res; 102 struct resource *res;
102 struct ehci_sh_priv *priv; 103 struct ehci_sh_priv *priv;
104 struct ehci_sh_platdata *pdata;
103 struct usb_hcd *hcd; 105 struct usb_hcd *hcd;
104 int irq, ret; 106 int irq, ret;
105 107
@@ -124,6 +126,9 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev)
124 goto fail_create_hcd; 126 goto fail_create_hcd;
125 } 127 }
126 128
129 if (pdev->dev.platform_data != NULL)
130 pdata = pdev->dev.platform_data;
131
127 /* initialize hcd */ 132 /* initialize hcd */
128 hcd = usb_create_hcd(&ehci_sh_hc_driver, &pdev->dev, 133 hcd = usb_create_hcd(&ehci_sh_hc_driver, &pdev->dev,
129 dev_name(&pdev->dev)); 134 dev_name(&pdev->dev));
@@ -168,6 +173,9 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev)
168 clk_enable(priv->fclk); 173 clk_enable(priv->fclk);
169 clk_enable(priv->iclk); 174 clk_enable(priv->iclk);
170 175
176 if (pdata && pdata->phy_init)
177 pdata->phy_init();
178
171 ret = usb_add_hcd(hcd, irq, IRQF_SHARED); 179 ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
172 if (ret != 0) { 180 if (ret != 0) {
173 dev_err(&pdev->dev, "Failed to add hcd"); 181 dev_err(&pdev->dev, "Failed to add hcd");
diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c
index 6e928559169..37ba8c8d2fd 100644
--- a/drivers/usb/host/ehci-spear.c
+++ b/drivers/usb/host/ehci-spear.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/clk.h> 14#include <linux/clk.h>
15#include <linux/jiffies.h> 15#include <linux/jiffies.h>
16#include <linux/of.h>
16#include <linux/platform_device.h> 17#include <linux/platform_device.h>
17#include <linux/pm.h> 18#include <linux/pm.h>
18 19
@@ -25,12 +26,12 @@ struct spear_ehci {
25 26
26static void spear_start_ehci(struct spear_ehci *ehci) 27static void spear_start_ehci(struct spear_ehci *ehci)
27{ 28{
28 clk_enable(ehci->clk); 29 clk_prepare_enable(ehci->clk);
29} 30}
30 31
31static void spear_stop_ehci(struct spear_ehci *ehci) 32static void spear_stop_ehci(struct spear_ehci *ehci)
32{ 33{
33 clk_disable(ehci->clk); 34 clk_disable_unprepare(ehci->clk);
34} 35}
35 36
36static int ehci_spear_setup(struct usb_hcd *hcd) 37static int ehci_spear_setup(struct usb_hcd *hcd)
@@ -168,6 +169,8 @@ static int ehci_spear_drv_resume(struct device *dev)
168static SIMPLE_DEV_PM_OPS(ehci_spear_pm_ops, ehci_spear_drv_suspend, 169static SIMPLE_DEV_PM_OPS(ehci_spear_pm_ops, ehci_spear_drv_suspend,
169 ehci_spear_drv_resume); 170 ehci_spear_drv_resume);
170 171
172static u64 spear_ehci_dma_mask = DMA_BIT_MASK(32);
173
171static int spear_ehci_hcd_drv_probe(struct platform_device *pdev) 174static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
172{ 175{
173 struct usb_hcd *hcd ; 176 struct usb_hcd *hcd ;
@@ -175,12 +178,9 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
175 struct resource *res; 178 struct resource *res;
176 struct clk *usbh_clk; 179 struct clk *usbh_clk;
177 const struct hc_driver *driver = &ehci_spear_hc_driver; 180 const struct hc_driver *driver = &ehci_spear_hc_driver;
178 int *pdata = pdev->dev.platform_data;
179 int irq, retval; 181 int irq, retval;
180 char clk_name[20] = "usbh_clk"; 182 char clk_name[20] = "usbh_clk";
181 183 static int instance = -1;
182 if (pdata == NULL)
183 return -EFAULT;
184 184
185 if (usb_disabled()) 185 if (usb_disabled())
186 return -ENODEV; 186 return -ENODEV;
@@ -191,8 +191,22 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
191 goto fail_irq_get; 191 goto fail_irq_get;
192 } 192 }
193 193
194 if (*pdata >= 0) 194 /*
195 sprintf(clk_name, "usbh.%01d_clk", *pdata); 195 * Right now device-tree probed devices don't get dma_mask set.
196 * Since shared usb code relies on it, set it here for now.
197 * Once we have dma capability bindings this can go away.
198 */
199 if (!pdev->dev.dma_mask)
200 pdev->dev.dma_mask = &spear_ehci_dma_mask;
201
202 /*
203 * Increment the device instance, when probing via device-tree
204 */
205 if (pdev->id < 0)
206 instance++;
207 else
208 instance = pdev->id;
209 sprintf(clk_name, "usbh.%01d_clk", instance);
196 210
197 usbh_clk = clk_get(NULL, clk_name); 211 usbh_clk = clk_get(NULL, clk_name);
198 if (IS_ERR(usbh_clk)) { 212 if (IS_ERR(usbh_clk)) {
@@ -277,6 +291,11 @@ static int spear_ehci_hcd_drv_remove(struct platform_device *pdev)
277 return 0; 291 return 0;
278} 292}
279 293
294static struct of_device_id spear_ehci_id_table[] __devinitdata = {
295 { .compatible = "st,spear600-ehci", },
296 { },
297};
298
280static struct platform_driver spear_ehci_hcd_driver = { 299static struct platform_driver spear_ehci_hcd_driver = {
281 .probe = spear_ehci_hcd_drv_probe, 300 .probe = spear_ehci_hcd_drv_probe,
282 .remove = spear_ehci_hcd_drv_remove, 301 .remove = spear_ehci_hcd_drv_remove,
@@ -285,6 +304,7 @@ static struct platform_driver spear_ehci_hcd_driver = {
285 .name = "spear-ehci", 304 .name = "spear-ehci",
286 .bus = &platform_bus_type, 305 .bus = &platform_bus_type,
287 .pm = &ehci_spear_pm_ops, 306 .pm = &ehci_spear_pm_ops,
307 .of_match_table = of_match_ptr(spear_ehci_id_table),
288 } 308 }
289}; 309};
290 310
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 86183366647..43bb0a9f1f7 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -148,18 +148,7 @@ static int tegra_ehci_hub_control(
148 148
149 spin_lock_irqsave(&ehci->lock, flags); 149 spin_lock_irqsave(&ehci->lock, flags);
150 150
151 /* 151 if (typeReq == GetPortStatus) {
152 * In ehci_hub_control() for USB_PORT_FEAT_ENABLE clears the other bits
153 * that are write on clear, by writing back the register read value, so
154 * USB_PORT_FEAT_ENABLE is handled by masking the set on clear bits
155 */
156 if (typeReq == ClearPortFeature && wValue == USB_PORT_FEAT_ENABLE) {
157 temp = ehci_readl(ehci, status_reg) & ~PORT_RWC_BITS;
158 ehci_writel(ehci, temp & ~PORT_PE, status_reg);
159 goto done;
160 }
161
162 else if (typeReq == GetPortStatus) {
163 temp = ehci_readl(ehci, status_reg); 152 temp = ehci_readl(ehci, status_reg);
164 if (tegra->port_resuming && !(temp & PORT_SUSPEND)) { 153 if (tegra->port_resuming && !(temp & PORT_SUSPEND)) {
165 /* Resume completed, re-enable disconnect detection */ 154 /* Resume completed, re-enable disconnect detection */
@@ -464,26 +453,23 @@ static int tegra_ehci_bus_resume(struct usb_hcd *hcd)
464} 453}
465#endif 454#endif
466 455
467struct temp_buffer { 456struct dma_aligned_buffer {
468 void *kmalloc_ptr; 457 void *kmalloc_ptr;
469 void *old_xfer_buffer; 458 void *old_xfer_buffer;
470 u8 data[0]; 459 u8 data[0];
471}; 460};
472 461
473static void free_temp_buffer(struct urb *urb) 462static void free_dma_aligned_buffer(struct urb *urb)
474{ 463{
475 enum dma_data_direction dir; 464 struct dma_aligned_buffer *temp;
476 struct temp_buffer *temp;
477 465
478 if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER)) 466 if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
479 return; 467 return;
480 468
481 dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; 469 temp = container_of(urb->transfer_buffer,
482 470 struct dma_aligned_buffer, data);
483 temp = container_of(urb->transfer_buffer, struct temp_buffer,
484 data);
485 471
486 if (dir == DMA_FROM_DEVICE) 472 if (usb_urb_dir_in(urb))
487 memcpy(temp->old_xfer_buffer, temp->data, 473 memcpy(temp->old_xfer_buffer, temp->data,
488 urb->transfer_buffer_length); 474 urb->transfer_buffer_length);
489 urb->transfer_buffer = temp->old_xfer_buffer; 475 urb->transfer_buffer = temp->old_xfer_buffer;
@@ -492,10 +478,9 @@ static void free_temp_buffer(struct urb *urb)
492 urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER; 478 urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
493} 479}
494 480
495static int alloc_temp_buffer(struct urb *urb, gfp_t mem_flags) 481static int alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
496{ 482{
497 enum dma_data_direction dir; 483 struct dma_aligned_buffer *temp, *kmalloc_ptr;
498 struct temp_buffer *temp, *kmalloc_ptr;
499 size_t kmalloc_size; 484 size_t kmalloc_size;
500 485
501 if (urb->num_sgs || urb->sg || 486 if (urb->num_sgs || urb->sg ||
@@ -503,22 +488,19 @@ static int alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
503 !((uintptr_t)urb->transfer_buffer & (TEGRA_USB_DMA_ALIGN - 1))) 488 !((uintptr_t)urb->transfer_buffer & (TEGRA_USB_DMA_ALIGN - 1)))
504 return 0; 489 return 0;
505 490
506 dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
507
508 /* Allocate a buffer with enough padding for alignment */ 491 /* Allocate a buffer with enough padding for alignment */
509 kmalloc_size = urb->transfer_buffer_length + 492 kmalloc_size = urb->transfer_buffer_length +
510 sizeof(struct temp_buffer) + TEGRA_USB_DMA_ALIGN - 1; 493 sizeof(struct dma_aligned_buffer) + TEGRA_USB_DMA_ALIGN - 1;
511 494
512 kmalloc_ptr = kmalloc(kmalloc_size, mem_flags); 495 kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
513 if (!kmalloc_ptr) 496 if (!kmalloc_ptr)
514 return -ENOMEM; 497 return -ENOMEM;
515 498
516 /* Position our struct temp_buffer such that data is aligned */ 499 /* Position our struct dma_aligned_buffer such that data is aligned */
517 temp = PTR_ALIGN(kmalloc_ptr + 1, TEGRA_USB_DMA_ALIGN) - 1; 500 temp = PTR_ALIGN(kmalloc_ptr + 1, TEGRA_USB_DMA_ALIGN) - 1;
518
519 temp->kmalloc_ptr = kmalloc_ptr; 501 temp->kmalloc_ptr = kmalloc_ptr;
520 temp->old_xfer_buffer = urb->transfer_buffer; 502 temp->old_xfer_buffer = urb->transfer_buffer;
521 if (dir == DMA_TO_DEVICE) 503 if (usb_urb_dir_out(urb))
522 memcpy(temp->data, urb->transfer_buffer, 504 memcpy(temp->data, urb->transfer_buffer,
523 urb->transfer_buffer_length); 505 urb->transfer_buffer_length);
524 urb->transfer_buffer = temp->data; 506 urb->transfer_buffer = temp->data;
@@ -533,13 +515,13 @@ static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
533{ 515{
534 int ret; 516 int ret;
535 517
536 ret = alloc_temp_buffer(urb, mem_flags); 518 ret = alloc_dma_aligned_buffer(urb, mem_flags);
537 if (ret) 519 if (ret)
538 return ret; 520 return ret;
539 521
540 ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags); 522 ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
541 if (ret) 523 if (ret)
542 free_temp_buffer(urb); 524 free_dma_aligned_buffer(urb);
543 525
544 return ret; 526 return ret;
545} 527}
@@ -547,38 +529,39 @@ static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
547static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) 529static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
548{ 530{
549 usb_hcd_unmap_urb_for_dma(hcd, urb); 531 usb_hcd_unmap_urb_for_dma(hcd, urb);
550 free_temp_buffer(urb); 532 free_dma_aligned_buffer(urb);
551} 533}
552 534
553static const struct hc_driver tegra_ehci_hc_driver = { 535static const struct hc_driver tegra_ehci_hc_driver = {
554 .description = hcd_name, 536 .description = hcd_name,
555 .product_desc = "Tegra EHCI Host Controller", 537 .product_desc = "Tegra EHCI Host Controller",
556 .hcd_priv_size = sizeof(struct ehci_hcd), 538 .hcd_priv_size = sizeof(struct ehci_hcd),
557
558 .flags = HCD_USB2 | HCD_MEMORY, 539 .flags = HCD_USB2 | HCD_MEMORY,
559 540
560 .reset = tegra_ehci_setup, 541 /* standard ehci functions */
561 .irq = ehci_irq, 542 .irq = ehci_irq,
562
563 .start = ehci_run, 543 .start = ehci_run,
564 .stop = ehci_stop, 544 .stop = ehci_stop,
565 .shutdown = tegra_ehci_shutdown,
566 .urb_enqueue = ehci_urb_enqueue, 545 .urb_enqueue = ehci_urb_enqueue,
567 .urb_dequeue = ehci_urb_dequeue, 546 .urb_dequeue = ehci_urb_dequeue,
568 .map_urb_for_dma = tegra_ehci_map_urb_for_dma,
569 .unmap_urb_for_dma = tegra_ehci_unmap_urb_for_dma,
570 .endpoint_disable = ehci_endpoint_disable, 547 .endpoint_disable = ehci_endpoint_disable,
571 .endpoint_reset = ehci_endpoint_reset, 548 .endpoint_reset = ehci_endpoint_reset,
572 .get_frame_number = ehci_get_frame, 549 .get_frame_number = ehci_get_frame,
573 .hub_status_data = ehci_hub_status_data, 550 .hub_status_data = ehci_hub_status_data,
574 .hub_control = tegra_ehci_hub_control,
575 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, 551 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
552 .relinquish_port = ehci_relinquish_port,
553 .port_handed_over = ehci_port_handed_over,
554
555 /* modified ehci functions for tegra */
556 .reset = tegra_ehci_setup,
557 .shutdown = tegra_ehci_shutdown,
558 .map_urb_for_dma = tegra_ehci_map_urb_for_dma,
559 .unmap_urb_for_dma = tegra_ehci_unmap_urb_for_dma,
560 .hub_control = tegra_ehci_hub_control,
576#ifdef CONFIG_PM 561#ifdef CONFIG_PM
577 .bus_suspend = tegra_ehci_bus_suspend, 562 .bus_suspend = tegra_ehci_bus_suspend,
578 .bus_resume = tegra_ehci_bus_resume, 563 .bus_resume = tegra_ehci_bus_resume,
579#endif 564#endif
580 .relinquish_port = ehci_relinquish_port,
581 .port_handed_over = ehci_port_handed_over,
582}; 565};
583 566
584static int setup_vbus_gpio(struct platform_device *pdev) 567static int setup_vbus_gpio(struct platform_device *pdev)
diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c
index 0ea577bfca2..c5ed8819929 100644
--- a/drivers/usb/host/fhci-tds.c
+++ b/drivers/usb/host/fhci-tds.c
@@ -155,7 +155,7 @@ u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
155 struct endpoint *ep; 155 struct endpoint *ep;
156 struct usb_td __iomem *td; 156 struct usb_td __iomem *td;
157 unsigned long ep_offset; 157 unsigned long ep_offset;
158 char *err_for = "enpoint PRAM"; 158 char *err_for = "endpoint PRAM";
159 int ep_mem_size; 159 int ep_mem_size;
160 u32 i; 160 u32 i;
161 161
diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c
index ab333ac6071..22ff6b3a676 100644
--- a/drivers/usb/host/fsl-mph-dr-of.c
+++ b/drivers/usb/host/fsl-mph-dr-of.c
@@ -119,6 +119,39 @@ error:
119 119
120static const struct of_device_id fsl_usb2_mph_dr_of_match[]; 120static const struct of_device_id fsl_usb2_mph_dr_of_match[];
121 121
122static int usb_get_ver_info(struct device_node *np)
123{
124 int ver = -1;
125
126 /*
127 * returns 1 for usb controller version 1.6
128 * returns 2 for usb controller version 2.2
129 * returns 0 otherwise
130 */
131 if (of_device_is_compatible(np, "fsl-usb2-dr")) {
132 if (of_device_is_compatible(np, "fsl-usb2-dr-v1.6"))
133 ver = FSL_USB_VER_1_6;
134 else if (of_device_is_compatible(np, "fsl-usb2-dr-v2.2"))
135 ver = FSL_USB_VER_2_2;
136 else /* for previous controller versions */
137 ver = FSL_USB_VER_OLD;
138
139 if (ver > -1)
140 return ver;
141 }
142
143 if (of_device_is_compatible(np, "fsl-usb2-mph")) {
144 if (of_device_is_compatible(np, "fsl-usb2-mph-v1.6"))
145 ver = FSL_USB_VER_1_6;
146 else if (of_device_is_compatible(np, "fsl-usb2-mph-v2.2"))
147 ver = FSL_USB_VER_2_2;
148 else /* for previous controller versions */
149 ver = FSL_USB_VER_OLD;
150 }
151
152 return ver;
153}
154
122static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) 155static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
123{ 156{
124 struct device_node *np = ofdev->dev.of_node; 157 struct device_node *np = ofdev->dev.of_node;
@@ -166,6 +199,14 @@ static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev)
166 199
167 prop = of_get_property(np, "phy_type", NULL); 200 prop = of_get_property(np, "phy_type", NULL);
168 pdata->phy_mode = determine_usb_phy(prop); 201 pdata->phy_mode = determine_usb_phy(prop);
202 pdata->controller_ver = usb_get_ver_info(np);
203
204 if (pdata->have_sysif_regs) {
205 if (pdata->controller_ver < 0) {
206 dev_warn(&ofdev->dev, "Could not get controller version\n");
207 return -ENODEV;
208 }
209 }
169 210
170 for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) { 211 for (i = 0; i < ARRAY_SIZE(dev_data->drivers); i++) {
171 if (!dev_data->drivers[i]) 212 if (!dev_data->drivers[i])
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index fc72d44bf78..a35bbddf896 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -1562,11 +1562,14 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
1562 1562
1563 if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { 1563 if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
1564 retval = -ESHUTDOWN; 1564 retval = -ESHUTDOWN;
1565 qtd_list_free(&new_qtds);
1565 goto out; 1566 goto out;
1566 } 1567 }
1567 retval = usb_hcd_link_urb_to_ep(hcd, urb); 1568 retval = usb_hcd_link_urb_to_ep(hcd, urb);
1568 if (retval) 1569 if (retval) {
1570 qtd_list_free(&new_qtds);
1569 goto out; 1571 goto out;
1572 }
1570 1573
1571 qh = urb->ep->hcpriv; 1574 qh = urb->ep->hcpriv;
1572 if (qh) { 1575 if (qh) {
@@ -1584,6 +1587,7 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
1584 if (!qh) { 1587 if (!qh) {
1585 retval = -ENOMEM; 1588 retval = -ENOMEM;
1586 usb_hcd_unlink_urb_from_ep(hcd, urb); 1589 usb_hcd_unlink_urb_from_ep(hcd, urb);
1590 qtd_list_free(&new_qtds);
1587 goto out; 1591 goto out;
1588 } 1592 }
1589 list_add_tail(&qh->qh_list, ep_queue); 1593 list_add_tail(&qh->qh_list, ep_queue);
@@ -1683,6 +1687,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
1683 list_for_each_entry(qtd, &qh->qtd_list, qtd_list) 1687 list_for_each_entry(qtd, &qh->qtd_list, qtd_list)
1684 if (qtd->urb == urb) { 1688 if (qtd->urb == urb) {
1685 dequeue_urb_from_qtd(hcd, qh, qtd); 1689 dequeue_urb_from_qtd(hcd, qh, qtd);
1690 list_move(&qtd->qtd_list, &qh->qtd_list);
1686 break; 1691 break;
1687 } 1692 }
1688 1693
@@ -2176,7 +2181,7 @@ static const struct hc_driver isp1760_hc_driver = {
2176 2181
2177int __init init_kmem_once(void) 2182int __init init_kmem_once(void)
2178{ 2183{
2179 urb_listitem_cachep = kmem_cache_create("isp1760 urb_listitem", 2184 urb_listitem_cachep = kmem_cache_create("isp1760_urb_listitem",
2180 sizeof(struct urb_listitem), 0, SLAB_TEMPORARY | 2185 sizeof(struct urb_listitem), 0, SLAB_TEMPORARY |
2181 SLAB_MEM_SPREAD, NULL); 2186 SLAB_MEM_SPREAD, NULL);
2182 2187
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
index 4592dc17a9f..fff114fd546 100644
--- a/drivers/usb/host/isp1760-if.c
+++ b/drivers/usb/host/isp1760-if.c
@@ -398,6 +398,9 @@ static int __devinit isp1760_plat_probe(struct platform_device *pdev)
398 hcd = isp1760_register(mem_res->start, mem_size, irq_res->start, 398 hcd = isp1760_register(mem_res->start, mem_size, irq_res->start,
399 irqflags, -ENOENT, 399 irqflags, -ENOENT,
400 &pdev->dev, dev_name(&pdev->dev), devflags); 400 &pdev->dev, dev_name(&pdev->dev), devflags);
401
402 dev_set_drvdata(&pdev->dev, hcd);
403
401 if (IS_ERR(hcd)) { 404 if (IS_ERR(hcd)) {
402 pr_warning("isp1760: Failed to register the HCD device\n"); 405 pr_warning("isp1760: Failed to register the HCD device\n");
403 ret = -ENODEV; 406 ret = -ENODEV;
@@ -417,11 +420,16 @@ static int __devexit isp1760_plat_remove(struct platform_device *pdev)
417{ 420{
418 struct resource *mem_res; 421 struct resource *mem_res;
419 resource_size_t mem_size; 422 resource_size_t mem_size;
423 struct usb_hcd *hcd = dev_get_drvdata(&pdev->dev);
424
425 usb_remove_hcd(hcd);
420 426
421 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 427 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
422 mem_size = resource_size(mem_res); 428 mem_size = resource_size(mem_res);
423 release_mem_region(mem_res->start, mem_size); 429 release_mem_region(mem_res->start, mem_size);
424 430
431 usb_put_hcd(hcd);
432
425 return 0; 433 return 0;
426} 434}
427 435
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 235171f2946..e0adf5c0cf5 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1080,11 +1080,6 @@ MODULE_LICENSE ("GPL");
1080#define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver 1080#define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver
1081#endif 1081#endif
1082 1082
1083#ifdef CONFIG_USB_OHCI_HCD_SSB
1084#include "ohci-ssb.c"
1085#define SSB_OHCI_DRIVER ssb_ohci_driver
1086#endif
1087
1088#ifdef CONFIG_MFD_SM501 1083#ifdef CONFIG_MFD_SM501
1089#include "ohci-sm501.c" 1084#include "ohci-sm501.c"
1090#define SM501_OHCI_DRIVER ohci_hcd_sm501_driver 1085#define SM501_OHCI_DRIVER ohci_hcd_sm501_driver
@@ -1128,8 +1123,7 @@ MODULE_LICENSE ("GPL");
1128 !defined(SA1111_DRIVER) && \ 1123 !defined(SA1111_DRIVER) && \
1129 !defined(PS3_SYSTEM_BUS_DRIVER) && \ 1124 !defined(PS3_SYSTEM_BUS_DRIVER) && \
1130 !defined(SM501_OHCI_DRIVER) && \ 1125 !defined(SM501_OHCI_DRIVER) && \
1131 !defined(TMIO_OHCI_DRIVER) && \ 1126 !defined(TMIO_OHCI_DRIVER)
1132 !defined(SSB_OHCI_DRIVER)
1133#error "missing bus glue for ohci-hcd" 1127#error "missing bus glue for ohci-hcd"
1134#endif 1128#endif
1135 1129
@@ -1195,12 +1189,6 @@ static int __init ohci_hcd_mod_init(void)
1195 goto error_pci; 1189 goto error_pci;
1196#endif 1190#endif
1197 1191
1198#ifdef SSB_OHCI_DRIVER
1199 retval = ssb_driver_register(&SSB_OHCI_DRIVER);
1200 if (retval)
1201 goto error_ssb;
1202#endif
1203
1204#ifdef SM501_OHCI_DRIVER 1192#ifdef SM501_OHCI_DRIVER
1205 retval = platform_driver_register(&SM501_OHCI_DRIVER); 1193 retval = platform_driver_register(&SM501_OHCI_DRIVER);
1206 if (retval < 0) 1194 if (retval < 0)
@@ -1224,10 +1212,6 @@ static int __init ohci_hcd_mod_init(void)
1224 platform_driver_unregister(&SM501_OHCI_DRIVER); 1212 platform_driver_unregister(&SM501_OHCI_DRIVER);
1225 error_sm501: 1213 error_sm501:
1226#endif 1214#endif
1227#ifdef SSB_OHCI_DRIVER
1228 ssb_driver_unregister(&SSB_OHCI_DRIVER);
1229 error_ssb:
1230#endif
1231#ifdef PCI_DRIVER 1215#ifdef PCI_DRIVER
1232 pci_unregister_driver(&PCI_DRIVER); 1216 pci_unregister_driver(&PCI_DRIVER);
1233 error_pci: 1217 error_pci:
@@ -1275,9 +1259,6 @@ static void __exit ohci_hcd_mod_exit(void)
1275#ifdef SM501_OHCI_DRIVER 1259#ifdef SM501_OHCI_DRIVER
1276 platform_driver_unregister(&SM501_OHCI_DRIVER); 1260 platform_driver_unregister(&SM501_OHCI_DRIVER);
1277#endif 1261#endif
1278#ifdef SSB_OHCI_DRIVER
1279 ssb_driver_unregister(&SSB_OHCI_DRIVER);
1280#endif
1281#ifdef PCI_DRIVER 1262#ifdef PCI_DRIVER
1282 pci_unregister_driver(&PCI_DRIVER); 1263 pci_unregister_driver(&PCI_DRIVER);
1283#endif 1264#endif
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index ec5c6791c8b..670c7059c9a 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -93,13 +93,13 @@ static int __devinit ohci_platform_probe(struct platform_device *dev)
93 93
94 irq = platform_get_irq(dev, 0); 94 irq = platform_get_irq(dev, 0);
95 if (irq < 0) { 95 if (irq < 0) {
96 pr_err("no irq provieded"); 96 pr_err("no irq provided");
97 return irq; 97 return irq;
98 } 98 }
99 99
100 res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); 100 res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
101 if (!res_mem) { 101 if (!res_mem) {
102 pr_err("no memory recourse provieded"); 102 pr_err("no memory recourse provided");
103 return -ENXIO; 103 return -ENXIO;
104 } 104 }
105 105
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c
index d24cc89de16..b2b5767cb37 100644
--- a/drivers/usb/host/ohci-ppc-of.c
+++ b/drivers/usb/host/ohci-ppc-of.c
@@ -236,7 +236,7 @@ MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match);
236 236
237#if !defined(CONFIG_USB_OHCI_HCD_PPC_OF_BE) && \ 237#if !defined(CONFIG_USB_OHCI_HCD_PPC_OF_BE) && \
238 !defined(CONFIG_USB_OHCI_HCD_PPC_OF_LE) 238 !defined(CONFIG_USB_OHCI_HCD_PPC_OF_LE)
239#error "No endianess selected for ppc-of-ohci" 239#error "No endianness selected for ppc-of-ohci"
240#endif 240#endif
241 241
242 242
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
index 95c16489e88..fc7305ee3c9 100644
--- a/drivers/usb/host/ohci-spear.c
+++ b/drivers/usb/host/ohci-spear.c
@@ -14,6 +14,7 @@
14#include <linux/signal.h> 14#include <linux/signal.h>
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/of.h>
17 18
18struct spear_ohci { 19struct spear_ohci {
19 struct ohci_hcd ohci; 20 struct ohci_hcd ohci;
@@ -24,12 +25,12 @@ struct spear_ohci {
24 25
25static void spear_start_ohci(struct spear_ohci *ohci) 26static void spear_start_ohci(struct spear_ohci *ohci)
26{ 27{
27 clk_enable(ohci->clk); 28 clk_prepare_enable(ohci->clk);
28} 29}
29 30
30static void spear_stop_ohci(struct spear_ohci *ohci) 31static void spear_stop_ohci(struct spear_ohci *ohci)
31{ 32{
32 clk_disable(ohci->clk); 33 clk_disable_unprepare(ohci->clk);
33} 34}
34 35
35static int __devinit ohci_spear_start(struct usb_hcd *hcd) 36static int __devinit ohci_spear_start(struct usb_hcd *hcd)
@@ -90,6 +91,8 @@ static const struct hc_driver ohci_spear_hc_driver = {
90 .start_port_reset = ohci_start_port_reset, 91 .start_port_reset = ohci_start_port_reset,
91}; 92};
92 93
94static u64 spear_ohci_dma_mask = DMA_BIT_MASK(32);
95
93static int spear_ohci_hcd_drv_probe(struct platform_device *pdev) 96static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
94{ 97{
95 const struct hc_driver *driver = &ohci_spear_hc_driver; 98 const struct hc_driver *driver = &ohci_spear_hc_driver;
@@ -98,11 +101,8 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
98 struct spear_ohci *ohci_p; 101 struct spear_ohci *ohci_p;
99 struct resource *res; 102 struct resource *res;
100 int retval, irq; 103 int retval, irq;
101 int *pdata = pdev->dev.platform_data;
102 char clk_name[20] = "usbh_clk"; 104 char clk_name[20] = "usbh_clk";
103 105 static int instance = -1;
104 if (pdata == NULL)
105 return -EFAULT;
106 106
107 irq = platform_get_irq(pdev, 0); 107 irq = platform_get_irq(pdev, 0);
108 if (irq < 0) { 108 if (irq < 0) {
@@ -110,8 +110,22 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
110 goto fail_irq_get; 110 goto fail_irq_get;
111 } 111 }
112 112
113 if (*pdata >= 0) 113 /*
114 sprintf(clk_name, "usbh.%01d_clk", *pdata); 114 * Right now device-tree probed devices don't get dma_mask set.
115 * Since shared usb code relies on it, set it here for now.
116 * Once we have dma capability bindings this can go away.
117 */
118 if (!pdev->dev.dma_mask)
119 pdev->dev.dma_mask = &spear_ohci_dma_mask;
120
121 /*
122 * Increment the device instance, when probing via device-tree
123 */
124 if (pdev->id < 0)
125 instance++;
126 else
127 instance = pdev->id;
128 sprintf(clk_name, "usbh.%01d_clk", instance);
115 129
116 usbh_clk = clk_get(NULL, clk_name); 130 usbh_clk = clk_get(NULL, clk_name);
117 if (IS_ERR(usbh_clk)) { 131 if (IS_ERR(usbh_clk)) {
@@ -222,6 +236,11 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
222} 236}
223#endif 237#endif
224 238
239static struct of_device_id spear_ohci_id_table[] __devinitdata = {
240 { .compatible = "st,spear600-ohci", },
241 { },
242};
243
225/* Driver definition to register with the platform bus */ 244/* Driver definition to register with the platform bus */
226static struct platform_driver spear_ohci_hcd_driver = { 245static struct platform_driver spear_ohci_hcd_driver = {
227 .probe = spear_ohci_hcd_drv_probe, 246 .probe = spear_ohci_hcd_drv_probe,
@@ -233,6 +252,7 @@ static struct platform_driver spear_ohci_hcd_driver = {
233 .driver = { 252 .driver = {
234 .owner = THIS_MODULE, 253 .owner = THIS_MODULE,
235 .name = "spear-ohci", 254 .name = "spear-ohci",
255 .of_match_table = of_match_ptr(spear_ohci_id_table),
236 }, 256 },
237}; 257};
238 258
diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c
deleted file mode 100644
index 5ba18595d6f..00000000000
--- a/drivers/usb/host/ohci-ssb.c
+++ /dev/null
@@ -1,260 +0,0 @@
1/*
2 * Sonics Silicon Backplane
3 * Broadcom USB-core OHCI driver
4 *
5 * Copyright 2007 Michael Buesch <m@bues.ch>
6 *
7 * Derived from the OHCI-PCI driver
8 * Copyright 1999 Roman Weissgaerber
9 * Copyright 2000-2002 David Brownell
10 * Copyright 1999 Linus Torvalds
11 * Copyright 1999 Gregory P. Smith
12 *
13 * Derived from the USBcore related parts of Broadcom-SB
14 * Copyright 2005 Broadcom Corporation
15 *
16 * Licensed under the GNU/GPL. See COPYING for details.
17 */
18#include <linux/ssb/ssb.h>
19
20
21#define SSB_OHCI_TMSLOW_HOSTMODE (1 << 29)
22
23struct ssb_ohci_device {
24 struct ohci_hcd ohci; /* _must_ be at the beginning. */
25
26 u32 enable_flags;
27};
28
29static inline
30struct ssb_ohci_device *hcd_to_ssb_ohci(struct usb_hcd *hcd)
31{
32 return (struct ssb_ohci_device *)(hcd->hcd_priv);
33}
34
35
36static int ssb_ohci_reset(struct usb_hcd *hcd)
37{
38 struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd);
39 struct ohci_hcd *ohci = &ohcidev->ohci;
40 int err;
41
42 ohci_hcd_init(ohci);
43 err = ohci_init(ohci);
44
45 return err;
46}
47
48static int ssb_ohci_start(struct usb_hcd *hcd)
49{
50 struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd);
51 struct ohci_hcd *ohci = &ohcidev->ohci;
52 int err;
53
54 err = ohci_run(ohci);
55 if (err < 0) {
56 ohci_err(ohci, "can't start\n");
57 ohci_stop(hcd);
58 }
59
60 return err;
61}
62
63static const struct hc_driver ssb_ohci_hc_driver = {
64 .description = "ssb-usb-ohci",
65 .product_desc = "SSB OHCI Controller",
66 .hcd_priv_size = sizeof(struct ssb_ohci_device),
67
68 .irq = ohci_irq,
69 .flags = HCD_MEMORY | HCD_USB11,
70
71 .reset = ssb_ohci_reset,
72 .start = ssb_ohci_start,
73 .stop = ohci_stop,
74 .shutdown = ohci_shutdown,
75
76 .urb_enqueue = ohci_urb_enqueue,
77 .urb_dequeue = ohci_urb_dequeue,
78 .endpoint_disable = ohci_endpoint_disable,
79
80 .get_frame_number = ohci_get_frame,
81
82 .hub_status_data = ohci_hub_status_data,
83 .hub_control = ohci_hub_control,
84#ifdef CONFIG_PM
85 .bus_suspend = ohci_bus_suspend,
86 .bus_resume = ohci_bus_resume,
87#endif
88
89 .start_port_reset = ohci_start_port_reset,
90};
91
92static void ssb_ohci_detach(struct ssb_device *dev)
93{
94 struct usb_hcd *hcd = ssb_get_drvdata(dev);
95
96 if (hcd->driver->shutdown)
97 hcd->driver->shutdown(hcd);
98 usb_remove_hcd(hcd);
99 iounmap(hcd->regs);
100 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
101 usb_put_hcd(hcd);
102 ssb_device_disable(dev, 0);
103}
104
105static int ssb_ohci_attach(struct ssb_device *dev)
106{
107 struct ssb_ohci_device *ohcidev;
108 struct usb_hcd *hcd;
109 int err = -ENOMEM;
110 u32 tmp, flags = 0;
111
112 if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) ||
113 dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32)))
114 return -EOPNOTSUPP;
115
116 if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV) {
117 /* Put the device into host-mode. */
118 flags |= SSB_OHCI_TMSLOW_HOSTMODE;
119 ssb_device_enable(dev, flags);
120 } else if (dev->id.coreid == SSB_DEV_USB20_HOST) {
121 /*
122 * USB 2.0 special considerations:
123 *
124 * In addition to the standard SSB reset sequence, the Host
125 * Control Register must be programmed to bring the USB core
126 * and various phy components out of reset.
127 */
128 ssb_device_enable(dev, 0);
129 ssb_write32(dev, 0x200, 0x7ff);
130
131 /* Change Flush control reg */
132 tmp = ssb_read32(dev, 0x400);
133 tmp &= ~8;
134 ssb_write32(dev, 0x400, tmp);
135 tmp = ssb_read32(dev, 0x400);
136
137 /* Change Shim control reg */
138 tmp = ssb_read32(dev, 0x304);
139 tmp &= ~0x100;
140 ssb_write32(dev, 0x304, tmp);
141 tmp = ssb_read32(dev, 0x304);
142
143 udelay(1);
144
145 /* Work around for 5354 failures */
146 if (dev->id.revision == 2 && dev->bus->chip_id == 0x5354) {
147 /* Change syn01 reg */
148 tmp = 0x00fe00fe;
149 ssb_write32(dev, 0x894, tmp);
150
151 /* Change syn03 reg */
152 tmp = ssb_read32(dev, 0x89c);
153 tmp |= 0x1;
154 ssb_write32(dev, 0x89c, tmp);
155 }
156 } else
157 ssb_device_enable(dev, 0);
158
159 hcd = usb_create_hcd(&ssb_ohci_hc_driver, dev->dev,
160 dev_name(dev->dev));
161 if (!hcd)
162 goto err_dev_disable;
163 ohcidev = hcd_to_ssb_ohci(hcd);
164 ohcidev->enable_flags = flags;
165
166 tmp = ssb_read32(dev, SSB_ADMATCH0);
167 hcd->rsrc_start = ssb_admatch_base(tmp);
168 hcd->rsrc_len = ssb_admatch_size(tmp);
169 hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
170 if (!hcd->regs)
171 goto err_put_hcd;
172 err = usb_add_hcd(hcd, dev->irq, IRQF_SHARED);
173 if (err)
174 goto err_iounmap;
175
176 ssb_set_drvdata(dev, hcd);
177
178 return err;
179
180err_iounmap:
181 iounmap(hcd->regs);
182err_put_hcd:
183 usb_put_hcd(hcd);
184err_dev_disable:
185 ssb_device_disable(dev, flags);
186 return err;
187}
188
189static int ssb_ohci_probe(struct ssb_device *dev,
190 const struct ssb_device_id *id)
191{
192 int err;
193 u16 chipid_top;
194
195 /* USBcores are only connected on embedded devices. */
196 chipid_top = (dev->bus->chip_id & 0xFF00);
197 if (chipid_top != 0x4700 && chipid_top != 0x5300)
198 return -ENODEV;
199
200 /* TODO: Probably need checks here; is the core connected? */
201
202 if (usb_disabled())
203 return -ENODEV;
204
205 /* We currently always attach SSB_DEV_USB11_HOSTDEV
206 * as HOST OHCI. If we want to attach it as Client device,
207 * we must branch here and call into the (yet to
208 * be written) Client mode driver. Same for remove(). */
209
210 err = ssb_ohci_attach(dev);
211
212 return err;
213}
214
215static void ssb_ohci_remove(struct ssb_device *dev)
216{
217 ssb_ohci_detach(dev);
218}
219
220#ifdef CONFIG_PM
221
222static int ssb_ohci_suspend(struct ssb_device *dev, pm_message_t state)
223{
224 ssb_device_disable(dev, 0);
225
226 return 0;
227}
228
229static int ssb_ohci_resume(struct ssb_device *dev)
230{
231 struct usb_hcd *hcd = ssb_get_drvdata(dev);
232 struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd);
233
234 ssb_device_enable(dev, ohcidev->enable_flags);
235
236 ohci_finish_controller_resume(hcd);
237 return 0;
238}
239
240#else /* !CONFIG_PM */
241#define ssb_ohci_suspend NULL
242#define ssb_ohci_resume NULL
243#endif /* CONFIG_PM */
244
245static const struct ssb_device_id ssb_ohci_table[] = {
246 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV),
247 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV),
248 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV),
249 SSB_DEVTABLE_END
250};
251MODULE_DEVICE_TABLE(ssb, ssb_ohci_table);
252
253static struct ssb_driver ssb_ohci_driver = {
254 .name = KBUILD_MODNAME,
255 .id_table = ssb_ohci_table,
256 .probe = ssb_ohci_probe,
257 .remove = ssb_ohci_remove,
258 .suspend = ssb_ohci_suspend,
259 .resume = ssb_ohci_resume,
260};
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index 3b38030b02a..77a52256eb3 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -2991,8 +2991,9 @@ static int oxu_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
2991 /* shouldn't happen often, but ... 2991 /* shouldn't happen often, but ...
2992 * FIXME kill those tds' urbs 2992 * FIXME kill those tds' urbs
2993 */ 2993 */
2994 err("can't reschedule qh %p, err %d", 2994 dev_err(hcd->self.controller,
2995 qh, status); 2995 "can't reschedule qh %p, err %d\n", qh,
2996 status);
2996 } 2997 }
2997 return status; 2998 return status;
2998 } 2999 }
diff --git a/drivers/usb/host/ssb-hcd.c b/drivers/usb/host/ssb-hcd.c
new file mode 100644
index 00000000000..c2e73433b30
--- /dev/null
+++ b/drivers/usb/host/ssb-hcd.c
@@ -0,0 +1,279 @@
1/*
2 * Sonics Silicon Backplane
3 * Broadcom USB-core driver (SSB bus glue)
4 *
5 * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
6 *
7 * Based on ssb-ohci driver
8 * Copyright 2007 Michael Buesch <m@bues.ch>
9 *
10 * Derived from the OHCI-PCI driver
11 * Copyright 1999 Roman Weissgaerber
12 * Copyright 2000-2002 David Brownell
13 * Copyright 1999 Linus Torvalds
14 * Copyright 1999 Gregory P. Smith
15 *
16 * Derived from the USBcore related parts of Broadcom-SB
17 * Copyright 2005-2011 Broadcom Corporation
18 *
19 * Licensed under the GNU/GPL. See COPYING for details.
20 */
21#include <linux/ssb/ssb.h>
22#include <linux/delay.h>
23#include <linux/platform_device.h>
24#include <linux/module.h>
25#include <linux/usb/ehci_pdriver.h>
26#include <linux/usb/ohci_pdriver.h>
27
28MODULE_AUTHOR("Hauke Mehrtens");
29MODULE_DESCRIPTION("Common USB driver for SSB Bus");
30MODULE_LICENSE("GPL");
31
32#define SSB_HCD_TMSLOW_HOSTMODE (1 << 29)
33
34struct ssb_hcd_device {
35 struct platform_device *ehci_dev;
36 struct platform_device *ohci_dev;
37
38 u32 enable_flags;
39};
40
41static void __devinit ssb_hcd_5354wa(struct ssb_device *dev)
42{
43#ifdef CONFIG_SSB_DRIVER_MIPS
44 /* Work around for 5354 failures */
45 if (dev->id.revision == 2 && dev->bus->chip_id == 0x5354) {
46 /* Change syn01 reg */
47 ssb_write32(dev, 0x894, 0x00fe00fe);
48
49 /* Change syn03 reg */
50 ssb_write32(dev, 0x89c, ssb_read32(dev, 0x89c) | 0x1);
51 }
52#endif
53}
54
55static void __devinit ssb_hcd_usb20wa(struct ssb_device *dev)
56{
57 if (dev->id.coreid == SSB_DEV_USB20_HOST) {
58 /*
59 * USB 2.0 special considerations:
60 *
61 * In addition to the standard SSB reset sequence, the Host
62 * Control Register must be programmed to bring the USB core
63 * and various phy components out of reset.
64 */
65 ssb_write32(dev, 0x200, 0x7ff);
66
67 /* Change Flush control reg */
68 ssb_write32(dev, 0x400, ssb_read32(dev, 0x400) & ~8);
69 ssb_read32(dev, 0x400);
70
71 /* Change Shim control reg */
72 ssb_write32(dev, 0x304, ssb_read32(dev, 0x304) & ~0x100);
73 ssb_read32(dev, 0x304);
74
75 udelay(1);
76
77 ssb_hcd_5354wa(dev);
78 }
79}
80
81/* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */
82static u32 __devinit ssb_hcd_init_chip(struct ssb_device *dev)
83{
84 u32 flags = 0;
85
86 if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV)
87 /* Put the device into host-mode. */
88 flags |= SSB_HCD_TMSLOW_HOSTMODE;
89
90 ssb_device_enable(dev, flags);
91
92 ssb_hcd_usb20wa(dev);
93
94 return flags;
95}
96
97static const struct usb_ehci_pdata ehci_pdata = {
98};
99
100static const struct usb_ohci_pdata ohci_pdata = {
101};
102
103static struct platform_device * __devinit
104ssb_hcd_create_pdev(struct ssb_device *dev, bool ohci, u32 addr, u32 len)
105{
106 struct platform_device *hci_dev;
107 struct resource hci_res[2];
108 int ret = -ENOMEM;
109
110 memset(hci_res, 0, sizeof(hci_res));
111
112 hci_res[0].start = addr;
113 hci_res[0].end = hci_res[0].start + len - 1;
114 hci_res[0].flags = IORESOURCE_MEM;
115
116 hci_res[1].start = dev->irq;
117 hci_res[1].flags = IORESOURCE_IRQ;
118
119 hci_dev = platform_device_alloc(ohci ? "ohci-platform" :
120 "ehci-platform" , 0);
121 if (!hci_dev)
122 return NULL;
123
124 hci_dev->dev.parent = dev->dev;
125 hci_dev->dev.dma_mask = &hci_dev->dev.coherent_dma_mask;
126
127 ret = platform_device_add_resources(hci_dev, hci_res,
128 ARRAY_SIZE(hci_res));
129 if (ret)
130 goto err_alloc;
131 if (ohci)
132 ret = platform_device_add_data(hci_dev, &ohci_pdata,
133 sizeof(ohci_pdata));
134 else
135 ret = platform_device_add_data(hci_dev, &ehci_pdata,
136 sizeof(ehci_pdata));
137 if (ret)
138 goto err_alloc;
139 ret = platform_device_add(hci_dev);
140 if (ret)
141 goto err_alloc;
142
143 return hci_dev;
144
145err_alloc:
146 platform_device_put(hci_dev);
147 return ERR_PTR(ret);
148}
149
150static int __devinit ssb_hcd_probe(struct ssb_device *dev,
151 const struct ssb_device_id *id)
152{
153 int err, tmp;
154 int start, len;
155 u16 chipid_top;
156 u16 coreid = dev->id.coreid;
157 struct ssb_hcd_device *usb_dev;
158
159 /* USBcores are only connected on embedded devices. */
160 chipid_top = (dev->bus->chip_id & 0xFF00);
161 if (chipid_top != 0x4700 && chipid_top != 0x5300)
162 return -ENODEV;
163
164 /* TODO: Probably need checks here; is the core connected? */
165
166 if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) ||
167 dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32)))
168 return -EOPNOTSUPP;
169
170 usb_dev = kzalloc(sizeof(struct ssb_hcd_device), GFP_KERNEL);
171 if (!usb_dev)
172 return -ENOMEM;
173
174 /* We currently always attach SSB_DEV_USB11_HOSTDEV
175 * as HOST OHCI. If we want to attach it as Client device,
176 * we must branch here and call into the (yet to
177 * be written) Client mode driver. Same for remove(). */
178 usb_dev->enable_flags = ssb_hcd_init_chip(dev);
179
180 tmp = ssb_read32(dev, SSB_ADMATCH0);
181
182 start = ssb_admatch_base(tmp);
183 len = (coreid == SSB_DEV_USB20_HOST) ? 0x800 : ssb_admatch_size(tmp);
184 usb_dev->ohci_dev = ssb_hcd_create_pdev(dev, true, start, len);
185 if (IS_ERR(usb_dev->ohci_dev)) {
186 err = PTR_ERR(usb_dev->ohci_dev);
187 goto err_free_usb_dev;
188 }
189
190 if (coreid == SSB_DEV_USB20_HOST) {
191 start = ssb_admatch_base(tmp) + 0x800; /* ehci core offset */
192 usb_dev->ehci_dev = ssb_hcd_create_pdev(dev, false, start, len);
193 if (IS_ERR(usb_dev->ehci_dev)) {
194 err = PTR_ERR(usb_dev->ehci_dev);
195 goto err_unregister_ohci_dev;
196 }
197 }
198
199 ssb_set_drvdata(dev, usb_dev);
200 return 0;
201
202err_unregister_ohci_dev:
203 platform_device_unregister(usb_dev->ohci_dev);
204err_free_usb_dev:
205 kfree(usb_dev);
206 return err;
207}
208
209static void __devexit ssb_hcd_remove(struct ssb_device *dev)
210{
211 struct ssb_hcd_device *usb_dev = ssb_get_drvdata(dev);
212 struct platform_device *ohci_dev = usb_dev->ohci_dev;
213 struct platform_device *ehci_dev = usb_dev->ehci_dev;
214
215 if (ohci_dev)
216 platform_device_unregister(ohci_dev);
217 if (ehci_dev)
218 platform_device_unregister(ehci_dev);
219
220 ssb_device_disable(dev, 0);
221}
222
223static void __devexit ssb_hcd_shutdown(struct ssb_device *dev)
224{
225 ssb_device_disable(dev, 0);
226}
227
228#ifdef CONFIG_PM
229
230static int ssb_hcd_suspend(struct ssb_device *dev, pm_message_t state)
231{
232 ssb_device_disable(dev, 0);
233
234 return 0;
235}
236
237static int ssb_hcd_resume(struct ssb_device *dev)
238{
239 struct ssb_hcd_device *usb_dev = ssb_get_drvdata(dev);
240
241 ssb_device_enable(dev, usb_dev->enable_flags);
242
243 return 0;
244}
245
246#else /* !CONFIG_PM */
247#define ssb_hcd_suspend NULL
248#define ssb_hcd_resume NULL
249#endif /* CONFIG_PM */
250
251static const struct ssb_device_id ssb_hcd_table[] __devinitconst = {
252 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV),
253 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV),
254 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV),
255 SSB_DEVTABLE_END
256};
257MODULE_DEVICE_TABLE(ssb, ssb_hcd_table);
258
259static struct ssb_driver ssb_hcd_driver = {
260 .name = KBUILD_MODNAME,
261 .id_table = ssb_hcd_table,
262 .probe = ssb_hcd_probe,
263 .remove = __devexit_p(ssb_hcd_remove),
264 .shutdown = ssb_hcd_shutdown,
265 .suspend = ssb_hcd_suspend,
266 .resume = ssb_hcd_resume,
267};
268
269static int __init ssb_hcd_init(void)
270{
271 return ssb_driver_register(&ssb_hcd_driver);
272}
273module_init(ssb_hcd_init);
274
275static void __exit ssb_hcd_exit(void)
276{
277 ssb_driver_unregister(&ssb_hcd_driver);
278}
279module_exit(ssb_hcd_exit);