aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-07 16:16:28 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-07 16:16:28 -0500
commit3e5b08cbbf78bedd316904ab0cf3b27119433ee5 (patch)
tree0365745c1b7441c1868551c024410c829c3accc6 /drivers/usb/host
parentda40d036fd716f0efb2917076220814b1e927ae1 (diff)
parent2af10844eb6ed104f9505bf3a7ba3ceb02264f31 (diff)
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (144 commits) USB: add support for Dream Cheeky DL100B Webmail Notifier (1d34:0004) USB: serial: ftdi_sio: add support for TIOCSERGETLSR USB: ehci-mxc: Setup portsc register prior to accessing OTG viewport USB: atmel_usba_udc: fix freeing irq in usba_udc_remove() usb: ehci-omap: fix tll channel enable mask usb: ohci-omap3: fix trivial typo USB: gadget: ci13xxx: don't assume that PAGE_SIZE is 4096 USB: gadget: ci13xxx: fix complete() callback for no_interrupt rq's USB: gadget: update ci13xxx to work with g_ether USB: gadgets: ci13xxx: fix probing of compiled-in gadget drivers Revert "USB: musb: pm: don't rely fully on clock support" Revert "USB: musb: blackfin: pm: make it work" USB: uas: Use GFP_NOIO instead of GFP_KERNEL in I/O submission path USB: uas: Ensure we only bind to a UAS interface USB: uas: Rename sense pipe and sense urb to status pipe and status urb USB: uas: Use kzalloc instead of kmalloc USB: uas: Fix up the Sense IU usb: musb: core: kill unneeded #include's DA8xx: assign name to MUSB IRQ resource usb: gadget: g_ncm added ... Manually fix up trivial conflicts in USB Kconfig changes in: arch/arm/mach-omap2/Kconfig arch/sh/Kconfig drivers/usb/Kconfig drivers/usb/host/ehci-hcd.c and annoying chip clock data conflicts in: arch/arm/mach-omap2/clock3xxx_data.c arch/arm/mach-omap2/clock44xx_data.c
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/Kconfig19
-rw-r--r--drivers/usb/host/ehci-atmel.c3
-rw-r--r--drivers/usb/host/ehci-dbg.c2
-rw-r--r--drivers/usb/host/ehci-hcd.c30
-rw-r--r--drivers/usb/host/ehci-msm.c345
-rw-r--r--drivers/usb/host/ehci-mxc.c29
-rw-r--r--drivers/usb/host/ehci-omap.c316
-rw-r--r--drivers/usb/host/ehci-pci.c39
-rw-r--r--drivers/usb/host/ehci-sched.c79
-rw-r--r--drivers/usb/host/ehci-sh.c243
-rw-r--r--drivers/usb/host/ehci-spear.c212
-rw-r--r--drivers/usb/host/ehci-vt8500.c172
-rw-r--r--drivers/usb/host/ehci-w90x900.c3
-rw-r--r--drivers/usb/host/ehci-xilinx-of.c1
-rw-r--r--drivers/usb/host/ehci.h1
-rw-r--r--drivers/usb/host/ohci-hcd.c5
-rw-r--r--drivers/usb/host/ohci-omap3.c2
-rw-r--r--drivers/usb/host/ohci-sh.c2
-rw-r--r--drivers/usb/host/ohci-spear.c240
-rw-r--r--drivers/usb/host/uhci-hcd.c2
-rw-r--r--drivers/usb/host/uhci-q.c12
-rw-r--r--drivers/usb/host/whci/hcd.c2
22 files changed, 1665 insertions, 94 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index f8970d151d2a..24046c0f5878 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -133,6 +133,25 @@ config USB_EHCI_MXC
133 ---help--- 133 ---help---
134 Variation of ARC USB block used in some Freescale chips. 134 Variation of ARC USB block used in some Freescale chips.
135 135
136config USB_EHCI_HCD_OMAP
137 bool "EHCI support for OMAP3 and later chips"
138 depends on USB_EHCI_HCD && ARCH_OMAP
139 default y
140 --- help ---
141 Enables support for the on-chip EHCI controller on
142 OMAP3 and later chips.
143
144config USB_EHCI_MSM
145 bool "Support for MSM on-chip EHCI USB controller"
146 depends on USB_EHCI_HCD && ARCH_MSM
147 select USB_EHCI_ROOT_HUB_TT
148 select USB_MSM_OTG_72K
149 ---help---
150 Enables support for the USB Host controller present on the
151 Qualcomm chipsets. Root Hub has inbuilt TT.
152 This driver depends on OTG driver for PHY initialization,
153 clock management, powering up VBUS, and power management.
154
136config USB_EHCI_HCD_PPC_OF 155config USB_EHCI_HCD_PPC_OF
137 bool "EHCI support for PPC USB controller on OF platform bus" 156 bool "EHCI support for PPC USB controller on OF platform bus"
138 depends on USB_EHCI_HCD && PPC_OF 157 depends on USB_EHCI_HCD && PPC_OF
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index 51bd0edf544f..d6a69d514a84 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -99,6 +99,7 @@ static const struct hc_driver ehci_atmel_hc_driver = {
99 .urb_enqueue = ehci_urb_enqueue, 99 .urb_enqueue = ehci_urb_enqueue,
100 .urb_dequeue = ehci_urb_dequeue, 100 .urb_dequeue = ehci_urb_dequeue,
101 .endpoint_disable = ehci_endpoint_disable, 101 .endpoint_disable = ehci_endpoint_disable,
102 .endpoint_reset = ehci_endpoint_reset,
102 103
103 /* scheduling support */ 104 /* scheduling support */
104 .get_frame_number = ehci_get_frame, 105 .get_frame_number = ehci_get_frame,
@@ -110,6 +111,8 @@ static const struct hc_driver ehci_atmel_hc_driver = {
110 .bus_resume = ehci_bus_resume, 111 .bus_resume = ehci_bus_resume,
111 .relinquish_port = ehci_relinquish_port, 112 .relinquish_port = ehci_relinquish_port,
112 .port_handed_over = ehci_port_handed_over, 113 .port_handed_over = ehci_port_handed_over,
114
115 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
113}; 116};
114 117
115static int __init ehci_atmel_drv_probe(struct platform_device *pdev) 118static int __init ehci_atmel_drv_probe(struct platform_device *pdev)
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 6e2599661b5b..3be238a24cc5 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -879,7 +879,7 @@ static int fill_buffer(struct debug_buffer *buf)
879 int ret = 0; 879 int ret = 0;
880 880
881 if (!buf->output_buf) 881 if (!buf->output_buf)
882 buf->output_buf = (char *)vmalloc(buf->alloc_size); 882 buf->output_buf = vmalloc(buf->alloc_size);
883 883
884 if (!buf->output_buf) { 884 if (!buf->output_buf) {
885 ret = -ENOMEM; 885 ret = -ENOMEM;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d0c8f7c03e05..6fee3cd58efe 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -114,6 +114,9 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us\n");
114 114
115#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) 115#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT)
116 116
117/* for ASPM quirk of ISOC on AMD SB800 */
118static struct pci_dev *amd_nb_dev;
119
117/*-------------------------------------------------------------------------*/ 120/*-------------------------------------------------------------------------*/
118 121
119#include "ehci.h" 122#include "ehci.h"
@@ -529,6 +532,11 @@ static void ehci_stop (struct usb_hcd *hcd)
529 spin_unlock_irq (&ehci->lock); 532 spin_unlock_irq (&ehci->lock);
530 ehci_mem_cleanup (ehci); 533 ehci_mem_cleanup (ehci);
531 534
535 if (amd_nb_dev) {
536 pci_dev_put(amd_nb_dev);
537 amd_nb_dev = NULL;
538 }
539
532#ifdef EHCI_STATS 540#ifdef EHCI_STATS
533 ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", 541 ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n",
534 ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, 542 ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim,
@@ -1166,12 +1174,17 @@ MODULE_LICENSE ("GPL");
1166#define PLATFORM_DRIVER ehci_mxc_driver 1174#define PLATFORM_DRIVER ehci_mxc_driver
1167#endif 1175#endif
1168 1176
1177#ifdef CONFIG_CPU_SUBTYPE_SH7786
1178#include "ehci-sh.c"
1179#define PLATFORM_DRIVER ehci_hcd_sh_driver
1180#endif
1181
1169#ifdef CONFIG_SOC_AU1200 1182#ifdef CONFIG_SOC_AU1200
1170#include "ehci-au1xxx.c" 1183#include "ehci-au1xxx.c"
1171#define PLATFORM_DRIVER ehci_hcd_au1xxx_driver 1184#define PLATFORM_DRIVER ehci_hcd_au1xxx_driver
1172#endif 1185#endif
1173 1186
1174#ifdef CONFIG_ARCH_OMAP3 1187#ifdef CONFIG_USB_EHCI_HCD_OMAP
1175#include "ehci-omap.c" 1188#include "ehci-omap.c"
1176#define PLATFORM_DRIVER ehci_hcd_omap_driver 1189#define PLATFORM_DRIVER ehci_hcd_omap_driver
1177#endif 1190#endif
@@ -1221,6 +1234,21 @@ MODULE_LICENSE ("GPL");
1221#define PLATFORM_DRIVER cns3xxx_ehci_driver 1234#define PLATFORM_DRIVER cns3xxx_ehci_driver
1222#endif 1235#endif
1223 1236
1237#ifdef CONFIG_ARCH_VT8500
1238#include "ehci-vt8500.c"
1239#define PLATFORM_DRIVER vt8500_ehci_driver
1240#endif
1241
1242#ifdef CONFIG_PLAT_SPEAR
1243#include "ehci-spear.c"
1244#define PLATFORM_DRIVER spear_ehci_hcd_driver
1245#endif
1246
1247#ifdef CONFIG_USB_EHCI_MSM
1248#include "ehci-msm.c"
1249#define PLATFORM_DRIVER ehci_msm_driver
1250#endif
1251
1224#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ 1252#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
1225 !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ 1253 !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
1226 !defined(XILINX_OF_PLATFORM_DRIVER) 1254 !defined(XILINX_OF_PLATFORM_DRIVER)
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
new file mode 100644
index 000000000000..413f4deca532
--- /dev/null
+++ b/drivers/usb/host/ehci-msm.c
@@ -0,0 +1,345 @@
1/* ehci-msm.c - HSUSB Host Controller Driver Implementation
2 *
3 * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
4 *
5 * Partly derived from ehci-fsl.c and ehci-hcd.c
6 * Copyright (c) 2000-2004 by David Brownell
7 * Copyright (c) 2005 MontaVista Software
8 *
9 * All source code in this file is licensed under the following license except
10 * where indicated.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License version 2 as published
14 * by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * See the GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, you can find it at http://www.fsf.org
23 */
24
25#include <linux/platform_device.h>
26#include <linux/clk.h>
27#include <linux/err.h>
28#include <linux/pm_runtime.h>
29
30#include <linux/usb/otg.h>
31#include <linux/usb/msm_hsusb_hw.h>
32
33#define MSM_USB_BASE (hcd->regs)
34
35static struct otg_transceiver *otg;
36
37/*
38 * ehci_run defined in drivers/usb/host/ehci-hcd.c reset the controller and
39 * the configuration settings in ehci_msm_reset vanish after controller is
40 * reset. Resetting the controler in ehci_run seems to be un-necessary
41 * provided HCD reset the controller before calling ehci_run. Most of the HCD
42 * do but some are not. So this function is same as ehci_run but we don't
43 * reset the controller here.
44 */
45static int ehci_msm_run(struct usb_hcd *hcd)
46{
47 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
48 u32 temp;
49 u32 hcc_params;
50
51 hcd->uses_new_polling = 1;
52
53 ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);
54 ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next);
55
56 /*
57 * hcc_params controls whether ehci->regs->segment must (!!!)
58 * be used; it constrains QH/ITD/SITD and QTD locations.
59 * pci_pool consistent memory always uses segment zero.
60 * streaming mappings for I/O buffers, like pci_map_single(),
61 * can return segments above 4GB, if the device allows.
62 *
63 * NOTE: the dma mask is visible through dma_supported(), so
64 * drivers can pass this info along ... like NETIF_F_HIGHDMA,
65 * Scsi_Host.highmem_io, and so forth. It's readonly to all
66 * host side drivers though.
67 */
68 hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
69 if (HCC_64BIT_ADDR(hcc_params))
70 ehci_writel(ehci, 0, &ehci->regs->segment);
71
72 /*
73 * Philips, Intel, and maybe others need CMD_RUN before the
74 * root hub will detect new devices (why?); NEC doesn't
75 */
76 ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
77 ehci->command |= CMD_RUN;
78 ehci_writel(ehci, ehci->command, &ehci->regs->command);
79 dbg_cmd(ehci, "init", ehci->command);
80
81 /*
82 * Start, enabling full USB 2.0 functionality ... usb 1.1 devices
83 * are explicitly handed to companion controller(s), so no TT is
84 * involved with the root hub. (Except where one is integrated,
85 * and there's no companion controller unless maybe for USB OTG.)
86 *
87 * Turning on the CF flag will transfer ownership of all ports
88 * from the companions to the EHCI controller. If any of the
89 * companions are in the middle of a port reset at the time, it
90 * could cause trouble. Write-locking ehci_cf_port_reset_rwsem
91 * guarantees that no resets are in progress. After we set CF,
92 * a short delay lets the hardware catch up; new resets shouldn't
93 * be started before the port switching actions could complete.
94 */
95 down_write(&ehci_cf_port_reset_rwsem);
96 hcd->state = HC_STATE_RUNNING;
97 ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
98 ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
99 usleep_range(5000, 5500);
100 up_write(&ehci_cf_port_reset_rwsem);
101 ehci->last_periodic_enable = ktime_get_real();
102
103 temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
104 ehci_info(ehci,
105 "USB %x.%x started, EHCI %x.%02x%s\n",
106 ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
107 temp >> 8, temp & 0xff,
108 ignore_oc ? ", overcurrent ignored" : "");
109
110 ehci_writel(ehci, INTR_MASK,
111 &ehci->regs->intr_enable); /* Turn On Interrupts */
112
113 /* GRR this is run-once init(), being done every time the HC starts.
114 * So long as they're part of class devices, we can't do it init()
115 * since the class device isn't created that early.
116 */
117 create_debug_files(ehci);
118 create_companion_file(ehci);
119
120 return 0;
121}
122
123static int ehci_msm_reset(struct usb_hcd *hcd)
124{
125 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
126 int retval;
127
128 ehci->caps = USB_CAPLENGTH;
129 ehci->regs = USB_CAPLENGTH +
130 HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
131
132 /* cache the data to minimize the chip reads*/
133 ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
134
135 hcd->has_tt = 1;
136 ehci->sbrn = HCD_USB2;
137
138 /* data structure init */
139 retval = ehci_init(hcd);
140 if (retval)
141 return retval;
142
143 retval = ehci_reset(ehci);
144 if (retval)
145 return retval;
146
147 /* bursts of unspecified length. */
148 writel(0, USB_AHBBURST);
149 /* Use the AHB transactor */
150 writel(0, USB_AHBMODE);
151 /* Disable streaming mode and select host mode */
152 writel(0x13, USB_USBMODE);
153
154 ehci_port_power(ehci, 1);
155 return 0;
156}
157
158static struct hc_driver msm_hc_driver = {
159 .description = hcd_name,
160 .product_desc = "Qualcomm On-Chip EHCI Host Controller",
161 .hcd_priv_size = sizeof(struct ehci_hcd),
162
163 /*
164 * generic hardware linkage
165 */
166 .irq = ehci_irq,
167 .flags = HCD_USB2 | HCD_MEMORY,
168
169 .reset = ehci_msm_reset,
170 .start = ehci_msm_run,
171
172 .stop = ehci_stop,
173 .shutdown = ehci_shutdown,
174
175 /*
176 * managing i/o requests and associated device resources
177 */
178 .urb_enqueue = ehci_urb_enqueue,
179 .urb_dequeue = ehci_urb_dequeue,
180 .endpoint_disable = ehci_endpoint_disable,
181 .endpoint_reset = ehci_endpoint_reset,
182 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
183
184 /*
185 * scheduling support
186 */
187 .get_frame_number = ehci_get_frame,
188
189 /*
190 * root hub support
191 */
192 .hub_status_data = ehci_hub_status_data,
193 .hub_control = ehci_hub_control,
194 .relinquish_port = ehci_relinquish_port,
195 .port_handed_over = ehci_port_handed_over,
196
197 /*
198 * PM support
199 */
200 .bus_suspend = ehci_bus_suspend,
201 .bus_resume = ehci_bus_resume,
202};
203
204static int ehci_msm_probe(struct platform_device *pdev)
205{
206 struct usb_hcd *hcd;
207 struct resource *res;
208 int ret;
209
210 dev_dbg(&pdev->dev, "ehci_msm proble\n");
211
212 hcd = usb_create_hcd(&msm_hc_driver, &pdev->dev, dev_name(&pdev->dev));
213 if (!hcd) {
214 dev_err(&pdev->dev, "Unable to create HCD\n");
215 return -ENOMEM;
216 }
217
218 hcd->irq = platform_get_irq(pdev, 0);
219 if (hcd->irq < 0) {
220 dev_err(&pdev->dev, "Unable to get IRQ resource\n");
221 ret = hcd->irq;
222 goto put_hcd;
223 }
224
225 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
226 if (!res) {
227 dev_err(&pdev->dev, "Unable to get memory resource\n");
228 ret = -ENODEV;
229 goto put_hcd;
230 }
231
232 hcd->rsrc_start = res->start;
233 hcd->rsrc_len = resource_size(res);
234 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
235 if (!hcd->regs) {
236 dev_err(&pdev->dev, "ioremap failed\n");
237 ret = -ENOMEM;
238 goto put_hcd;
239 }
240
241 /*
242 * OTG driver takes care of PHY initialization, clock management,
243 * powering up VBUS, mapping of registers address space and power
244 * management.
245 */
246 otg = otg_get_transceiver();
247 if (!otg) {
248 dev_err(&pdev->dev, "unable to find transceiver\n");
249 ret = -ENODEV;
250 goto unmap;
251 }
252
253 ret = otg_set_host(otg, &hcd->self);
254 if (ret < 0) {
255 dev_err(&pdev->dev, "unable to register with transceiver\n");
256 goto put_transceiver;
257 }
258
259 device_init_wakeup(&pdev->dev, 1);
260 /*
261 * OTG device parent of HCD takes care of putting
262 * hardware into low power mode.
263 */
264 pm_runtime_no_callbacks(&pdev->dev);
265 pm_runtime_enable(&pdev->dev);
266
267 return 0;
268
269put_transceiver:
270 otg_put_transceiver(otg);
271unmap:
272 iounmap(hcd->regs);
273put_hcd:
274 usb_put_hcd(hcd);
275
276 return ret;
277}
278
279static int __devexit ehci_msm_remove(struct platform_device *pdev)
280{
281 struct usb_hcd *hcd = platform_get_drvdata(pdev);
282
283 device_init_wakeup(&pdev->dev, 0);
284 pm_runtime_disable(&pdev->dev);
285 pm_runtime_set_suspended(&pdev->dev);
286
287 otg_set_host(otg, NULL);
288 otg_put_transceiver(otg);
289
290 usb_put_hcd(hcd);
291
292 return 0;
293}
294
295#ifdef CONFIG_PM
296static int ehci_msm_pm_suspend(struct device *dev)
297{
298 struct usb_hcd *hcd = dev_get_drvdata(dev);
299 bool wakeup = device_may_wakeup(dev);
300
301 dev_dbg(dev, "ehci-msm PM suspend\n");
302
303 /*
304 * EHCI helper function has also the same check before manipulating
305 * port wakeup flags. We do check here the same condition before
306 * calling the same helper function to avoid bringing hardware
307 * from Low power mode when there is no need for adjusting port
308 * wakeup flags.
309 */
310 if (hcd->self.root_hub->do_remote_wakeup && !wakeup) {
311 pm_runtime_resume(dev);
312 ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd),
313 wakeup);
314 }
315
316 return 0;
317}
318
319static int ehci_msm_pm_resume(struct device *dev)
320{
321 struct usb_hcd *hcd = dev_get_drvdata(dev);
322
323 dev_dbg(dev, "ehci-msm PM resume\n");
324 ehci_prepare_ports_for_controller_resume(hcd_to_ehci(hcd));
325
326 return 0;
327}
328#else
329#define ehci_msm_pm_suspend NULL
330#define ehci_msm_pm_resume NULL
331#endif
332
333static const struct dev_pm_ops ehci_msm_dev_pm_ops = {
334 .suspend = ehci_msm_pm_suspend,
335 .resume = ehci_msm_pm_resume,
336};
337
338static struct platform_driver ehci_msm_driver = {
339 .probe = ehci_msm_probe,
340 .remove = __devexit_p(ehci_msm_remove),
341 .driver = {
342 .name = "msm_hsusb_host",
343 .pm = &ehci_msm_dev_pm_ops,
344 },
345};
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index a22d2df769a9..fa59b26fc5bc 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -36,14 +36,8 @@ struct ehci_mxc_priv {
36static int ehci_mxc_setup(struct usb_hcd *hcd) 36static int ehci_mxc_setup(struct usb_hcd *hcd)
37{ 37{
38 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 38 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
39 struct device *dev = hcd->self.controller;
40 struct mxc_usbh_platform_data *pdata = dev_get_platdata(dev);
41 int retval; 39 int retval;
42 40
43 /* EHCI registers start at offset 0x100 */
44 ehci->caps = hcd->regs + 0x100;
45 ehci->regs = hcd->regs + 0x100 +
46 HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
47 dbg_hcs_params(ehci, "reset"); 41 dbg_hcs_params(ehci, "reset");
48 dbg_hcc_params(ehci, "reset"); 42 dbg_hcc_params(ehci, "reset");
49 43
@@ -65,12 +59,6 @@ static int ehci_mxc_setup(struct usb_hcd *hcd)
65 59
66 ehci_reset(ehci); 60 ehci_reset(ehci);
67 61
68 /* set up the PORTSCx register */
69 ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]);
70
71 /* is this really needed? */
72 msleep(10);
73
74 ehci_port_power(ehci, 0); 62 ehci_port_power(ehci, 0);
75 return 0; 63 return 0;
76} 64}
@@ -100,6 +88,7 @@ static const struct hc_driver ehci_mxc_hc_driver = {
100 .urb_enqueue = ehci_urb_enqueue, 88 .urb_enqueue = ehci_urb_enqueue,
101 .urb_dequeue = ehci_urb_dequeue, 89 .urb_dequeue = ehci_urb_dequeue,
102 .endpoint_disable = ehci_endpoint_disable, 90 .endpoint_disable = ehci_endpoint_disable,
91 .endpoint_reset = ehci_endpoint_reset,
103 92
104 /* 93 /*
105 * scheduling support 94 * scheduling support
@@ -115,6 +104,8 @@ static const struct hc_driver ehci_mxc_hc_driver = {
115 .bus_resume = ehci_bus_resume, 104 .bus_resume = ehci_bus_resume,
116 .relinquish_port = ehci_relinquish_port, 105 .relinquish_port = ehci_relinquish_port,
117 .port_handed_over = ehci_port_handed_over, 106 .port_handed_over = ehci_port_handed_over,
107
108 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
118}; 109};
119 110
120static int ehci_mxc_drv_probe(struct platform_device *pdev) 111static int ehci_mxc_drv_probe(struct platform_device *pdev)
@@ -125,6 +116,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
125 int irq, ret; 116 int irq, ret;
126 struct ehci_mxc_priv *priv; 117 struct ehci_mxc_priv *priv;
127 struct device *dev = &pdev->dev; 118 struct device *dev = &pdev->dev;
119 struct ehci_hcd *ehci;
128 120
129 dev_info(&pdev->dev, "initializing i.MX USB Controller\n"); 121 dev_info(&pdev->dev, "initializing i.MX USB Controller\n");
130 122
@@ -212,6 +204,19 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
212 if (ret < 0) 204 if (ret < 0)
213 goto err_init; 205 goto err_init;
214 206
207 ehci = hcd_to_ehci(hcd);
208
209 /* EHCI registers start at offset 0x100 */
210 ehci->caps = hcd->regs + 0x100;
211 ehci->regs = hcd->regs + 0x100 +
212 HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
213
214 /* set up the PORTSCx register */
215 ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]);
216
217 /* is this really needed? */
218 msleep(10);
219
215 /* Initialize the transceiver */ 220 /* Initialize the transceiver */
216 if (pdata->otg) { 221 if (pdata->otg) {
217 pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET; 222 pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET;
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 116ae280053a..680f2ef4e59f 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -1,11 +1,12 @@
1/* 1/*
2 * ehci-omap.c - driver for USBHOST on OMAP 34xx processor 2 * ehci-omap.c - driver for USBHOST on OMAP3/4 processors
3 * 3 *
4 * Bus Glue for OMAP34xx USBHOST 3 port EHCI controller 4 * Bus Glue for the EHCI controllers in OMAP3/4
5 * Tested on OMAP3430 ES2.0 SDP 5 * Tested on several OMAP3 boards, and OMAP4 Pandaboard
6 * 6 *
7 * Copyright (C) 2007-2008 Texas Instruments, Inc. 7 * Copyright (C) 2007-2010 Texas Instruments, Inc.
8 * Author: Vikram Pandita <vikram.pandita@ti.com> 8 * Author: Vikram Pandita <vikram.pandita@ti.com>
9 * Author: Anand Gadiyar <gadiyar@ti.com>
9 * 10 *
10 * Copyright (C) 2009 Nokia Corporation 11 * Copyright (C) 2009 Nokia Corporation
11 * Contact: Felipe Balbi <felipe.balbi@nokia.com> 12 * Contact: Felipe Balbi <felipe.balbi@nokia.com>
@@ -26,11 +27,14 @@
26 * along with this program; if not, write to the Free Software 27 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * 29 *
29 * TODO (last updated Feb 12, 2010): 30 * TODO (last updated Nov 21, 2010):
30 * - add kernel-doc 31 * - add kernel-doc
31 * - enable AUTOIDLE 32 * - enable AUTOIDLE
32 * - add suspend/resume 33 * - add suspend/resume
33 * - move workarounds to board-files 34 * - move workarounds to board-files
35 * - factor out code common to OHCI
36 * - add HSIC and TLL support
37 * - convert to use hwmod and runtime PM
34 */ 38 */
35 39
36#include <linux/platform_device.h> 40#include <linux/platform_device.h>
@@ -86,9 +90,9 @@
86#define OMAP_TLL_ULPI_SCRATCH_REGISTER(num) (0x816 + 0x100 * num) 90#define OMAP_TLL_ULPI_SCRATCH_REGISTER(num) (0x816 + 0x100 * num)
87 91
88#define OMAP_TLL_CHANNEL_COUNT 3 92#define OMAP_TLL_CHANNEL_COUNT 3
89#define OMAP_TLL_CHANNEL_1_EN_MASK (1 << 1) 93#define OMAP_TLL_CHANNEL_1_EN_MASK (1 << 0)
90#define OMAP_TLL_CHANNEL_2_EN_MASK (1 << 2) 94#define OMAP_TLL_CHANNEL_2_EN_MASK (1 << 1)
91#define OMAP_TLL_CHANNEL_3_EN_MASK (1 << 4) 95#define OMAP_TLL_CHANNEL_3_EN_MASK (1 << 2)
92 96
93/* UHH Register Set */ 97/* UHH Register Set */
94#define OMAP_UHH_REVISION (0x00) 98#define OMAP_UHH_REVISION (0x00)
@@ -114,6 +118,23 @@
114#define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9) 118#define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9)
115#define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10) 119#define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10)
116 120
121/* OMAP4-specific defines */
122#define OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR (3 << 2)
123#define OMAP4_UHH_SYSCONFIG_NOIDLE (1 << 2)
124
125#define OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR (3 << 4)
126#define OMAP4_UHH_SYSCONFIG_NOSTDBY (1 << 4)
127#define OMAP4_UHH_SYSCONFIG_SOFTRESET (1 << 0)
128
129#define OMAP4_P1_MODE_CLEAR (3 << 16)
130#define OMAP4_P1_MODE_TLL (1 << 16)
131#define OMAP4_P1_MODE_HSIC (3 << 16)
132#define OMAP4_P2_MODE_CLEAR (3 << 18)
133#define OMAP4_P2_MODE_TLL (1 << 18)
134#define OMAP4_P2_MODE_HSIC (3 << 18)
135
136#define OMAP_REV2_TLL_CHANNEL_COUNT 2
137
117#define OMAP_UHH_DEBUG_CSR (0x44) 138#define OMAP_UHH_DEBUG_CSR (0x44)
118 139
119/* EHCI Register Set */ 140/* EHCI Register Set */
@@ -127,6 +148,17 @@
127#define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 148#define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8
128#define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 149#define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0
129 150
151/* Values of UHH_REVISION - Note: these are not given in the TRM */
152#define OMAP_EHCI_REV1 0x00000010 /* OMAP3 */
153#define OMAP_EHCI_REV2 0x50700100 /* OMAP4 */
154
155#define is_omap_ehci_rev1(x) (x->omap_ehci_rev == OMAP_EHCI_REV1)
156#define is_omap_ehci_rev2(x) (x->omap_ehci_rev == OMAP_EHCI_REV2)
157
158#define is_ehci_phy_mode(x) (x == EHCI_HCD_OMAP_MODE_PHY)
159#define is_ehci_tll_mode(x) (x == EHCI_HCD_OMAP_MODE_TLL)
160#define is_ehci_hsic_mode(x) (x == EHCI_HCD_OMAP_MODE_HSIC)
161
130/*-------------------------------------------------------------------------*/ 162/*-------------------------------------------------------------------------*/
131 163
132static inline void ehci_omap_writel(void __iomem *base, u32 reg, u32 val) 164static inline void ehci_omap_writel(void __iomem *base, u32 reg, u32 val)
@@ -156,10 +188,14 @@ struct ehci_hcd_omap {
156 struct device *dev; 188 struct device *dev;
157 189
158 struct clk *usbhost_ick; 190 struct clk *usbhost_ick;
159 struct clk *usbhost2_120m_fck; 191 struct clk *usbhost_hs_fck;
160 struct clk *usbhost1_48m_fck; 192 struct clk *usbhost_fs_fck;
161 struct clk *usbtll_fck; 193 struct clk *usbtll_fck;
162 struct clk *usbtll_ick; 194 struct clk *usbtll_ick;
195 struct clk *xclk60mhsp1_ck;
196 struct clk *xclk60mhsp2_ck;
197 struct clk *utmi_p1_fck;
198 struct clk *utmi_p2_fck;
163 199
164 /* FIXME the following two workarounds are 200 /* FIXME the following two workarounds are
165 * board specific not silicon-specific so these 201 * board specific not silicon-specific so these
@@ -176,6 +212,9 @@ struct ehci_hcd_omap {
176 /* phy reset workaround */ 212 /* phy reset workaround */
177 int phy_reset; 213 int phy_reset;
178 214
215 /* IP revision */
216 u32 omap_ehci_rev;
217
179 /* desired phy_mode: TLL, PHY */ 218 /* desired phy_mode: TLL, PHY */
180 enum ehci_hcd_omap_mode port_mode[OMAP3_HS_USB_PORTS]; 219 enum ehci_hcd_omap_mode port_mode[OMAP3_HS_USB_PORTS];
181 220
@@ -191,13 +230,14 @@ struct ehci_hcd_omap {
191 230
192/*-------------------------------------------------------------------------*/ 231/*-------------------------------------------------------------------------*/
193 232
194static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask) 233static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask,
234 u8 tll_channel_count)
195{ 235{
196 unsigned reg; 236 unsigned reg;
197 int i; 237 int i;
198 238
199 /* Program the 3 TLL channels upfront */ 239 /* Program the 3 TLL channels upfront */
200 for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) { 240 for (i = 0; i < tll_channel_count; i++) {
201 reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); 241 reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i));
202 242
203 /* Disable AutoIdle, BitStuffing and use SDR Mode */ 243 /* Disable AutoIdle, BitStuffing and use SDR Mode */
@@ -217,7 +257,7 @@ static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask)
217 ehci_omap_writel(omap->tll_base, OMAP_TLL_SHARED_CONF, reg); 257 ehci_omap_writel(omap->tll_base, OMAP_TLL_SHARED_CONF, reg);
218 258
219 /* Enable channels now */ 259 /* Enable channels now */
220 for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) { 260 for (i = 0; i < tll_channel_count; i++) {
221 reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); 261 reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i));
222 262
223 /* Enable only the reg that is needed */ 263 /* Enable only the reg that is needed */
@@ -286,19 +326,19 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
286 } 326 }
287 clk_enable(omap->usbhost_ick); 327 clk_enable(omap->usbhost_ick);
288 328
289 omap->usbhost2_120m_fck = clk_get(omap->dev, "usbhost_120m_fck"); 329 omap->usbhost_hs_fck = clk_get(omap->dev, "hs_fck");
290 if (IS_ERR(omap->usbhost2_120m_fck)) { 330 if (IS_ERR(omap->usbhost_hs_fck)) {
291 ret = PTR_ERR(omap->usbhost2_120m_fck); 331 ret = PTR_ERR(omap->usbhost_hs_fck);
292 goto err_host_120m_fck; 332 goto err_host_120m_fck;
293 } 333 }
294 clk_enable(omap->usbhost2_120m_fck); 334 clk_enable(omap->usbhost_hs_fck);
295 335
296 omap->usbhost1_48m_fck = clk_get(omap->dev, "usbhost_48m_fck"); 336 omap->usbhost_fs_fck = clk_get(omap->dev, "fs_fck");
297 if (IS_ERR(omap->usbhost1_48m_fck)) { 337 if (IS_ERR(omap->usbhost_fs_fck)) {
298 ret = PTR_ERR(omap->usbhost1_48m_fck); 338 ret = PTR_ERR(omap->usbhost_fs_fck);
299 goto err_host_48m_fck; 339 goto err_host_48m_fck;
300 } 340 }
301 clk_enable(omap->usbhost1_48m_fck); 341 clk_enable(omap->usbhost_fs_fck);
302 342
303 if (omap->phy_reset) { 343 if (omap->phy_reset) {
304 /* Refer: ISSUE1 */ 344 /* Refer: ISSUE1 */
@@ -333,6 +373,80 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
333 } 373 }
334 clk_enable(omap->usbtll_ick); 374 clk_enable(omap->usbtll_ick);
335 375
376 omap->omap_ehci_rev = ehci_omap_readl(omap->uhh_base,
377 OMAP_UHH_REVISION);
378 dev_dbg(omap->dev, "OMAP UHH_REVISION 0x%x\n",
379 omap->omap_ehci_rev);
380
381 /*
382 * Enable per-port clocks as needed (newer controllers only).
383 * - External ULPI clock for PHY mode
384 * - Internal clocks for TLL and HSIC modes (TODO)
385 */
386 if (is_omap_ehci_rev2(omap)) {
387 switch (omap->port_mode[0]) {
388 case EHCI_HCD_OMAP_MODE_PHY:
389 omap->xclk60mhsp1_ck = clk_get(omap->dev,
390 "xclk60mhsp1_ck");
391 if (IS_ERR(omap->xclk60mhsp1_ck)) {
392 ret = PTR_ERR(omap->xclk60mhsp1_ck);
393 dev_err(omap->dev,
394 "Unable to get Port1 ULPI clock\n");
395 }
396
397 omap->utmi_p1_fck = clk_get(omap->dev,
398 "utmi_p1_gfclk");
399 if (IS_ERR(omap->utmi_p1_fck)) {
400 ret = PTR_ERR(omap->utmi_p1_fck);
401 dev_err(omap->dev,
402 "Unable to get utmi_p1_fck\n");
403 }
404
405 ret = clk_set_parent(omap->utmi_p1_fck,
406 omap->xclk60mhsp1_ck);
407 if (ret != 0) {
408 dev_err(omap->dev,
409 "Unable to set P1 f-clock\n");
410 }
411 break;
412 case EHCI_HCD_OMAP_MODE_TLL:
413 /* TODO */
414 default:
415 break;
416 }
417 switch (omap->port_mode[1]) {
418 case EHCI_HCD_OMAP_MODE_PHY:
419 omap->xclk60mhsp2_ck = clk_get(omap->dev,
420 "xclk60mhsp2_ck");
421 if (IS_ERR(omap->xclk60mhsp2_ck)) {
422 ret = PTR_ERR(omap->xclk60mhsp2_ck);
423 dev_err(omap->dev,
424 "Unable to get Port2 ULPI clock\n");
425 }
426
427 omap->utmi_p2_fck = clk_get(omap->dev,
428 "utmi_p2_gfclk");
429 if (IS_ERR(omap->utmi_p2_fck)) {
430 ret = PTR_ERR(omap->utmi_p2_fck);
431 dev_err(omap->dev,
432 "Unable to get utmi_p2_fck\n");
433 }
434
435 ret = clk_set_parent(omap->utmi_p2_fck,
436 omap->xclk60mhsp2_ck);
437 if (ret != 0) {
438 dev_err(omap->dev,
439 "Unable to set P2 f-clock\n");
440 }
441 break;
442 case EHCI_HCD_OMAP_MODE_TLL:
443 /* TODO */
444 default:
445 break;
446 }
447 }
448
449
336 /* perform TLL soft reset, and wait until reset is complete */ 450 /* perform TLL soft reset, and wait until reset is complete */
337 ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, 451 ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
338 OMAP_USBTLL_SYSCONFIG_SOFTRESET); 452 OMAP_USBTLL_SYSCONFIG_SOFTRESET);
@@ -360,12 +474,20 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
360 474
361 /* Put UHH in NoIdle/NoStandby mode */ 475 /* Put UHH in NoIdle/NoStandby mode */
362 reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); 476 reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG);
363 reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP 477 if (is_omap_ehci_rev1(omap)) {
364 | OMAP_UHH_SYSCONFIG_SIDLEMODE 478 reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP
365 | OMAP_UHH_SYSCONFIG_CACTIVITY 479 | OMAP_UHH_SYSCONFIG_SIDLEMODE
366 | OMAP_UHH_SYSCONFIG_MIDLEMODE); 480 | OMAP_UHH_SYSCONFIG_CACTIVITY
367 reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; 481 | OMAP_UHH_SYSCONFIG_MIDLEMODE);
482 reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE;
483
368 484
485 } else if (is_omap_ehci_rev2(omap)) {
486 reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR;
487 reg |= OMAP4_UHH_SYSCONFIG_NOIDLE;
488 reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR;
489 reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY;
490 }
369 ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); 491 ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg);
370 492
371 reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); 493 reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
@@ -376,40 +498,56 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
376 | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); 498 | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN);
377 reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; 499 reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN;
378 500
379 if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN) 501 if (is_omap_ehci_rev1(omap)) {
380 reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; 502 if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN)
381 if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN) 503 reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS;
382 reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; 504 if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN)
383 if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN) 505 reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS;
384 reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; 506 if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN)
385 507 reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS;
386 /* Bypass the TLL module for PHY mode operation */ 508
387 if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) { 509 /* Bypass the TLL module for PHY mode operation */
388 dev_dbg(omap->dev, "OMAP3 ES version <= ES2.1\n"); 510 if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) {
389 if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) || 511 dev_dbg(omap->dev, "OMAP3 ES version <= ES2.1\n");
390 (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) || 512 if (is_ehci_phy_mode(omap->port_mode[0]) ||
391 (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY)) 513 is_ehci_phy_mode(omap->port_mode[1]) ||
392 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; 514 is_ehci_phy_mode(omap->port_mode[2]))
393 else 515 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
394 reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; 516 else
395 } else { 517 reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
396 dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n"); 518 } else {
397 if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) 519 dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n");
398 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; 520 if (is_ehci_phy_mode(omap->port_mode[0]))
399 else if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) 521 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
400 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; 522 else if (is_ehci_tll_mode(omap->port_mode[0]))
401 523 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
402 if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) 524
403 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; 525 if (is_ehci_phy_mode(omap->port_mode[1]))
404 else if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) 526 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS;
405 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; 527 else if (is_ehci_tll_mode(omap->port_mode[1]))
406 528 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS;
407 if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY) 529
408 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; 530 if (is_ehci_phy_mode(omap->port_mode[2]))
409 else if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL) 531 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS;
410 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; 532 else if (is_ehci_tll_mode(omap->port_mode[2]))
533 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS;
534 }
535 } else if (is_omap_ehci_rev2(omap)) {
536 /* Clear port mode fields for PHY mode*/
537 reg &= ~OMAP4_P1_MODE_CLEAR;
538 reg &= ~OMAP4_P2_MODE_CLEAR;
539
540 if (is_ehci_tll_mode(omap->port_mode[0]))
541 reg |= OMAP4_P1_MODE_TLL;
542 else if (is_ehci_hsic_mode(omap->port_mode[0]))
543 reg |= OMAP4_P1_MODE_HSIC;
411 544
545 if (is_ehci_tll_mode(omap->port_mode[1]))
546 reg |= OMAP4_P2_MODE_TLL;
547 else if (is_ehci_hsic_mode(omap->port_mode[1]))
548 reg |= OMAP4_P2_MODE_HSIC;
412 } 549 }
550
413 ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); 551 ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg);
414 dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg); 552 dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg);
415 553
@@ -438,7 +576,7 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
438 tll_ch_mask |= OMAP_TLL_CHANNEL_3_EN_MASK; 576 tll_ch_mask |= OMAP_TLL_CHANNEL_3_EN_MASK;
439 577
440 /* Enable UTMI mode for required TLL channels */ 578 /* Enable UTMI mode for required TLL channels */
441 omap_usb_utmi_init(omap, tll_ch_mask); 579 omap_usb_utmi_init(omap, tll_ch_mask, OMAP_TLL_CHANNEL_COUNT);
442 } 580 }
443 581
444 if (omap->phy_reset) { 582 if (omap->phy_reset) {
@@ -464,6 +602,14 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
464 return 0; 602 return 0;
465 603
466err_sys_status: 604err_sys_status:
605 clk_disable(omap->utmi_p2_fck);
606 clk_put(omap->utmi_p2_fck);
607 clk_disable(omap->xclk60mhsp2_ck);
608 clk_put(omap->xclk60mhsp2_ck);
609 clk_disable(omap->utmi_p1_fck);
610 clk_put(omap->utmi_p1_fck);
611 clk_disable(omap->xclk60mhsp1_ck);
612 clk_put(omap->xclk60mhsp1_ck);
467 clk_disable(omap->usbtll_ick); 613 clk_disable(omap->usbtll_ick);
468 clk_put(omap->usbtll_ick); 614 clk_put(omap->usbtll_ick);
469 615
@@ -472,8 +618,8 @@ err_tll_ick:
472 clk_put(omap->usbtll_fck); 618 clk_put(omap->usbtll_fck);
473 619
474err_tll_fck: 620err_tll_fck:
475 clk_disable(omap->usbhost1_48m_fck); 621 clk_disable(omap->usbhost_fs_fck);
476 clk_put(omap->usbhost1_48m_fck); 622 clk_put(omap->usbhost_fs_fck);
477 623
478 if (omap->phy_reset) { 624 if (omap->phy_reset) {
479 if (gpio_is_valid(omap->reset_gpio_port[0])) 625 if (gpio_is_valid(omap->reset_gpio_port[0]))
@@ -484,8 +630,8 @@ err_tll_fck:
484 } 630 }
485 631
486err_host_48m_fck: 632err_host_48m_fck:
487 clk_disable(omap->usbhost2_120m_fck); 633 clk_disable(omap->usbhost_hs_fck);
488 clk_put(omap->usbhost2_120m_fck); 634 clk_put(omap->usbhost_hs_fck);
489 635
490err_host_120m_fck: 636err_host_120m_fck:
491 clk_disable(omap->usbhost_ick); 637 clk_disable(omap->usbhost_ick);
@@ -503,6 +649,8 @@ static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
503 649
504 /* Reset OMAP modules for insmod/rmmod to work */ 650 /* Reset OMAP modules for insmod/rmmod to work */
505 ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, 651 ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG,
652 is_omap_ehci_rev2(omap) ?
653 OMAP4_UHH_SYSCONFIG_SOFTRESET :
506 OMAP_UHH_SYSCONFIG_SOFTRESET); 654 OMAP_UHH_SYSCONFIG_SOFTRESET);
507 while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) 655 while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS)
508 & (1 << 0))) { 656 & (1 << 0))) {
@@ -550,16 +698,16 @@ static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
550 omap->usbhost_ick = NULL; 698 omap->usbhost_ick = NULL;
551 } 699 }
552 700
553 if (omap->usbhost1_48m_fck != NULL) { 701 if (omap->usbhost_fs_fck != NULL) {
554 clk_disable(omap->usbhost1_48m_fck); 702 clk_disable(omap->usbhost_fs_fck);
555 clk_put(omap->usbhost1_48m_fck); 703 clk_put(omap->usbhost_fs_fck);
556 omap->usbhost1_48m_fck = NULL; 704 omap->usbhost_fs_fck = NULL;
557 } 705 }
558 706
559 if (omap->usbhost2_120m_fck != NULL) { 707 if (omap->usbhost_hs_fck != NULL) {
560 clk_disable(omap->usbhost2_120m_fck); 708 clk_disable(omap->usbhost_hs_fck);
561 clk_put(omap->usbhost2_120m_fck); 709 clk_put(omap->usbhost_hs_fck);
562 omap->usbhost2_120m_fck = NULL; 710 omap->usbhost_hs_fck = NULL;
563 } 711 }
564 712
565 if (omap->usbtll_ick != NULL) { 713 if (omap->usbtll_ick != NULL) {
@@ -568,6 +716,32 @@ static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd)
568 omap->usbtll_ick = NULL; 716 omap->usbtll_ick = NULL;
569 } 717 }
570 718
719 if (is_omap_ehci_rev2(omap)) {
720 if (omap->xclk60mhsp1_ck != NULL) {
721 clk_disable(omap->xclk60mhsp1_ck);
722 clk_put(omap->xclk60mhsp1_ck);
723 omap->xclk60mhsp1_ck = NULL;
724 }
725
726 if (omap->utmi_p1_fck != NULL) {
727 clk_disable(omap->utmi_p1_fck);
728 clk_put(omap->utmi_p1_fck);
729 omap->utmi_p1_fck = NULL;
730 }
731
732 if (omap->xclk60mhsp2_ck != NULL) {
733 clk_disable(omap->xclk60mhsp2_ck);
734 clk_put(omap->xclk60mhsp2_ck);
735 omap->xclk60mhsp2_ck = NULL;
736 }
737
738 if (omap->utmi_p2_fck != NULL) {
739 clk_disable(omap->utmi_p2_fck);
740 clk_put(omap->utmi_p2_fck);
741 omap->utmi_p2_fck = NULL;
742 }
743 }
744
571 if (omap->phy_reset) { 745 if (omap->phy_reset) {
572 if (gpio_is_valid(omap->reset_gpio_port[0])) 746 if (gpio_is_valid(omap->reset_gpio_port[0]))
573 gpio_free(omap->reset_gpio_port[0]); 747 gpio_free(omap->reset_gpio_port[0]);
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 655f3c9f88bf..76179c39c0e3 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -22,6 +22,9 @@
22#error "This file is PCI bus glue. CONFIG_PCI must be defined." 22#error "This file is PCI bus glue. CONFIG_PCI must be defined."
23#endif 23#endif
24 24
25/* defined here to avoid adding to pci_ids.h for single instance use */
26#define PCI_DEVICE_ID_INTEL_CE4100_USB 0x2e70
27
25/*-------------------------------------------------------------------------*/ 28/*-------------------------------------------------------------------------*/
26 29
27/* called after powerup, by probe or system-pm "wakeup" */ 30/* called after powerup, by probe or system-pm "wakeup" */
@@ -41,6 +44,35 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev)
41 return 0; 44 return 0;
42} 45}
43 46
47static int ehci_quirk_amd_SB800(struct ehci_hcd *ehci)
48{
49 struct pci_dev *amd_smbus_dev;
50 u8 rev = 0;
51
52 amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL);
53 if (!amd_smbus_dev)
54 return 0;
55
56 pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);
57 if (rev < 0x40) {
58 pci_dev_put(amd_smbus_dev);
59 amd_smbus_dev = NULL;
60 return 0;
61 }
62
63 if (!amd_nb_dev)
64 amd_nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1510, NULL);
65 if (!amd_nb_dev)
66 ehci_err(ehci, "QUIRK: unable to get AMD NB device\n");
67
68 ehci_info(ehci, "QUIRK: Enable AMD SB800 L1 fix\n");
69
70 pci_dev_put(amd_smbus_dev);
71 amd_smbus_dev = NULL;
72
73 return 1;
74}
75
44/* called during probe() after chip reset completes */ 76/* called during probe() after chip reset completes */
45static int ehci_pci_setup(struct usb_hcd *hcd) 77static int ehci_pci_setup(struct usb_hcd *hcd)
46{ 78{
@@ -99,6 +131,9 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
99 /* cache this readonly data; minimize chip reads */ 131 /* cache this readonly data; minimize chip reads */
100 ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); 132 ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
101 133
134 if (ehci_quirk_amd_SB800(ehci))
135 ehci->amd_l1_fix = 1;
136
102 retval = ehci_halt(ehci); 137 retval = ehci_halt(ehci);
103 if (retval) 138 if (retval)
104 return retval; 139 return retval;
@@ -137,6 +172,10 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
137 ehci_info(ehci, "disable lpm for langwell/penwell\n"); 172 ehci_info(ehci, "disable lpm for langwell/penwell\n");
138 ehci->has_lpm = 0; 173 ehci->has_lpm = 0;
139 } 174 }
175 if (pdev->device == PCI_DEVICE_ID_INTEL_CE4100_USB) {
176 hcd->has_tt = 1;
177 tdi_reset(ehci);
178 }
140 break; 179 break;
141 case PCI_VENDOR_ID_TDI: 180 case PCI_VENDOR_ID_TDI:
142 if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { 181 if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index d9f78eb26572..aa46f57f9ec8 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1590,6 +1590,63 @@ itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd)
1590 *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); 1590 *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
1591} 1591}
1592 1592
1593#define AB_REG_BAR_LOW 0xe0
1594#define AB_REG_BAR_HIGH 0xe1
1595#define AB_INDX(addr) ((addr) + 0x00)
1596#define AB_DATA(addr) ((addr) + 0x04)
1597#define NB_PCIE_INDX_ADDR 0xe0
1598#define NB_PCIE_INDX_DATA 0xe4
1599#define NB_PIF0_PWRDOWN_0 0x01100012
1600#define NB_PIF0_PWRDOWN_1 0x01100013
1601
1602static void ehci_quirk_amd_L1(struct ehci_hcd *ehci, int disable)
1603{
1604 u32 addr, addr_low, addr_high, val;
1605
1606 outb_p(AB_REG_BAR_LOW, 0xcd6);
1607 addr_low = inb_p(0xcd7);
1608 outb_p(AB_REG_BAR_HIGH, 0xcd6);
1609 addr_high = inb_p(0xcd7);
1610 addr = addr_high << 8 | addr_low;
1611 outl_p(0x30, AB_INDX(addr));
1612 outl_p(0x40, AB_DATA(addr));
1613 outl_p(0x34, AB_INDX(addr));
1614 val = inl_p(AB_DATA(addr));
1615
1616 if (disable) {
1617 val &= ~0x8;
1618 val |= (1 << 4) | (1 << 9);
1619 } else {
1620 val |= 0x8;
1621 val &= ~((1 << 4) | (1 << 9));
1622 }
1623 outl_p(val, AB_DATA(addr));
1624
1625 if (amd_nb_dev) {
1626 addr = NB_PIF0_PWRDOWN_0;
1627 pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr);
1628 pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val);
1629 if (disable)
1630 val &= ~(0x3f << 7);
1631 else
1632 val |= 0x3f << 7;
1633
1634 pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val);
1635
1636 addr = NB_PIF0_PWRDOWN_1;
1637 pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr);
1638 pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val);
1639 if (disable)
1640 val &= ~(0x3f << 7);
1641 else
1642 val |= 0x3f << 7;
1643
1644 pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val);
1645 }
1646
1647 return;
1648}
1649
1593/* fit urb's itds into the selected schedule slot; activate as needed */ 1650/* fit urb's itds into the selected schedule slot; activate as needed */
1594static int 1651static int
1595itd_link_urb ( 1652itd_link_urb (
@@ -1616,6 +1673,12 @@ itd_link_urb (
1616 urb->interval, 1673 urb->interval,
1617 next_uframe >> 3, next_uframe & 0x7); 1674 next_uframe >> 3, next_uframe & 0x7);
1618 } 1675 }
1676
1677 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
1678 if (ehci->amd_l1_fix == 1)
1679 ehci_quirk_amd_L1(ehci, 1);
1680 }
1681
1619 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; 1682 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
1620 1683
1621 /* fill iTDs uframe by uframe */ 1684 /* fill iTDs uframe by uframe */
@@ -1740,6 +1803,11 @@ itd_complete (
1740 (void) disable_periodic(ehci); 1803 (void) disable_periodic(ehci);
1741 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; 1804 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
1742 1805
1806 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
1807 if (ehci->amd_l1_fix == 1)
1808 ehci_quirk_amd_L1(ehci, 0);
1809 }
1810
1743 if (unlikely(list_is_singular(&stream->td_list))) { 1811 if (unlikely(list_is_singular(&stream->td_list))) {
1744 ehci_to_hcd(ehci)->self.bandwidth_allocated 1812 ehci_to_hcd(ehci)->self.bandwidth_allocated
1745 -= stream->bandwidth; 1813 -= stream->bandwidth;
@@ -2025,6 +2093,12 @@ sitd_link_urb (
2025 (next_uframe >> 3) & (ehci->periodic_size - 1), 2093 (next_uframe >> 3) & (ehci->periodic_size - 1),
2026 stream->interval, hc32_to_cpu(ehci, stream->splits)); 2094 stream->interval, hc32_to_cpu(ehci, stream->splits));
2027 } 2095 }
2096
2097 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
2098 if (ehci->amd_l1_fix == 1)
2099 ehci_quirk_amd_L1(ehci, 1);
2100 }
2101
2028 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; 2102 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
2029 2103
2030 /* fill sITDs frame by frame */ 2104 /* fill sITDs frame by frame */
@@ -2125,6 +2199,11 @@ sitd_complete (
2125 (void) disable_periodic(ehci); 2199 (void) disable_periodic(ehci);
2126 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; 2200 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
2127 2201
2202 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
2203 if (ehci->amd_l1_fix == 1)
2204 ehci_quirk_amd_L1(ehci, 0);
2205 }
2206
2128 if (list_is_singular(&stream->td_list)) { 2207 if (list_is_singular(&stream->td_list)) {
2129 ehci_to_hcd(ehci)->self.bandwidth_allocated 2208 ehci_to_hcd(ehci)->self.bandwidth_allocated
2130 -= stream->bandwidth; 2209 -= stream->bandwidth;
diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c
new file mode 100644
index 000000000000..595f70f42b52
--- /dev/null
+++ b/drivers/usb/host/ehci-sh.c
@@ -0,0 +1,243 @@
1/*
2 * SuperH EHCI host controller driver
3 *
4 * Copyright (C) 2010 Paul Mundt
5 *
6 * Based on ohci-sh.c and ehci-atmel.c.
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/platform_device.h>
13#include <linux/clk.h>
14
15struct ehci_sh_priv {
16 struct clk *iclk, *fclk;
17 struct usb_hcd *hcd;
18};
19
20static int ehci_sh_reset(struct usb_hcd *hcd)
21{
22 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
23 int ret;
24
25 ehci->caps = hcd->regs;
26 ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci,
27 &ehci->caps->hc_capbase));
28
29 dbg_hcs_params(ehci, "reset");
30 dbg_hcc_params(ehci, "reset");
31
32 ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
33
34 ret = ehci_halt(ehci);
35 if (unlikely(ret))
36 return ret;
37
38 ret = ehci_init(hcd);
39 if (unlikely(ret))
40 return ret;
41
42 ehci->sbrn = 0x20;
43
44 ehci_reset(ehci);
45 ehci_port_power(ehci, 0);
46
47 return ret;
48}
49
50static const struct hc_driver ehci_sh_hc_driver = {
51 .description = hcd_name,
52 .product_desc = "SuperH EHCI",
53 .hcd_priv_size = sizeof(struct ehci_hcd),
54
55 /*
56 * generic hardware linkage
57 */
58 .irq = ehci_irq,
59 .flags = HCD_USB2 | HCD_MEMORY,
60
61 /*
62 * basic lifecycle operations
63 */
64 .reset = ehci_sh_reset,
65 .start = ehci_run,
66 .stop = ehci_stop,
67 .shutdown = ehci_shutdown,
68
69 /*
70 * managing i/o requests and associated device resources
71 */
72 .urb_enqueue = ehci_urb_enqueue,
73 .urb_dequeue = ehci_urb_dequeue,
74 .endpoint_disable = ehci_endpoint_disable,
75 .endpoint_reset = ehci_endpoint_reset,
76
77 /*
78 * scheduling support
79 */
80 .get_frame_number = ehci_get_frame,
81
82 /*
83 * root hub support
84 */
85 .hub_status_data = ehci_hub_status_data,
86 .hub_control = ehci_hub_control,
87
88#ifdef CONFIG_PM
89 .bus_suspend = ehci_bus_suspend,
90 .bus_resume = ehci_bus_resume,
91#endif
92
93 .relinquish_port = ehci_relinquish_port,
94 .port_handed_over = ehci_port_handed_over,
95 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
96};
97
98static int ehci_hcd_sh_probe(struct platform_device *pdev)
99{
100 const struct hc_driver *driver = &ehci_sh_hc_driver;
101 struct resource *res;
102 struct ehci_sh_priv *priv;
103 struct usb_hcd *hcd;
104 int irq, ret;
105
106 if (usb_disabled())
107 return -ENODEV;
108
109 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
110 if (!res) {
111 dev_err(&pdev->dev,
112 "Found HC with no register addr. Check %s setup!\n",
113 dev_name(&pdev->dev));
114 ret = -ENODEV;
115 goto fail_create_hcd;
116 }
117
118 irq = platform_get_irq(pdev, 0);
119 if (irq <= 0) {
120 dev_err(&pdev->dev,
121 "Found HC with no IRQ. Check %s setup!\n",
122 dev_name(&pdev->dev));
123 ret = -ENODEV;
124 goto fail_create_hcd;
125 }
126
127 /* initialize hcd */
128 hcd = usb_create_hcd(&ehci_sh_hc_driver, &pdev->dev,
129 dev_name(&pdev->dev));
130 if (!hcd) {
131 ret = -ENOMEM;
132 goto fail_create_hcd;
133 }
134
135 hcd->rsrc_start = res->start;
136 hcd->rsrc_len = resource_size(res);
137
138 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
139 driver->description)) {
140 dev_dbg(&pdev->dev, "controller already in use\n");
141 ret = -EBUSY;
142 goto fail_request_resource;
143 }
144
145 hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
146 if (hcd->regs == NULL) {
147 dev_dbg(&pdev->dev, "error mapping memory\n");
148 ret = -ENXIO;
149 goto fail_ioremap;
150 }
151
152 priv = kmalloc(sizeof(struct ehci_sh_priv), GFP_KERNEL);
153 if (!priv) {
154 dev_dbg(&pdev->dev, "error allocating priv data\n");
155 ret = -ENOMEM;
156 goto fail_alloc;
157 }
158
159 /* These are optional, we don't care if they fail */
160 priv->fclk = clk_get(&pdev->dev, "usb_fck");
161 if (IS_ERR(priv->fclk))
162 priv->fclk = NULL;
163
164 priv->iclk = clk_get(&pdev->dev, "usb_ick");
165 if (IS_ERR(priv->iclk))
166 priv->iclk = NULL;
167
168 clk_enable(priv->fclk);
169 clk_enable(priv->iclk);
170
171 ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
172 if (ret != 0) {
173 dev_err(&pdev->dev, "Failed to add hcd");
174 goto fail_add_hcd;
175 }
176
177 priv->hcd = hcd;
178 platform_set_drvdata(pdev, priv);
179
180 return ret;
181
182fail_add_hcd:
183 clk_disable(priv->iclk);
184 clk_disable(priv->fclk);
185
186 clk_put(priv->iclk);
187 clk_put(priv->fclk);
188
189 kfree(priv);
190fail_alloc:
191 iounmap(hcd->regs);
192fail_ioremap:
193 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
194fail_request_resource:
195 usb_put_hcd(hcd);
196fail_create_hcd:
197 dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), ret);
198
199 return ret;
200}
201
202static int __exit ehci_hcd_sh_remove(struct platform_device *pdev)
203{
204 struct ehci_sh_priv *priv = platform_get_drvdata(pdev);
205 struct usb_hcd *hcd = priv->hcd;
206
207 usb_remove_hcd(hcd);
208 iounmap(hcd->regs);
209 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
210 usb_put_hcd(hcd);
211 platform_set_drvdata(pdev, NULL);
212
213 clk_disable(priv->fclk);
214 clk_disable(priv->iclk);
215
216 clk_put(priv->fclk);
217 clk_put(priv->iclk);
218
219 kfree(priv);
220
221 return 0;
222}
223
224static void ehci_hcd_sh_shutdown(struct platform_device *pdev)
225{
226 struct ehci_sh_priv *priv = platform_get_drvdata(pdev);
227 struct usb_hcd *hcd = priv->hcd;
228
229 if (hcd->driver->shutdown)
230 hcd->driver->shutdown(hcd);
231}
232
233static struct platform_driver ehci_hcd_sh_driver = {
234 .probe = ehci_hcd_sh_probe,
235 .remove = __exit_p(ehci_hcd_sh_remove),
236 .shutdown = ehci_hcd_sh_shutdown,
237 .driver = {
238 .name = "sh_ehci",
239 .owner = THIS_MODULE,
240 },
241};
242
243MODULE_ALIAS("platform:sh_ehci");
diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c
new file mode 100644
index 000000000000..75c00873443d
--- /dev/null
+++ b/drivers/usb/host/ehci-spear.c
@@ -0,0 +1,212 @@
1/*
2* Driver for EHCI HCD on SPEAR SOC
3*
4* Copyright (C) 2010 ST Micro Electronics,
5* Deepak Sikri <deepak.sikri@st.com>
6*
7* Based on various ehci-*.c drivers
8*
9* This file is subject to the terms and conditions of the GNU General Public
10* License. See the file COPYING in the main directory of this archive for
11* more details.
12*/
13
14#include <linux/platform_device.h>
15#include <linux/clk.h>
16
17struct spear_ehci {
18 struct ehci_hcd ehci;
19 struct clk *clk;
20};
21
22#define to_spear_ehci(hcd) (struct spear_ehci *)hcd_to_ehci(hcd)
23
24static void spear_start_ehci(struct spear_ehci *ehci)
25{
26 clk_enable(ehci->clk);
27}
28
29static void spear_stop_ehci(struct spear_ehci *ehci)
30{
31 clk_disable(ehci->clk);
32}
33
34static int ehci_spear_setup(struct usb_hcd *hcd)
35{
36 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
37 int retval = 0;
38
39 /* registers start at offset 0x0 */
40 ehci->caps = hcd->regs;
41 ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci,
42 &ehci->caps->hc_capbase));
43 /* cache this readonly data; minimize chip reads */
44 ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
45 retval = ehci_halt(ehci);
46 if (retval)
47 return retval;
48
49 retval = ehci_init(hcd);
50 if (retval)
51 return retval;
52
53 ehci_reset(ehci);
54 ehci_port_power(ehci, 0);
55
56 return retval;
57}
58
59static const struct hc_driver ehci_spear_hc_driver = {
60 .description = hcd_name,
61 .product_desc = "SPEAr EHCI",
62 .hcd_priv_size = sizeof(struct spear_ehci),
63
64 /* generic hardware linkage */
65 .irq = ehci_irq,
66 .flags = HCD_MEMORY | HCD_USB2,
67
68 /* basic lifecycle operations */
69 .reset = ehci_spear_setup,
70 .start = ehci_run,
71 .stop = ehci_stop,
72 .shutdown = ehci_shutdown,
73
74 /* managing i/o requests and associated device resources */
75 .urb_enqueue = ehci_urb_enqueue,
76 .urb_dequeue = ehci_urb_dequeue,
77 .endpoint_disable = ehci_endpoint_disable,
78 .endpoint_reset = ehci_endpoint_reset,
79
80 /* scheduling support */
81 .get_frame_number = ehci_get_frame,
82
83 /* root hub support */
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 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
91};
92
93static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)
94{
95 struct usb_hcd *hcd ;
96 struct spear_ehci *ehci;
97 struct resource *res;
98 struct clk *usbh_clk;
99 const struct hc_driver *driver = &ehci_spear_hc_driver;
100 int *pdata = pdev->dev.platform_data;
101 int irq, retval;
102 char clk_name[20] = "usbh_clk";
103
104 if (pdata == NULL)
105 return -EFAULT;
106
107 if (usb_disabled())
108 return -ENODEV;
109
110 irq = platform_get_irq(pdev, 0);
111 if (irq < 0) {
112 retval = irq;
113 goto fail_irq_get;
114 }
115
116 if (*pdata >= 0)
117 sprintf(clk_name, "usbh.%01d_clk", *pdata);
118
119 usbh_clk = clk_get(NULL, clk_name);
120 if (IS_ERR(usbh_clk)) {
121 dev_err(&pdev->dev, "Error getting interface clock\n");
122 retval = PTR_ERR(usbh_clk);
123 goto fail_get_usbh_clk;
124 }
125
126 hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
127 if (!hcd) {
128 retval = -ENOMEM;
129 goto fail_create_hcd;
130 }
131
132 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
133 if (!res) {
134 retval = -ENODEV;
135 goto fail_request_resource;
136 }
137
138 hcd->rsrc_start = res->start;
139 hcd->rsrc_len = resource_size(res);
140 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
141 driver->description)) {
142 retval = -EBUSY;
143 goto fail_request_resource;
144 }
145
146 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
147 if (hcd->regs == NULL) {
148 dev_dbg(&pdev->dev, "error mapping memory\n");
149 retval = -ENOMEM;
150 goto fail_ioremap;
151 }
152
153 ehci = (struct spear_ehci *)hcd_to_ehci(hcd);
154 ehci->clk = usbh_clk;
155
156 spear_start_ehci(ehci);
157 retval = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED);
158 if (retval)
159 goto fail_add_hcd;
160
161 return retval;
162
163fail_add_hcd:
164 spear_stop_ehci(ehci);
165 iounmap(hcd->regs);
166fail_ioremap:
167 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
168fail_request_resource:
169 usb_put_hcd(hcd);
170fail_create_hcd:
171 clk_put(usbh_clk);
172fail_get_usbh_clk:
173fail_irq_get:
174 dev_err(&pdev->dev, "init fail, %d\n", retval);
175
176 return retval ;
177}
178
179static int spear_ehci_hcd_drv_remove(struct platform_device *pdev)
180{
181 struct usb_hcd *hcd = platform_get_drvdata(pdev);
182 struct spear_ehci *ehci_p = to_spear_ehci(hcd);
183
184 if (!hcd)
185 return 0;
186 if (in_interrupt())
187 BUG();
188 usb_remove_hcd(hcd);
189
190 if (ehci_p->clk)
191 spear_stop_ehci(ehci_p);
192 iounmap(hcd->regs);
193 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
194 usb_put_hcd(hcd);
195
196 if (ehci_p->clk)
197 clk_put(ehci_p->clk);
198
199 return 0;
200}
201
202static struct platform_driver spear_ehci_hcd_driver = {
203 .probe = spear_ehci_hcd_drv_probe,
204 .remove = spear_ehci_hcd_drv_remove,
205 .shutdown = usb_hcd_platform_shutdown,
206 .driver = {
207 .name = "spear-ehci",
208 .bus = &platform_bus_type
209 }
210};
211
212MODULE_ALIAS("platform:spear-ehci");
diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c
new file mode 100644
index 000000000000..20168062035a
--- /dev/null
+++ b/drivers/usb/host/ehci-vt8500.c
@@ -0,0 +1,172 @@
1/*
2 * drivers/usb/host/ehci-vt8500.c
3 *
4 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
5 *
6 * Based on ehci-au1xxx.c
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/platform_device.h>
20
21static int ehci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
22{
23 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
24 int rc = 0;
25
26 if (!udev->parent) /* udev is root hub itself, impossible */
27 rc = -1;
28 /* we only support lpm device connected to root hub yet */
29 if (ehci->has_lpm && !udev->parent->parent) {
30 rc = ehci_lpm_set_da(ehci, udev->devnum, udev->portnum);
31 if (!rc)
32 rc = ehci_lpm_check(ehci, udev->portnum);
33 }
34 return rc;
35}
36
37static const struct hc_driver vt8500_ehci_hc_driver = {
38 .description = hcd_name,
39 .product_desc = "VT8500 EHCI",
40 .hcd_priv_size = sizeof(struct ehci_hcd),
41
42 /*
43 * generic hardware linkage
44 */
45 .irq = ehci_irq,
46 .flags = HCD_MEMORY | HCD_USB2,
47
48 /*
49 * basic lifecycle operations
50 */
51 .reset = ehci_init,
52 .start = ehci_run,
53 .stop = ehci_stop,
54 .shutdown = ehci_shutdown,
55
56 /*
57 * managing i/o requests and associated device resources
58 */
59 .urb_enqueue = ehci_urb_enqueue,
60 .urb_dequeue = ehci_urb_dequeue,
61 .endpoint_disable = ehci_endpoint_disable,
62 .endpoint_reset = ehci_endpoint_reset,
63
64 /*
65 * scheduling support
66 */
67 .get_frame_number = ehci_get_frame,
68
69 /*
70 * root hub support
71 */
72 .hub_status_data = ehci_hub_status_data,
73 .hub_control = ehci_hub_control,
74 .bus_suspend = ehci_bus_suspend,
75 .bus_resume = ehci_bus_resume,
76 .relinquish_port = ehci_relinquish_port,
77 .port_handed_over = ehci_port_handed_over,
78
79 /*
80 * call back when device connected and addressed
81 */
82 .update_device = ehci_update_device,
83
84 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
85};
86
87static int vt8500_ehci_drv_probe(struct platform_device *pdev)
88{
89 struct usb_hcd *hcd;
90 struct ehci_hcd *ehci;
91 struct resource *res;
92 int ret;
93
94 if (usb_disabled())
95 return -ENODEV;
96
97 if (pdev->resource[1].flags != IORESOURCE_IRQ) {
98 pr_debug("resource[1] is not IORESOURCE_IRQ");
99 return -ENOMEM;
100 }
101 hcd = usb_create_hcd(&vt8500_ehci_hc_driver, &pdev->dev, "VT8500");
102 if (!hcd)
103 return -ENOMEM;
104
105 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
106 hcd->rsrc_start = res->start;
107 hcd->rsrc_len = resource_size(res);
108
109 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
110 pr_debug("request_mem_region failed");
111 ret = -EBUSY;
112 goto err1;
113 }
114
115 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
116 if (!hcd->regs) {
117 pr_debug("ioremap failed");
118 ret = -ENOMEM;
119 goto err2;
120 }
121
122 ehci = hcd_to_ehci(hcd);
123 ehci->caps = hcd->regs;
124 ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase));
125
126 dbg_hcs_params(ehci, "reset");
127 dbg_hcc_params(ehci, "reset");
128
129 /* cache this readonly data; minimize chip reads */
130 ehci->hcs_params = readl(&ehci->caps->hcs_params);
131
132 ehci_port_power(ehci, 1);
133
134 ret = usb_add_hcd(hcd, pdev->resource[1].start,
135 IRQF_DISABLED | IRQF_SHARED);
136 if (ret == 0) {
137 platform_set_drvdata(pdev, hcd);
138 return ret;
139 }
140
141 iounmap(hcd->regs);
142err2:
143 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
144err1:
145 usb_put_hcd(hcd);
146 return ret;
147}
148
149static int vt8500_ehci_drv_remove(struct platform_device *pdev)
150{
151 struct usb_hcd *hcd = platform_get_drvdata(pdev);
152
153 usb_remove_hcd(hcd);
154 iounmap(hcd->regs);
155 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
156 usb_put_hcd(hcd);
157 platform_set_drvdata(pdev, NULL);
158
159 return 0;
160}
161
162static struct platform_driver vt8500_ehci_driver = {
163 .probe = vt8500_ehci_drv_probe,
164 .remove = vt8500_ehci_drv_remove,
165 .shutdown = usb_hcd_platform_shutdown,
166 .driver = {
167 .name = "vt8500-ehci",
168 .owner = THIS_MODULE,
169 }
170};
171
172MODULE_ALIAS("platform:vt8500-ehci");
diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c
index cfa21ea20f82..6bc35809a5c6 100644
--- a/drivers/usb/host/ehci-w90x900.c
+++ b/drivers/usb/host/ehci-w90x900.c
@@ -130,6 +130,7 @@ static const struct hc_driver ehci_w90x900_hc_driver = {
130 .urb_enqueue = ehci_urb_enqueue, 130 .urb_enqueue = ehci_urb_enqueue,
131 .urb_dequeue = ehci_urb_dequeue, 131 .urb_dequeue = ehci_urb_dequeue,
132 .endpoint_disable = ehci_endpoint_disable, 132 .endpoint_disable = ehci_endpoint_disable,
133 .endpoint_reset = ehci_endpoint_reset,
133 134
134 /* 135 /*
135 * scheduling support 136 * scheduling support
@@ -147,6 +148,8 @@ static const struct hc_driver ehci_w90x900_hc_driver = {
147#endif 148#endif
148 .relinquish_port = ehci_relinquish_port, 149 .relinquish_port = ehci_relinquish_port,
149 .port_handed_over = ehci_port_handed_over, 150 .port_handed_over = ehci_port_handed_over,
151
152 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
150}; 153};
151 154
152static int __devinit ehci_w90x900_probe(struct platform_device *pdev) 155static int __devinit ehci_w90x900_probe(struct platform_device *pdev)
diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c
index 6c8076ad821d..e8f4f36fdf0b 100644
--- a/drivers/usb/host/ehci-xilinx-of.c
+++ b/drivers/usb/host/ehci-xilinx-of.c
@@ -117,6 +117,7 @@ static const struct hc_driver ehci_xilinx_of_hc_driver = {
117 .urb_enqueue = ehci_urb_enqueue, 117 .urb_enqueue = ehci_urb_enqueue,
118 .urb_dequeue = ehci_urb_dequeue, 118 .urb_dequeue = ehci_urb_dequeue,
119 .endpoint_disable = ehci_endpoint_disable, 119 .endpoint_disable = ehci_endpoint_disable,
120 .endpoint_reset = ehci_endpoint_reset,
120 121
121 /* 122 /*
122 * scheduling support 123 * scheduling support
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index ba8eab366b82..799ac16a54b4 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -131,6 +131,7 @@ struct ehci_hcd { /* one per controller */
131 unsigned has_amcc_usb23:1; 131 unsigned has_amcc_usb23:1;
132 unsigned need_io_watchdog:1; 132 unsigned need_io_watchdog:1;
133 unsigned broken_periodic:1; 133 unsigned broken_periodic:1;
134 unsigned amd_l1_fix:1;
134 unsigned fs_i_thresh:1; /* Intel iso scheduling */ 135 unsigned fs_i_thresh:1; /* Intel iso scheduling */
135 unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ 136 unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/
136 137
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 5cb6731ba443..9751647665df 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1081,6 +1081,11 @@ MODULE_LICENSE ("GPL");
1081#define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver 1081#define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver
1082#endif 1082#endif
1083 1083
1084#ifdef CONFIG_PLAT_SPEAR
1085#include "ohci-spear.c"
1086#define PLATFORM_DRIVER spear_ohci_hcd_driver
1087#endif
1088
1084#ifdef CONFIG_PPC_PS3 1089#ifdef CONFIG_PPC_PS3
1085#include "ohci-ps3.c" 1090#include "ohci-ps3.c"
1086#define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver 1091#define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index 2cc8a504b18c..a37d5993e4e3 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -648,7 +648,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev)
648 648
649 ret = omap3_start_ohci(omap, hcd); 649 ret = omap3_start_ohci(omap, hcd);
650 if (ret) { 650 if (ret) {
651 dev_dbg(&pdev->dev, "failed to start ehci\n"); 651 dev_dbg(&pdev->dev, "failed to start ohci\n");
652 goto err_start; 652 goto err_start;
653 } 653 }
654 654
diff --git a/drivers/usb/host/ohci-sh.c b/drivers/usb/host/ohci-sh.c
index 0b35d22cc70e..f47867ff78c7 100644
--- a/drivers/usb/host/ohci-sh.c
+++ b/drivers/usb/host/ohci-sh.c
@@ -109,7 +109,7 @@ static int ohci_hcd_sh_probe(struct platform_device *pdev)
109 hcd->regs = (void __iomem *)res->start; 109 hcd->regs = (void __iomem *)res->start;
110 hcd->rsrc_start = res->start; 110 hcd->rsrc_start = res->start;
111 hcd->rsrc_len = resource_size(res); 111 hcd->rsrc_len = resource_size(res);
112 ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); 112 ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
113 if (ret != 0) { 113 if (ret != 0) {
114 err("Failed to add hcd"); 114 err("Failed to add hcd");
115 usb_put_hcd(hcd); 115 usb_put_hcd(hcd);
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c
new file mode 100644
index 000000000000..4fd4bea9ac7a
--- /dev/null
+++ b/drivers/usb/host/ohci-spear.c
@@ -0,0 +1,240 @@
1/*
2* OHCI HCD (Host Controller Driver) for USB.
3*
4* Copyright (C) 2010 ST Microelectronics.
5* Deepak Sikri<deepak.sikri@st.com>
6*
7* Based on various ohci-*.c drivers
8*
9* This file is licensed under the terms of the GNU General Public
10* License version 2. This program is licensed "as is" without any
11* warranty of any kind, whether express or implied.
12*/
13
14#include <linux/signal.h>
15#include <linux/platform_device.h>
16#include <linux/clk.h>
17
18struct spear_ohci {
19 struct ohci_hcd ohci;
20 struct clk *clk;
21};
22
23#define to_spear_ohci(hcd) (struct spear_ohci *)hcd_to_ohci(hcd)
24
25static void spear_start_ohci(struct spear_ohci *ohci)
26{
27 clk_enable(ohci->clk);
28}
29
30static void spear_stop_ohci(struct spear_ohci *ohci)
31{
32 clk_disable(ohci->clk);
33}
34
35static int __devinit ohci_spear_start(struct usb_hcd *hcd)
36{
37 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
38 int ret;
39
40 ret = ohci_init(ohci);
41 if (ret < 0)
42 return ret;
43 ohci->regs = hcd->regs;
44
45 ret = ohci_run(ohci);
46 if (ret < 0) {
47 dev_err(hcd->self.controller, "can't start\n");
48 ohci_stop(hcd);
49 return ret;
50 }
51
52 create_debug_files(ohci);
53
54#ifdef DEBUG
55 ohci_dump(ohci, 1);
56#endif
57 return 0;
58}
59
60static const struct hc_driver ohci_spear_hc_driver = {
61 .description = hcd_name,
62 .product_desc = "SPEAr OHCI",
63 .hcd_priv_size = sizeof(struct spear_ohci),
64
65 /* generic hardware linkage */
66 .irq = ohci_irq,
67 .flags = HCD_USB11 | HCD_MEMORY,
68
69 /* basic lifecycle operations */
70 .start = ohci_spear_start,
71 .stop = ohci_stop,
72 .shutdown = ohci_shutdown,
73#ifdef CONFIG_PM
74 .bus_suspend = ohci_bus_suspend,
75 .bus_resume = ohci_bus_resume,
76#endif
77
78 /* managing i/o requests and associated device resources */
79 .urb_enqueue = ohci_urb_enqueue,
80 .urb_dequeue = ohci_urb_dequeue,
81 .endpoint_disable = ohci_endpoint_disable,
82
83 /* scheduling support */
84 .get_frame_number = ohci_get_frame,
85
86 /* root hub support */
87 .hub_status_data = ohci_hub_status_data,
88 .hub_control = ohci_hub_control,
89
90 .start_port_reset = ohci_start_port_reset,
91};
92
93static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
94{
95 const struct hc_driver *driver = &ohci_spear_hc_driver;
96 struct usb_hcd *hcd = NULL;
97 struct clk *usbh_clk;
98 struct spear_ohci *ohci_p;
99 struct resource *res;
100 int retval, irq;
101 int *pdata = pdev->dev.platform_data;
102 char clk_name[20] = "usbh_clk";
103
104 if (pdata == NULL)
105 return -EFAULT;
106
107 irq = platform_get_irq(pdev, 0);
108 if (irq < 0) {
109 retval = irq;
110 goto fail_irq_get;
111 }
112
113 if (*pdata >= 0)
114 sprintf(clk_name, "usbh.%01d_clk", *pdata);
115
116 usbh_clk = clk_get(NULL, clk_name);
117 if (IS_ERR(usbh_clk)) {
118 dev_err(&pdev->dev, "Error getting interface clock\n");
119 retval = PTR_ERR(usbh_clk);
120 goto fail_get_usbh_clk;
121 }
122
123 hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
124 if (!hcd) {
125 retval = -ENOMEM;
126 goto fail_create_hcd;
127 }
128
129 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
130 if (!res) {
131 retval = -ENODEV;
132 goto fail_request_resource;
133 }
134
135 hcd->rsrc_start = pdev->resource[0].start;
136 hcd->rsrc_len = resource_size(res);
137 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
138 dev_dbg(&pdev->dev, "request_mem_region failed\n");
139 retval = -EBUSY;
140 goto fail_request_resource;
141 }
142
143 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
144 if (!hcd->regs) {
145 dev_dbg(&pdev->dev, "ioremap failed\n");
146 retval = -ENOMEM;
147 goto fail_ioremap;
148 }
149
150 ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
151 ohci_p->clk = usbh_clk;
152 spear_start_ohci(ohci_p);
153 ohci_hcd_init(hcd_to_ohci(hcd));
154
155 retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), IRQF_DISABLED);
156 if (retval == 0)
157 return retval;
158
159 spear_stop_ohci(ohci_p);
160 iounmap(hcd->regs);
161fail_ioremap:
162 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
163fail_request_resource:
164 usb_put_hcd(hcd);
165fail_create_hcd:
166 clk_put(usbh_clk);
167fail_get_usbh_clk:
168fail_irq_get:
169 dev_err(&pdev->dev, "init fail, %d\n", retval);
170
171 return retval;
172}
173
174static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
175{
176 struct usb_hcd *hcd = platform_get_drvdata(pdev);
177 struct spear_ohci *ohci_p = to_spear_ohci(hcd);
178
179 usb_remove_hcd(hcd);
180 if (ohci_p->clk)
181 spear_stop_ohci(ohci_p);
182
183 iounmap(hcd->regs);
184 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
185 usb_put_hcd(hcd);
186
187 if (ohci_p->clk)
188 clk_put(ohci_p->clk);
189 platform_set_drvdata(pdev, NULL);
190 return 0;
191}
192
193#if defined(CONFIG_PM)
194static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,
195 pm_message_t message)
196{
197 struct usb_hcd *hcd = platform_get_drvdata(dev);
198 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
199 struct spear_ohci *ohci_p = to_spear_ohci(hcd);
200
201 if (time_before(jiffies, ohci->next_statechange))
202 msleep(5);
203 ohci->next_statechange = jiffies;
204
205 spear_stop_ohci(ohci_p);
206 ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
207 return 0;
208}
209
210static int spear_ohci_hcd_drv_resume(struct platform_device *dev)
211{
212 struct usb_hcd *hcd = platform_get_drvdata(dev);
213 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
214 struct spear_ohci *ohci_p = to_spear_ohci(hcd);
215
216 if (time_before(jiffies, ohci->next_statechange))
217 msleep(5);
218 ohci->next_statechange = jiffies;
219
220 spear_start_ohci(ohci_p);
221 ohci_finish_controller_resume(hcd);
222 return 0;
223}
224#endif
225
226/* Driver definition to register with the platform bus */
227static struct platform_driver spear_ohci_hcd_driver = {
228 .probe = spear_ohci_hcd_drv_probe,
229 .remove = spear_ohci_hcd_drv_remove,
230#ifdef CONFIG_PM
231 .suspend = spear_ohci_hcd_drv_suspend,
232 .resume = spear_ohci_hcd_drv_resume,
233#endif
234 .driver = {
235 .owner = THIS_MODULE,
236 .name = "spear-ohci",
237 },
238};
239
240MODULE_ALIAS("platform:spear-ohci");
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index f52d04db28f4..cee867829ec9 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -569,7 +569,7 @@ static int uhci_init(struct usb_hcd *hcd)
569 */ 569 */
570static void uhci_shutdown(struct pci_dev *pdev) 570static void uhci_shutdown(struct pci_dev *pdev)
571{ 571{
572 struct usb_hcd *hcd = (struct usb_hcd *) pci_get_drvdata(pdev); 572 struct usb_hcd *hcd = pci_get_drvdata(pdev);
573 573
574 uhci_hc_died(hcd_to_uhci(hcd)); 574 uhci_hc_died(hcd_to_uhci(hcd));
575} 575}
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 2090b45eb606..af77abb5c68b 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -29,7 +29,7 @@ static void uhci_set_next_interrupt(struct uhci_hcd *uhci)
29{ 29{
30 if (uhci->is_stopped) 30 if (uhci->is_stopped)
31 mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies); 31 mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
32 uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC); 32 uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC);
33} 33}
34 34
35static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci) 35static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci)
@@ -195,7 +195,9 @@ static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci,
195 } else { 195 } else {
196 struct uhci_td *ntd; 196 struct uhci_td *ntd;
197 197
198 ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); 198 ntd = list_entry(td->fl_list.next,
199 struct uhci_td,
200 fl_list);
199 uhci->frame[td->frame] = LINK_TO_TD(ntd); 201 uhci->frame[td->frame] = LINK_TO_TD(ntd);
200 uhci->frame_cpu[td->frame] = ntd; 202 uhci->frame_cpu[td->frame] = ntd;
201 } 203 }
@@ -728,7 +730,7 @@ static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci,
728 730
729 urbp->urb = urb; 731 urbp->urb = urb;
730 urb->hcpriv = urbp; 732 urb->hcpriv = urbp;
731 733
732 INIT_LIST_HEAD(&urbp->node); 734 INIT_LIST_HEAD(&urbp->node);
733 INIT_LIST_HEAD(&urbp->td_list); 735 INIT_LIST_HEAD(&urbp->td_list);
734 736
@@ -846,7 +848,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
846 848
847 /* Alternate Data0/1 (start with Data1) */ 849 /* Alternate Data0/1 (start with Data1) */
848 destination ^= TD_TOKEN_TOGGLE; 850 destination ^= TD_TOKEN_TOGGLE;
849 851
850 uhci_add_td_to_urbp(td, urbp); 852 uhci_add_td_to_urbp(td, urbp);
851 uhci_fill_td(td, status, destination | uhci_explen(pktsze), 853 uhci_fill_td(td, status, destination | uhci_explen(pktsze),
852 data); 854 data);
@@ -857,7 +859,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb,
857 } 859 }
858 860
859 /* 861 /*
860 * Build the final TD for control status 862 * Build the final TD for control status
861 */ 863 */
862 td = uhci_alloc_td(uhci); 864 td = uhci_alloc_td(uhci);
863 if (!td) 865 if (!td)
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c
index 72b6892fda67..9546f6cd01f0 100644
--- a/drivers/usb/host/whci/hcd.c
+++ b/drivers/usb/host/whci/hcd.c
@@ -356,7 +356,7 @@ static void __exit whci_hc_driver_exit(void)
356module_exit(whci_hc_driver_exit); 356module_exit(whci_hc_driver_exit);
357 357
358/* PCI device ID's that we handle (so it gets loaded) */ 358/* PCI device ID's that we handle (so it gets loaded) */
359static struct pci_device_id whci_hcd_id_table[] = { 359static struct pci_device_id __used whci_hcd_id_table[] = {
360 { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) }, 360 { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) },
361 { /* empty last entry */ } 361 { /* empty last entry */ }
362}; 362};