[gemini]: upgrade to 3.9-rc4, disable unsupported boards
[openwrt.git] / target / linux / gemini / patches / 130-usb-ehci-gemini-fot2gxx-support.patch
1 --- /dev/null
2 +++ b/drivers/usb/host/ehci-fotg2xx.c
3 @@ -0,0 +1,465 @@
4 +/*
5 + *  EHCI Host Controller driver
6 + *
7 + *  Copyright (C) 2006 Sony Computer Entertainment Inc.
8 + *  Copyright 2006 Sony Corp.
9 + *
10 + *  This program is free software; you can redistribute it and/or modify
11 + *  it under the terms of the GNU General Public License as published by
12 + *  the Free Software Foundation; version 2 of the License.
13 + */
14 +
15 +#include <linux/platform_device.h>
16 +#include <mach/hardware.h>
17 +
18 +#define otg_set(port, bits) writel(readl(hcd->regs + port) | bits, hcd->regs + port)
19 +
20 +#define otg_clear(port, bits) writel(readl(hcd->regs + port) & ~bits, hcd->regs + port)
21 +
22 +#define GLOBAL_ISR                     0xC0
23 +#define GLOBAL_ICR                     0xC4
24 +
25 +#define HCD_MISC                       0x40
26 +
27 +#define OTGC_SCR                       0x80
28 +#define OTGC_INT_EN                    0x88
29 +
30 +#define GLOBAL_INT_POLARITY            (1 << 3)
31 +#define GLOBAL_INT_MASK_HC             (1 << 2)
32 +#define GLOBAL_INT_MASK_OTG            (1 << 1)
33 +#define GLOBAL_INT_MASK_DEV            (1 << 0)
34 +
35 +#define OTGC_SCR_ID                    (1 << 21)
36 +#define OTGC_SCR_CROLE                 (1 << 20)
37 +#define OTGC_SCR_VBUS_VLD              (1 << 19)
38 +#define OTGC_SCR_A_SRP_RESP_TYPE       (1 << 8)
39 +#define OTGC_SCR_A_SRP_DET_EN          (1 << 7)
40 +#define OTGC_SCR_A_SET_B_HNP_EN                (1 << 6)
41 +#define OTGC_SCR_A_BUS_DROP            (1 << 5)
42 +#define OTGC_SCR_A_BUS_REQ             (1 << 4)
43 +
44 +#define OTGC_INT_APLGRMV               (1 << 12)
45 +#define OTGC_INT_BPLGRMV               (1 << 11)
46 +#define OTGC_INT_OVC                   (1 << 10)
47 +#define OTGC_INT_IDCHG                 (1 << 9)
48 +#define OTGC_INT_RLCHG                 (1 << 8)
49 +#define OTGC_INT_AVBUSERR              (1 << 5)
50 +#define OTGC_INT_ASRPDET               (1 << 4)
51 +#define OTGC_INT_BSRPDN                        (1 << 0)
52 +
53 +#define OTGC_INT_A_TYPE                (OTGC_INT_ASRPDET|OTGC_INT_AVBUSERR|OTGC_INT_OVC|OTGC_INT_RLCHG|OTGC_INT_IDCHG|OTGC_INT_APLGRMV)
54 +#define OTGC_INT_B_TYPE                (OTGC_INT_AVBUSERR|OTGC_INT_OVC|OTGC_INT_RLCHG|OTGC_INT_IDCHG)
55 +
56 +static void fotg2xx_otgc_role_change(struct usb_hcd *hcd);
57 +
58 +static void fotg2xx_otgc_init(struct usb_hcd *hcd)
59 +{
60 +       struct ehci_hcd *ehci = hcd_to_ehci(hcd);
61 +       unsigned int reg;
62 +
63 +       reg = __raw_readl(hcd->regs + OTGC_SCR);
64 +       ehci_info(ehci, "role detected: %s, ",
65 +                 (reg & OTGC_SCR_CROLE) ? "Peripheral" : "Host");
66 +
67 +       if (reg & OTGC_SCR_ID)
68 +               ehci_info(ehci, "B-Device (may be unsupported!)\n");
69 +       else
70 +               ehci_info(ehci, "A-Device\n");
71 +
72 +       /* Enable the SRP detect */
73 +       reg &= ~OTGC_SCR_A_SRP_RESP_TYPE;
74 +       __raw_writel(reg, hcd->regs + OTGC_SCR);
75 +
76 +       reg = __raw_readl(hcd->regs + OTGC_INT_EN);
77 +       /* clear INT B: bits AVBUSERR | OVC | RLCHG | IDCHG */
78 +       reg &= ~OTGC_INT_B_TYPE;
79 +       /* set INT A: bits ASRPDET | AVBUSERR | OVC | RLCHG | IDCHG | APLGRMV */
80 +       reg |= OTGC_INT_A_TYPE;
81 +       __raw_writel(reg, hcd->regs + OTGC_INT_EN);
82 +
83 +       reg = __raw_readl(hcd->regs + GLOBAL_ICR);
84 +       reg &= ~GLOBAL_INT_MASK_OTG;
85 +       __raw_writel(reg, hcd->regs + GLOBAL_ICR);
86 +
87 +       /* setup MISC register, fixes timing problems */
88 +       reg = __raw_readl(hcd->regs + HCD_MISC);
89 +       reg |= 0xD;
90 +       __raw_writel(reg, hcd->regs + HCD_MISC);
91 +
92 +       fotg2xx_otgc_role_change(hcd);
93 +}
94 +
95 +static void fotg2xx_otgh_close(struct usb_hcd *hcd)
96 +{
97 +       unsigned int reg;
98 +
99 +       /* <1>.Enable Interrupt Mask */
100 +       reg = __raw_readl(hcd->regs + GLOBAL_ICR);
101 +       reg |= GLOBAL_INT_MASK_HC;
102 +       __raw_writel(reg, hcd->regs + GLOBAL_ICR);
103 +
104 +       /* <2>.Clear the Interrupt status */
105 +       reg = __raw_readl(hcd->regs + 0x18);
106 +       reg &= 0x0000003F;
107 +       __raw_writel(reg, hcd->regs + 0x14);
108 +}
109 +
110 +static void fotg2xx_otgh_open(struct usb_hcd *hcd)
111 +{
112 +       unsigned int reg;
113 +
114 +       reg = __raw_readl(hcd->regs + OTGC_SCR);
115 +       reg &= ~OTGC_SCR_A_SRP_DET_EN;
116 +       __raw_writel(reg, hcd->regs + OTGC_SCR);
117 +
118 +       reg = __raw_readl(hcd->regs + GLOBAL_ICR);
119 +       reg &= ~GLOBAL_INT_MASK_HC;
120 +       __raw_writel(reg, hcd->regs + GLOBAL_ICR);
121 +}
122 +
123 +/* change to host role */
124 +static void fotg2xx_otgc_role_change(struct usb_hcd *hcd)
125 +{
126 +
127 +       /* clear A_SET_B_HNP_EN */
128 +       otg_clear(0x80, BIT(6));
129 +
130 +       /*** Enable VBUS driving */
131 +       if (readl(hcd->regs + 0x80) & BIT(19))
132 +               printk(KERN_INFO "VBUS already enabled\n");
133 +       else {
134 +               int cnt = 0;
135 +
136 +               /* clear A_BUS_DROP */
137 +               otg_clear(0x80, BIT(5));
138 +
139 +               /* set A_BUS_REQ */
140 +               otg_set(0x80, BIT(4));
141 +
142 +               /* set global bus reg to VBUS on */
143 +               writel(readl(IO_ADDRESS(0x40000000) + 0x30) | ((BIT(21)|BIT(22))),
144 +                       IO_ADDRESS(0x40000000) + 0x30);
145 +
146 +               if (readl(hcd->regs + 0x80) & (1<<19)) {
147 +                       printk(KERN_INFO "Waiting for VBus");
148 +                       while (!(readl(hcd->regs + 0x80) & (1<<19)) && (cnt < 80)) {
149 +                               printk(KERN_CONT ".");
150 +                               cnt++;
151 +                       }
152 +                       printk(KERN_CONT "\n");
153 +               } else
154 +                       printk(KERN_INFO "VBUS enabled.\n");
155 +
156 +               mdelay(1);
157 +       }
158 +       fotg2xx_otgh_open(hcd);
159 +}
160 +
161 +static int fotg2xx_ehci_hc_reset(struct usb_hcd *hcd)
162 +{
163 +       int result;
164 +       struct ehci_hcd *ehci = hcd_to_ehci(hcd);
165 +
166 +       ehci->caps = hcd->regs;
167 +       ehci->regs = hcd->regs + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
168 +
169 +       dbg_hcs_params(ehci, "reset");
170 +       dbg_hcc_params(ehci, "reset");
171 +
172 +       ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
173 +       hcd->has_tt = 1;
174 +
175 +       result = ehci_halt(ehci);
176 +       if (result)
177 +               return result;
178 +
179 +       result = ehci_init(hcd);
180 +       if (result)
181 +               return result;
182 +
183 +       ehci_port_power(ehci, 0);
184 +
185 +       return result;
186 +}
187 +
188 +/*
189 + * Name: OTGC_INT_ISR
190 + * Description:This interrupt service routine belongs to the OTG-Controller
191 + *           <1>.Check for ID_Change
192 + *           <2>.Check for RL_Change
193 + *           <3>.Error Detect
194 + * Input: wINTStatus
195 + * Output:void
196 + */
197 +void fotg2xx_int_isr(struct usb_hcd *hcd, u32 wINTStatus)
198 +{
199 +       /* <1>.Check for ID_Change */
200 +       if (wINTStatus&OTGC_INT_IDCHG) {
201 +               if ((readl(hcd->regs + 0x80) & BIT(21)) != 0)
202 +                       fotg2xx_otgc_init(hcd); /* Change to B Type */
203 +               else
204 +                       fotg2xx_otgc_init(hcd); /* Change to A Type */
205 +
206 +               return;
207 +       }
208 +
209 +       /* <2>.Check for RL_Change */
210 +       if (wINTStatus&OTGC_INT_RLCHG)
211 +               fotg2xx_otgc_role_change(hcd);
212 +
213 +       /* <3>.Error Detect */
214 +       if (wINTStatus&OTGC_INT_AVBUSERR)
215 +               printk(KERN_ERR "VBus error!\n");
216 +
217 +       if (wINTStatus&OTGC_INT_OVC)
218 +               printk(KERN_WARNING "Overcurrent detected!\n");
219 +
220 +       /* <3>.Check for Type-A/Type-B Interrupt */
221 +       if ((readl(hcd->regs + 0x80) & BIT(21)) == 0) { /*For Type-A Interrupt*/
222 +               if (wINTStatus & (OTGC_INT_A_TYPE | OTGC_INT_ASRPDET)) {
223 +                       /* <1>.SRP detected => then set global variable */
224 +                       printk(KERN_WARNING "SRP detected, but not implemented!\n");
225 +
226 +#if 0
227 +                       u32 wTempCounter;
228 +                       /* <2>.Turn on the V Bus */
229 +                       pFTC_OTG->otg.state = OTG_STATE_A_WAIT_VRISE;
230 +                       OTGC_enable_vbus_draw_storlink(1);
231 +                       pFTC_OTG->otg.state = OTG_STATE_A_HOST;
232 +                       /* <3>.Should waiting for Device-Connect Wait 300ms */
233 +                       INFO(pFTC_OTG, ">>> OTG-A Waiting for OTG-B Connect,\n");
234 +                       wTempCounter = 0;
235 +                       while (mwHost20_PORTSC_ConnectStatus_Rd() == 0) {
236 +                               mdelay(1);
237 +                               wTempCounter++;
238 +                               /* Waiting for 300 ms */
239 +                               if (wTempCounter > 300) {
240 +                                       mdwOTGC_Control_A_SRP_DET_EN_Clr();
241 +                                       INFO(pFTC_OTG, ">>> OTG-B do not connect under 300 ms...\n");
242 +                                       break;
243 +                               }
244 +                       }
245 +                       /* <4>.If Connect => issue quick Reset */
246 +                       if (mwHost20_PORTSC_ConnectStatus_Rd() > 0) {
247 +                               mdelay(300); /* For OPT-A Test */
248 +                               OTGH_host_quick_Reset();
249 +                               OTGH_Open();
250 +                               pFTC_OTG->otg.host->A_Disable_Set_Feature_HNP = 0;
251 +                       }
252 +#endif
253 +               }
254 +       } else { /* For Type-B Interrupt */
255 +               BUG();
256 +       }
257 +}
258 +
259 +static irqreturn_t fotg2xx_ehci_irq(int irq, void *devid)
260 +{
261 +       struct usb_hcd *hcd = devid;
262 +       u32 val;
263 +
264 +       /* OTG Interrupt Status Register */
265 +       val = readl(hcd->regs + 0x84);
266 +
267 +       /* OTG stuff */
268 +       if (val) {
269 +               /* supposed to do "INT STS Clr" - XXX */
270 +               writel(readl(hcd->regs + 0x84) | val, hcd->regs + 0x84);
271 +
272 +               fotg2xx_int_isr(hcd, val);
273 +
274 +               /* supposed to do "INT STS Clr" - XXX */
275 +               writel(readl(hcd->regs + 0x84) | val, hcd->regs + 0x84);
276 +
277 +               return IRQ_HANDLED;
278 +       }
279 +
280 +       if ((readl(hcd->regs + 0x80) & BIT(20)) == 0) { /* Role is HOST */
281 +               if (readl(hcd->regs + 0xC0) & BIT(2)) { /* INT STS HOST */
282 +                       /* leave this for ehci irq handler */
283 +                       return IRQ_NONE;
284 +               }
285 +       } else
286 +               printk(KERN_WARNING
287 +                     "received irq for peripheral - don't know what to do!\n");
288 +
289 +       /* do not call the ehci irq handler */
290 +       return IRQ_HANDLED;
291 +}
292 +
293 +static int fotg2xx_ehci_run(struct usb_hcd *hcd)
294 +{
295 +       int retval;
296 +
297 +       retval = ehci_run(hcd);
298 +
299 +       fotg2xx_otgh_close(hcd);
300 +       fotg2xx_otgc_init(hcd);
301 +
302 +       return retval;
303 +}
304 +
305 +static const struct hc_driver fotg2xx_ehci_hc_driver = {
306 +       .description            = hcd_name,
307 +       .product_desc           = "FOTG2XX EHCI Host Controller",
308 +       .hcd_priv_size          = sizeof(struct ehci_hcd),
309 +       .irq                    = ehci_irq,
310 +       .flags                  = HCD_MEMORY | HCD_USB2,
311 +       .reset                  = fotg2xx_ehci_hc_reset,
312 +       .start                  = fotg2xx_ehci_run,
313 +       .stop                   = ehci_stop,
314 +       .shutdown               = ehci_shutdown,
315 +
316 +       .urb_enqueue            = ehci_urb_enqueue,
317 +       .urb_dequeue            = ehci_urb_dequeue,
318 +       .endpoint_disable       = ehci_endpoint_disable,
319 +       .endpoint_reset         = ehci_endpoint_reset,
320 +
321 +       .get_frame_number       = ehci_get_frame,
322 +
323 +       .hub_status_data        = ehci_hub_status_data,
324 +       .hub_control            = ehci_hub_control,
325 +#if defined(CONFIG_PM)
326 +       .bus_suspend            = ehci_bus_suspend,
327 +       .bus_resume             = ehci_bus_resume,
328 +#endif
329 +       .relinquish_port        = ehci_relinquish_port,
330 +       .port_handed_over       = ehci_port_handed_over,
331 +
332 +       .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
333 +};
334 +
335 +static int fotg2xx_ehci_probe(struct platform_device *pdev)
336 +{
337 +       const struct hc_driver *driver = &fotg2xx_ehci_hc_driver;
338 +       struct usb_hcd *hcd;
339 +       struct resource *res;
340 +       int irq;
341 +       int retval;
342 +
343 +       pr_debug("initializing FOTG2XX-SOC USB Controller\n");
344 +
345 +       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
346 +       if (!res) {
347 +               dev_err(&pdev->dev,
348 +                       "Found HC with no IRQ. Check %s setup!\n",
349 +                       dev_name(&pdev->dev));
350 +               return -ENODEV;
351 +       }
352 +
353 +       irq = res->start;
354 +
355 +       hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
356 +       if (!hcd) {
357 +               retval = -ENOMEM;
358 +               goto err1;
359 +       }
360 +
361 +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
362 +       if (!res) {
363 +               dev_err(&pdev->dev,
364 +                       "Found HC with no register addr. Check %s setup!\n",
365 +                       dev_name(&pdev->dev));
366 +               retval = -ENODEV;
367 +               goto err2;
368 +       }
369 +
370 +       hcd->rsrc_start = res->start;
371 +       hcd->rsrc_len = res->end - res->start + 1;
372 +       if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
373 +                               driver->description)) {
374 +               dev_dbg(&pdev->dev, "controller already in use\n");
375 +               retval = -EBUSY;
376 +               goto err2;
377 +       }
378 +
379 +       hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
380 +       if (hcd->regs == NULL) {
381 +               dev_dbg(&pdev->dev, "error mapping memory\n");
382 +               retval = -EFAULT;
383 +               goto err3;
384 +       }
385 +
386 +
387 +       /* set global reg to mini-A host */
388 +       writel(readl(IO_ADDRESS(0x40000000) + 0x30) & ~(BIT(30)|BIT(29)),
389 +               IO_ADDRESS(0x40000000) + 0x30);
390 +
391 +       /* USB0&USB1 - VBUS off */
392 +       writel(readl(IO_ADDRESS(0x40000000) + 0x30) & ~(BIT(21)|BIT(22)),
393 +               IO_ADDRESS(0x40000000) + 0x30);
394 +
395 +       if ((readl(hcd->regs) == 0x01000010) &&
396 +               (readl(hcd->regs + 4) == 0x00000001) &&
397 +               (readl(hcd->regs + 8) == 0x00000006)) {
398 +               dev_info(&pdev->dev,
399 +                       "Found Faraday OTG 2XX controller (base = 0x%08lX)\n",
400 +                       (unsigned long) hcd->rsrc_start);
401 +       } else {
402 +               dev_err(&pdev->dev, "fotg2xx id mismatch: found %d.%d.%d\n",
403 +                       readl(hcd->regs + 0x00),
404 +                       readl(hcd->regs + 0x04),
405 +                       readl(hcd->regs + 0x08));
406 +               retval = -ENODEV;
407 +               goto err4;
408 +       }
409 +
410 +       platform_set_drvdata(pdev, hcd);
411 +
412 +       /* mask interrupts - peripheral, otg, host, hi-active (bits 0,1,2,3) */
413 +       otg_set(0xc4, BIT(3)); /* hi active */
414 +
415 +       otg_set(0xc4, BIT(2)); /* host */
416 +       otg_set(0xc4, BIT(1)); /* otg */
417 +       otg_set(0xc4, BIT(0)); /* peripheral */
418 +
419 +       /* register additional interrupt - here we check otg status */
420 +       if ((request_irq(irq, &fotg2xx_ehci_irq, IRQF_SHARED | IRQF_DISABLED,
421 +               hcd->irq_descr, hcd)) != 0) {
422 +               dev_dbg(&pdev->dev, "error requesting irq %d\n", irq);
423 +               retval = -EFAULT;
424 +               goto err4;
425 +       }
426 +
427 +       retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
428 +       if (retval != 0)
429 +               goto err4;
430 +       return retval;
431 +
432 +err4:
433 +       iounmap(hcd->regs);
434 +err3:
435 +       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
436 +err2:
437 +       usb_put_hcd(hcd);
438 +err1:
439 +       dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
440 +       return retval;
441 +}
442 +
443 +/* may be called without controller electrically present */
444 +/* may be called with controller, bus, and devices active */
445 +
446 +int fotg2xx_ehci_remove(struct platform_device *pdev)
447 +{
448 +       struct usb_hcd *hcd =
449 +               (struct usb_hcd *)platform_get_drvdata(pdev);
450 +
451 +       usb_remove_hcd(hcd);
452 +       release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
453 +       iounmap(hcd->regs);
454 +       usb_put_hcd(hcd);
455 +       platform_set_drvdata(pdev, NULL);
456 +
457 +       return 0;
458 +}
459 +
460 +MODULE_ALIAS("platform:ehci-fotg2xx");
461 +
462 +static struct platform_driver fotg2xx_ehci_driver = {
463 +       .probe = fotg2xx_ehci_probe,
464 +       .remove = fotg2xx_ehci_remove,
465 +       .driver = {
466 +               .name = "ehci-fotg2xx",
467 +       },
468 +};
469 --- a/drivers/usb/host/ehci.h
470 +++ b/drivers/usb/host/ehci.h
471 @@ -600,7 +600,12 @@ static inline unsigned int
472  ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
473  {
474         if (ehci_is_TDI(ehci)) {
475 +#ifdef CONFIG_ARCH_GEMINI
476 +               portsc = readl(ehci_to_hcd(ehci)->regs + 0x80);
477 +               switch ((portsc>>22)&3) {
478 +#else
479                 switch ((portsc >> (ehci->has_hostpc ? 25 : 26)) & 3) {
480 +#endif
481                 case 0:
482                         return 0;
483                 case 1:
484 --- a/drivers/usb/host/ehci-hcd.c
485 +++ b/drivers/usb/host/ehci-hcd.c
486 @@ -204,10 +204,12 @@ static int ehci_halt (struct ehci_hcd *e
487          * This routine gets called during probe before ehci->command
488          * has been initialized, so we can't rely on its value.
489          */
490 +#ifndef CONFIG_ARCH_GEMINI
491         ehci->command &= ~CMD_RUN;
492         temp = ehci_readl(ehci, &ehci->regs->command);
493         temp &= ~(CMD_RUN | CMD_IAAD);
494         ehci_writel(ehci, temp, &ehci->regs->command);
495 +#endif
496  
497         spin_unlock_irq(&ehci->lock);
498         synchronize_irq(ehci_to_hcd(ehci)->irq);
499 @@ -257,13 +259,17 @@ static int ehci_reset (struct ehci_hcd *
500         if (ehci->has_hostpc) {
501                 ehci_writel(ehci, USBMODE_EX_HC | USBMODE_EX_VBPS,
502                                 &ehci->regs->usbmode_ex);
503 +#ifndef CONFIG_ARCH_GEMINI
504                 ehci_writel(ehci, TXFIFO_DEFAULT, &ehci->regs->txfill_tuning);
505 +#endif
506         }
507         if (retval)
508                 return retval;
509  
510 +#ifndef CONFIG_ARCH_GEMINI
511         if (ehci_is_TDI(ehci))
512                 tdi_reset (ehci);
513 +#endif
514  
515         if (ehci->debug)
516                 dbgp_external_startup(ehci_to_hcd(ehci));
517 @@ -341,11 +347,14 @@ static void ehci_silence_controller(stru
518         ehci->rh_state = EHCI_RH_HALTED;
519         ehci_turn_off_all_ports(ehci);
520  
521 +#ifndef CONFIG_ARCH_GEMINI
522         /* make BIOS/etc use companion controller during reboot */
523         ehci_writel(ehci, 0, &ehci->regs->configured_flag);
524  
525         /* unblock posted writes */
526         ehci_readl(ehci, &ehci->regs->configured_flag);
527 +#endif
528 +
529         spin_unlock_irq(&ehci->lock);
530  }
531  
532 @@ -600,7 +609,9 @@ static int ehci_run (struct usb_hcd *hcd
533         // Philips, Intel, and maybe others need CMD_RUN before the
534         // root hub will detect new devices (why?); NEC doesn't
535         ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
536 +#ifndef CONFIG_ARCH_GEMINI
537         ehci->command |= CMD_RUN;
538 +#endif
539         ehci_writel(ehci, ehci->command, &ehci->regs->command);
540         dbg_cmd (ehci, "init", ehci->command);
541  
542 @@ -620,9 +631,11 @@ static int ehci_run (struct usb_hcd *hcd
543          */
544         down_write(&ehci_cf_port_reset_rwsem);
545         ehci->rh_state = EHCI_RH_RUNNING;
546 +#ifndef CONFIG_ARCH_GEMINI
547         ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
548         ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
549         msleep(5);
550 +#endif /* !CONFIG_ARCH_GEMINI */
551         up_write(&ehci_cf_port_reset_rwsem);
552         ehci->last_periodic_enable = ktime_get_real();
553  
554 @@ -1241,6 +1254,11 @@ MODULE_DESCRIPTION(DRIVER_DESC);
555  MODULE_AUTHOR (DRIVER_AUTHOR);
556  MODULE_LICENSE ("GPL");
557  
558 +#ifdef CONFIG_ARCH_GEMINI
559 +#include "ehci-fotg2xx.c"
560 +#define PLATFORM_DRIVER                fotg2xx_ehci_driver
561 +#endif
562 +
563  #ifdef CONFIG_USB_EHCI_FSL
564  #include "ehci-fsl.c"
565  #define        PLATFORM_DRIVER         ehci_fsl_driver
566 --- a/drivers/usb/host/ehci-hub.c
567 +++ b/drivers/usb/host/ehci-hub.c
568 @@ -912,6 +912,12 @@ static int ehci_hub_control (
569                         /* see what we found out */
570                         temp = check_reset_complete (ehci, wIndex, status_reg,
571                                         ehci_readl(ehci, status_reg));
572 +#ifdef CONFIG_ARCH_GEMINI
573 +                       /* restart schedule */
574 +                       ehci_writel(ehci, ehci_readl(ehci, &ehci->regs->command) | CMD_RUN, &ehci->regs->command);
575 +
576 +//                     hcd->state = HC_STATE_RUNNING;
577 +#endif
578                 }
579  
580                 if (!(temp & (PORT_RESUME|PORT_RESET))) {
581 --- a/drivers/usb/Kconfig
582 +++ b/drivers/usb/Kconfig
583 @@ -47,6 +47,7 @@ config USB_ARCH_HAS_EHCI
584         default y if MICROBLAZE
585         default y if SPARC_LEON
586         default y if ARCH_MMP
587 +       default y if ARCH_GEMINI
588         default y if MACH_LOONGSON1
589         default y if PLAT_ORION
590         default PCI
591 @@ -96,7 +97,7 @@ config USB
592           traditional PC serial port.  The bus supplies power to peripherals
593           and allows for hot swapping.  Up to 127 USB peripherals can be
594           connected to a single USB host in a tree structure.
595 -         
596 +
597           The USB host is the root of the tree, the peripherals are the
598           leaves and the inner nodes are special USB devices called hubs.
599           Most PCs now have USB host ports, used to connect peripherals
600 --- a/include/linux/usb/ehci_def.h
601 +++ b/include/linux/usb/ehci_def.h
602 @@ -111,6 +111,7 @@ struct ehci_regs {
603         /* ASYNCLISTADDR: offset 0x18 */
604         u32             async_next;     /* address of next async queue head */
605  
606 +#ifndef CONFIG_ARCH_GEMINI
607         u32             reserved1[2];
608  
609         /* TXFILLTUNING: offset 0x24 */
610 @@ -118,6 +119,7 @@ struct ehci_regs {
611  #define TXFIFO_DEFAULT (8<<16)         /* FIFO burst threshold 8 */
612  
613         u32             reserved2[6];
614 +#endif /* !CONFIG_ARCH_GEMINI */
615  
616         /* CONFIGFLAG: offset 0x40 */
617         u32             configured_flag;