511e0e4fe238e1b1609d1da64dce2e88b6640612
[kernel-bfs] / kernel-bfs-2.6.28 / debian / patches / usbhostmode.diff
1 --- kernel-power-2.6.28.orig/arch/arm/mach-omap2/board-rx51.c
2 +++ kernel-power-2.6.28/arch/arm/mach-omap2/board-rx51.c
3 @@ -108,6 +108,7 @@
4  
5  static int rx51_xceiv_reset(void)
6  {
7 +       printk(KERN_ERR "rx51_xceiv_reset\n");
8         /* make sure the transceiver is awake */
9         msleep(15);
10         /* only reset powered transceivers */
11 @@ -125,6 +126,7 @@
12  {
13         unsigned long   timeout;
14  
15 +       printk(KERN_ERR "rx51_xceiv_power %d\n",power);
16         if (!power) {
17                 /* Let musb go stdby before powering down the transceiver */
18                 timeout = jiffies + msecs_to_jiffies(100);
19 --- kernel-power-2.6.28.orig/drivers/usb/musb/isp1704.h
20 +++ kernel-power-2.6.28/drivers/usb/musb/isp1704.h
21 @@ -41,6 +41,7 @@
22  #define ISP1704_OTG_CTRL               0x0a
23  #define ISP1704_USB_INTRISE            0x0d
24  #define ISP1704_USB_INTFALL            0x10
25 +#define ISP1704_USB_INTSTAT   0x13
26  #define ISP1704_DEBUG                  0x15
27  #define ISP1704_SCRATCH                        0x16
28  #define ISP1704_PWR_CTRL               0x3d
29 --- kernel-power-2.6.28.orig/drivers/usb/musb/musb_core.c
30 +++ kernel-power-2.6.28/drivers/usb/musb/musb_core.c
31 @@ -142,6 +142,59 @@
32  MODULE_LICENSE("GPL");
33  MODULE_ALIAS("platform:" MUSB_DRIVER_NAME);
34  
35 +
36 +
37 +inline void mbusywait(int ms)
38 +{
39 +       unsigned long end_time = jiffies + msecs_to_jiffies(ms);
40 +       while(time_before(jiffies,end_time))
41 +               cpu_relax();
42 +
43 +}
44 +
45 +void musb_force_term(void __iomem *addr, enum musb_term term)
46 +{
47 +       u8 r;
48 +
49 +
50 +       r = musb_ulpi_readb(addr, ISP1704_OTG_CTRL);
51 +       r |= ISP1704_OTG_CTRL_DP_PULLDOWN | ISP1704_OTG_CTRL_DM_PULLDOWN;
52 +       musb_ulpi_writeb(addr, ISP1704_OTG_CTRL, r);
53 +
54 +       r = musb_ulpi_readb(addr, ISP1704_FUNC_CTRL);
55 +
56 +       switch(term) {
57 +
58 +       case MUSB_TERM_HOST_HIGHSPEED:
59 +               r &= ~ISP1704_FUNC_CTRL_XCVRSELECT;
60 +               r &= ~ISP1704_FUNC_CTRL_TERMSELECT;
61 +               r &= ~ISP1704_FUNC_CTRL_OPMODE;
62 +               break;
63 +
64 +       case MUSB_TERM_HOST_FULLSPEED:
65 +               r |= 1 << ISP1704_FUNC_CTRL_XCVRSELECT_SHIFT;
66 +               r |= ISP1704_FUNC_CTRL_TERMSELECT;
67 +               r &= ~ISP1704_FUNC_CTRL_OPMODE;
68 +               break;
69 +
70 +       case MUSB_TERM_HOST_LOWSPEED:
71 +               r |= 2 << ISP1704_FUNC_CTRL_XCVRSELECT_SHIFT;
72 +               r |= ISP1704_FUNC_CTRL_TERMSELECT;
73 +               r &= ~ISP1704_FUNC_CTRL_OPMODE;
74 +               break;
75 +
76 +       default:
77 +               ERR("Unknown musb termination\n");
78 +               return;
79 +       }
80 +
81 +       r |= ISP1704_OTG_CTRL_IDPULLUP;
82 +       musb_ulpi_writeb(addr, ISP1704_FUNC_CTRL, r);
83 +
84 +}
85 +
86 +
87 +
88  static inline int musb_verify_charger(void __iomem *addr)
89  {
90         u8 r, ret = 0;
91 @@ -220,6 +273,8 @@
92  
93         u8              vdat = 0;
94         u8              r;
95 +       u8 testmode;
96 +       testmode = musb_readb(musb->mregs,MUSB_TESTMODE);
97  
98         msleep(5);
99  
100 @@ -297,7 +352,7 @@
101                         break;
102         }
103  
104 -       if (vdat) {
105 +       if (vdat && !(testmode & MUSB_TEST_FORCE_HOST)) {
106                 /* REVISIT: This code works only with dedicated chargers!
107                  * When support for HOST/HUB chargers is added, don't
108                  * forget this.
109 @@ -349,7 +404,7 @@
110  
111         prefetch((u8 *)src);
112  
113 -       DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
114 +       DBG(6, "%cX ep%d fifo %p count %d buf %p\n",
115                         'T', hw_ep->epnum, fifo, len, src);
116  
117         /* we can't assume unaligned reads work */
118 @@ -387,7 +442,7 @@
119  {
120         void __iomem *fifo = hw_ep->fifo;
121  
122 -       DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
123 +       DBG(6, "%cX ep%d fifo %p count %d buf %p\n",
124                         'R', hw_ep->epnum, fifo, len, dst);
125  
126         /* we can't assume unaligned writes work */
127 @@ -490,7 +545,6 @@
128  {
129         struct musb     *musb = (struct musb *)data;
130         unsigned long   flags;
131 -
132         spin_lock_irqsave(&musb->lock, flags);
133         switch (musb->xceiv->state) {
134         case OTG_STATE_B_WAIT_ACON:
135 @@ -572,10 +626,19 @@
136  static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
137                                 u8 devctl, u8 power)
138  {
139 +       u8 testmode;
140         irqreturn_t handled = IRQ_NONE;
141         void __iomem *mbase = musb->mregs;
142         u8 r;
143  
144 +       testmode = musb_readb(mbase,MUSB_TESTMODE);
145 +  if(testmode & MUSB_TEST_FORCE_HOST) {
146 +               if(int_usb & MUSB_INTR_SESSREQ) {
147 +                       DBG(1,"Piggybacking CONNECT on SESS REQ\n");
148 +                       musb->int_usb |= MUSB_INTR_CONNECT;
149 +               } 
150 +       }
151 +
152         DBG(3, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl,
153                 int_usb);
154  
155 @@ -630,6 +693,8 @@
156                 } else {
157                         switch (musb->xceiv->state) {
158  #ifdef CONFIG_USB_MUSB_HDRC_HCD
159 +                       case OTG_STATE_A_WAIT_BCON:
160 +                       case OTG_STATE_A_HOST:
161                         case OTG_STATE_A_SUSPEND:
162                                 /* possibly DISCONNECT is upcoming */
163                                 musb->xceiv->state = OTG_STATE_A_HOST;
164 @@ -678,7 +743,7 @@
165                  * be discarded silently.
166                  */
167                 if ((devctl & MUSB_DEVCTL_VBUS)
168 -                   && !(devctl & MUSB_DEVCTL_BDEVICE)) {
169 +                   && host_mode(musb->mregs)) {
170                         musb_writeb(mbase, MUSB_DEVCTL, MUSB_DEVCTL_SESSION);
171                         musb->ep0_stage = MUSB_EP0_START;
172                         musb->xceiv->state = OTG_STATE_A_IDLE;
173 @@ -796,9 +861,15 @@
174                                         + msecs_to_jiffies(musb->a_wait_bcon));
175                         break;
176                 case OTG_STATE_A_HOST:
177 +                       if(testmode & MUSB_TEST_FORCE_HOST) {
178 +                               //                              musb->int_usb |= MUSB_INTR_RESUME;
179 +                               break;
180 +                       }
181 +
182                         musb->xceiv->state = OTG_STATE_A_SUSPEND;
183                         musb->is_active = is_otg_enabled(musb)
184                                         && musb->xceiv->host->b_hnp_enable;
185 +
186                         break;
187                 case OTG_STATE_B_HOST:
188                         /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */
189 @@ -818,6 +889,7 @@
190                 musb->is_active = 1;
191                 set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
192  
193 +
194                 musb->ep0_stage = MUSB_EP0_START;
195  
196  #ifdef CONFIG_USB_MUSB_OTG
197 @@ -836,9 +908,65 @@
198                 musb->port1_status |= USB_PORT_STAT_CONNECTION
199                                         |(USB_PORT_STAT_C_CONNECTION << 16);
200  
201 -               /* high vs full speed is just a guess until after reset */
202 -               if (devctl & MUSB_DEVCTL_LSDEV)
203 -                       musb->port1_status |= USB_PORT_STAT_LOW_SPEED;
204 +               if (testmode & MUSB_TEST_FORCE_HOST) {
205 +                       u8 r,reg;
206 +      void __iomem *mbase = musb->mregs;
207 +
208 +                       musb_force_term(musb->mregs,MUSB_TERM_HOST_HIGHSPEED);
209 +
210 +                       r = musb_ulpi_readb(mbase, ISP1704_DEBUG);
211 +                       DBG(1,"Linestate %x\n",r);
212 +                       switch(r) {
213 +                       case 2:
214 +                               musb->port1_status |= USB_PORT_STAT_LOW_SPEED;
215 +                               reg = musb_readb(mbase, MUSB_TESTMODE);
216 +                               reg &= ~MUSB_TEST_FORCE_FS;
217 +                               reg &= ~MUSB_TEST_FORCE_HS;
218 +                               musb_writeb(mbase, MUSB_TESTMODE, reg);
219 +
220 +                               reg = musb_readb(mbase, MUSB_POWER);
221 +                               reg &= ~MUSB_POWER_HSENAB;
222 +                               musb_writeb(mbase, MUSB_POWER, reg);
223 +
224 +                               musb_force_term(musb->mregs,MUSB_TERM_HOST_LOWSPEED);
225 +                               break;
226 +                       case 1:
227 +                               /*High or full speed*/
228 +                               reg = musb_readb(mbase, MUSB_TESTMODE);
229 +                               if(reg &  MUSB_TEST_FORCE_HS) {
230 +                                       /*High speed*/
231 +                                       reg &= ~MUSB_TEST_FORCE_FS;
232 +                                       musb_writeb(mbase, MUSB_TESTMODE, reg);
233 +
234 +                                       reg = musb_readb(mbase, MUSB_POWER);
235 +                                       reg |= MUSB_POWER_HSENAB;
236 +                                       musb_writeb(mbase, MUSB_POWER, reg);
237 +                               } else {
238 +                                       /*Full speed*/
239 +                                       reg |= MUSB_TEST_FORCE_FS;
240 +                                       musb_writeb(mbase, MUSB_TESTMODE, reg);
241 +
242 +                                       reg = musb_readb(mbase, MUSB_POWER);
243 +                                       reg &= ~MUSB_POWER_HSENAB;
244 +                                       musb_writeb(mbase, MUSB_POWER, reg);
245 +                               }
246 +
247 +                               musb_force_term(mbase,MUSB_TERM_HOST_FULLSPEED);
248 +
249 +                               break;
250 +                       case 0:
251 +                       case 3:
252 +                               /*invalid*/
253 +                               WARNING("Invalid line state of %d\n",r);
254 +                               break;
255 +                               
256 +                       }
257 +               } else {
258 +
259 +                       /* high vs full speed is just a guess until after reset */
260 +                       if (devctl & MUSB_DEVCTL_LSDEV)
261 +                               musb->port1_status |= USB_PORT_STAT_LOW_SPEED;
262 +               }
263  
264                 if (hcd->status_urb)
265                         usb_hcd_poll_rh_status(hcd);
266 @@ -974,6 +1102,8 @@
267                                 musb->ignore_disconnect = 1;
268                                 musb_g_reset(musb);
269                                 /* FALLTHROUGH */
270 +                       case OTG_STATE_A_HOST:
271 +                               musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
272                         case OTG_STATE_A_WAIT_BCON:     /* OPT TD.4.7-900ms */
273                                 DBG(1, "HNP: Setting timer as %s\n",
274                                                 otg_state_string(musb));
275 @@ -2421,8 +2551,7 @@
276                 DBG(1, "%s mode, status %d, devctl %02x %c\n",
277                         "HOST", status,
278                         musb_readb(musb->mregs, MUSB_DEVCTL),
279 -                       (musb_readb(musb->mregs, MUSB_DEVCTL)
280 -                                       & MUSB_DEVCTL_BDEVICE
281 +                               (!host_mode(musb->mregs)
282                                 ? 'B' : 'A'));
283  
284         } else /* peripheral is enabled */ {
285 --- kernel-power-2.6.28.orig/drivers/usb/musb/musb_core.h
286 +++ kernel-power-2.6.28/drivers/usb/musb/musb_core.h
287 @@ -85,6 +85,16 @@
288  #define        is_host_active(musb)            is_host_capable()
289  #endif
290  
291 +static inline int host_mode(void __iomem *addr) 
292 +{
293 +       u8              devctl,testmode;
294 +       devctl = musb_readb(addr, MUSB_DEVCTL);
295 +       testmode = musb_readb(addr,MUSB_TESTMODE);
296 +
297 +       return (testmode & MUSB_TEST_FORCE_HOST) || !(devctl & MUSB_DEVCTL_BDEVICE);
298 +}
299 +
300 +
301  #if defined(CONFIG_USB_MUSB_OTG) || defined(CONFIG_USB_MUSB_PERIPHERAL)
302  /* for some reason, the "select USB_GADGET_MUSB_HDRC" doesn't always
303   * override that choice selection (often USB_GADGET_DUMMY_HCD).
304 @@ -593,6 +603,14 @@
305  
306  extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode);
307  
308 +enum musb_term {
309 +       MUSB_TERM_HOST_HIGHSPEED,
310 +       MUSB_TERM_HOST_FULLSPEED,
311 +       MUSB_TERM_HOST_LOWSPEED,
312 +};
313 +
314 +extern void musb_force_term(void __iomem *addr, enum musb_term term);
315 +
316  #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \
317         defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
318  extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout);
319 --- kernel-power-2.6.28.orig/drivers/usb/musb/musb_gadget.c
320 +++ kernel-power-2.6.28/drivers/usb/musb/musb_gadget.c
321 @@ -1957,7 +1957,7 @@
322         u8              power;
323  
324         DBG(3, "<== %s addr=%x driver '%s'\n",
325 -                       (devctl & MUSB_DEVCTL_BDEVICE)
326 +                       !host_mode(musb->mregs)
327                                 ? "B-Device" : "A-Device",
328                         musb_readb(mbase, MUSB_FADDR),
329                         musb->gadget_driver
330 @@ -1994,7 +1994,7 @@
331         /* Normal reset, as B-Device;
332          * or else after HNP, as A-Device
333          */
334 -       if (devctl & MUSB_DEVCTL_BDEVICE) {
335 +       if (!host_mode(musb->mregs)) {
336                 musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
337                 musb->g.is_a_peripheral = 0;
338         } else if (is_otg_enabled(musb)) {
339 --- kernel-power-2.6.28.orig/drivers/usb/musb/musb_host.c
340 +++ kernel-power-2.6.28/drivers/usb/musb/musb_host.c
341 @@ -1863,8 +1863,10 @@
342         unsigned                        interval;
343  
344         /* host role must be active */
345 -       if (!is_host_active(musb) || !musb->is_active)
346 +       if (!is_host_active(musb) || !musb->is_active) {
347 +               printk(KERN_ERR "musb is_host_active %d is_active %d\n",is_host_active(musb),musb->is_active);
348                 return -ENODEV;
349 +       }
350  
351         spin_lock_irqsave(&musb->lock, flags);
352         ret = usb_hcd_link_urb_to_ep(hcd, urb);
353 @@ -2275,6 +2277,7 @@
354         return 0;
355  }
356  
357 +
358  const struct hc_driver musb_hc_driver = {
359         .description            = "musb-hcd",
360         .product_desc           = "MUSB HDRC host driver",
361 @@ -2298,6 +2301,5 @@
362         .hub_control            = musb_hub_control,
363         .bus_suspend            = musb_bus_suspend,
364         .bus_resume             = musb_bus_resume,
365 -       /* .start_port_reset    = NULL, */
366         /* .hub_irq_enable      = NULL, */
367  };
368 --- kernel-power-2.6.28.orig/drivers/usb/musb/musb_procfs.c
369 +++ kernel-power-2.6.28/drivers/usb/musb/musb_procfs.c
370 @@ -37,6 +37,7 @@
371  #include <linux/seq_file.h>
372  #include <linux/uaccess.h>     /* FIXME remove procfs writes */
373  #include <mach/hardware.h>
374 +#include <asm/mach-types.h>
375  
376  #include "musb_core.h"
377  
378 @@ -450,8 +451,8 @@
379                 return 0;
380         buffer += count;
381  
382 -       code = sprintf(buffer, "OTG state: %s; %sactive\n",
383 -                       otg_state_string(musb),
384 +       code = sprintf(buffer, "OTG state: %s:%d; %sactive\n",
385 +                                                                otg_state_string(musb),musb->xceiv->state,
386                         musb->is_active ? "" : "in");
387         if (code <= 0)
388                 goto done;
389 @@ -591,16 +592,34 @@
390   *
391   * C soft-connect
392   * c soft-disconnect
393 - * I enable HS
394 - * i disable HS
395 - * s stop session
396 - * F force session (OTG-unfriendly)
397 + * D<num> set/query the debug level
398   * E rElinquish bus (OTG)
399 + * e enumerate
400 + * F force session (OTG-unfriendly)
401   * H request host mode
402   * h cancel host request
403 + * I enable HS
404 + * i disable HS
405 + * J set HS test mode
406 + * j clear HS test mode
407 + * K set FS test mode
408 + * k clear FS test mode
409 + * M set host test mode
410 + * m clear host test mode
411 + * R reset peripheral
412 + * r resume root hub
413 + * s stop session
414   * T start sending TEST_PACKET
415 - * D<num> set/query the debug level
416 + * X term highspeed
417 + * Y term fullspeed
418 + * Z term lowspeed
419 + * 
420   */
421 +
422 +extern inline void mbusywait(int ms);
423 +extern void musb_port_reset(struct musb *musb, bool do_reset);
424 +extern void musb_port_suspend(struct musb *musb, bool do_suspend);
425 +
426  static int musb_proc_write(struct file *file, const char __user *buffer,
427                         unsigned long count, void *data)
428  {
429 @@ -608,49 +627,63 @@
430         u8 reg;
431         struct musb *musb = (struct musb *)data;
432         void __iomem *mbase = musb->mregs;
433 +       unsigned long   flags;
434 +       struct usb_hcd *hcd = musb_to_hcd(musb);
435 +       struct usb_bus *bus = hcd_to_bus(hcd);
436  
437         /* MOD_INC_USE_COUNT; */
438  
439         if (unlikely(copy_from_user(&cmd, buffer, 1)))
440                 return -EFAULT;
441  
442 +
443         switch (cmd) {
444         case 'C':
445                 if (mbase) {
446 -                       reg = musb_readb(mbase, MUSB_POWER)
447 -                                       | MUSB_POWER_SOFTCONN;
448 +                       reg = musb_readb(mbase, MUSB_POWER);
449 +                       reg |= MUSB_POWER_SOFTCONN;
450                         musb_writeb(mbase, MUSB_POWER, reg);
451                 }
452                 break;
453  
454         case 'c':
455                 if (mbase) {
456 -                       reg = musb_readb(mbase, MUSB_POWER)
457 -                                       & ~MUSB_POWER_SOFTCONN;
458 +                       reg = musb_readb(mbase, MUSB_POWER);
459 +                       reg &= ~MUSB_POWER_SOFTCONN;
460                         musb_writeb(mbase, MUSB_POWER, reg);
461                 }
462                 break;
463  
464         case 'I':
465                 if (mbase) {
466 -                       reg = musb_readb(mbase, MUSB_POWER)
467 -                                       | MUSB_POWER_HSENAB;
468 +                       reg = musb_readb(mbase, MUSB_POWER);
469 +                       reg |= MUSB_POWER_HSENAB;
470                         musb_writeb(mbase, MUSB_POWER, reg);
471                 }
472                 break;
473  
474         case 'i':
475                 if (mbase) {
476 -                       reg = musb_readb(mbase, MUSB_POWER)
477 -                                       & ~MUSB_POWER_HSENAB;
478 +                       reg = musb_readb(mbase, MUSB_POWER);
479 +                       reg &= ~MUSB_POWER_HSENAB;
480                         musb_writeb(mbase, MUSB_POWER, reg);
481                 }
482                 break;
483  
484         case 'F':
485 -               reg = musb_readb(mbase, MUSB_DEVCTL);
486 -               reg |= MUSB_DEVCTL_SESSION;
487 -               musb_writeb(mbase, MUSB_DEVCTL, reg);
488 +               if (mbase) {
489 +                       reg = musb_readb(mbase, MUSB_DEVCTL);
490 +                       reg |= MUSB_DEVCTL_SESSION;
491 +                       musb_writeb(mbase, MUSB_DEVCTL, reg);
492 +               }
493 +               break;
494 +
495 +       case 's':
496 +               if (mbase) {
497 +                       reg = musb_readb(mbase, MUSB_DEVCTL);
498 +                       reg &= ~MUSB_DEVCTL_SESSION;
499 +                       musb_writeb(mbase, MUSB_DEVCTL, reg);
500 +               }
501                 break;
502  
503         case 'H':
504 @@ -679,6 +712,114 @@
505                 }
506                 break;
507  
508 +       case 'M':
509 +               if (mbase) {
510 +                       reg = musb_readb(mbase, MUSB_TESTMODE);
511 +                       reg |= MUSB_TEST_FORCE_HOST;
512 +                       musb_writeb(mbase, MUSB_TESTMODE, reg);
513 +               }
514 +               break;
515 +       
516 +       case 'm':
517 +               if (mbase) {
518 +                       reg = musb_readb(mbase, MUSB_TESTMODE);
519 +                       reg &= ~MUSB_TEST_FORCE_HOST;
520 +                       musb_writeb(mbase, MUSB_TESTMODE, reg);
521 +                       MUSB_DEV_MODE(musb);
522 +                       musb->xceiv->state = OTG_STATE_B_IDLE;
523 +               }
524 +               break;
525 +
526 +  case 'L':
527 +                       musb->xceiv->state = OTG_STATE_A_HOST;
528 +                       MUSB_HST_MODE(musb);
529 +               break;
530 +
531 +  case 'l':
532 +                       musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
533 +                       MUSB_HST_MODE(musb);
534 +               break;
535 +
536 +       case 'J':
537 +               if (mbase) {
538 +                       reg = musb_readb(mbase, MUSB_TESTMODE);
539 +                       reg |= MUSB_TEST_FORCE_HS;
540 +                       musb_writeb(mbase, MUSB_TESTMODE, reg);
541 +               }
542 +               break;
543 +
544 +       case 'j':
545 +               if (mbase) {
546 +                       reg = musb_readb(mbase, MUSB_TESTMODE);
547 +                       reg &= ~MUSB_TEST_FORCE_HS;
548 +                       musb_writeb(mbase, MUSB_TESTMODE, reg);
549 +               }
550 +               break;
551 +
552 +       case 'K':
553 +               if (mbase) {
554 +                       reg = musb_readb(mbase, MUSB_TESTMODE);
555 +                       reg |= MUSB_TEST_FORCE_FS;
556 +                       musb_writeb(mbase, MUSB_TESTMODE, reg);
557 +               }
558 +               break;
559 +
560 +       case 'k':
561 +               if (mbase) {
562 +                       reg = musb_readb(mbase, MUSB_TESTMODE);
563 +                       reg &= ~MUSB_TEST_FORCE_FS;
564 +                       musb_writeb(mbase, MUSB_TESTMODE, reg);
565 +               }
566 +               break;
567 +
568 +  case 'X':
569 +    if (mbase)
570 +                       musb_force_term(mbase,MUSB_TERM_HOST_HIGHSPEED);
571 +               break;
572 +
573 +  case 'Y':
574 +    if (mbase)
575 +                       musb_force_term(mbase,MUSB_TERM_HOST_FULLSPEED);
576 +               break;
577 +
578 +  case 'Z':
579 +    if (mbase)
580 +                       musb_force_term(mbase,MUSB_TERM_HOST_LOWSPEED);
581 +               break;
582 +
583 +       case 'R':
584 +               musb_port_reset(musb, true);
585 +               while (time_before(jiffies, musb->rh_timer))
586 +                       msleep(1);
587 +               musb_port_reset(musb, false);
588 +
589 +               break;
590 +               
591 +  case 'r':
592 +               usb_hcd_resume_root_hub(hcd);
593 +               break;
594 +
595 +  case 'e':
596 +               if(bus) 
597 +                       usb_bus_start_enum(bus,bus->otg_port);
598 +               break;
599 +
600 +       case 'U':
601 +               /*Suspend*/
602 +               musb_port_suspend(musb, true);
603 +               break;
604 +
605 +       case 'u':
606 +               /*Resume*/
607 +               musb_port_suspend(musb, false);
608 +               /*How to end sanely? */
609 +               musb_port_reset(musb, true);
610 +               while (time_before(jiffies, musb->rh_timer))
611 +                       msleep(1);
612 +               musb_port_reset(musb, false);
613 +
614 +       break;
615 +
616         case '?':
617                 INFO("?: you are seeing it\n");
618                 INFO("C/c: soft connect enable/disable\n");
619 @@ -695,6 +836,7 @@
620  
621         musb_platform_try_idle(musb, 0);
622  
623 +
624         return count;
625  }
626  
627 @@ -709,6 +851,8 @@
628  
629         count -= off;
630         count -= 1;             /* for NUL at end */
631 +       count -= 20; /* Padding */
632 +
633         if (count <= 0)
634                 return -EINVAL;
635  
636 @@ -720,6 +864,9 @@
637                 count -= code;
638         }
639  
640 +       if (count < 0)
641 +               goto done;
642 +
643         /* generate the report for the end points */
644         /* REVISIT ... not unless something's connected! */
645         for (epnum = 0; count >= 0 && epnum < musb->nr_endpoints;
646 @@ -728,14 +875,22 @@
647                 if (code > 0) {
648                         buffer += code;
649                         count -= code;
650 +                       if (count < 0)
651 +                               goto done;
652                 }
653         }
654  
655 +
656 + done:
657 +
658         musb_platform_try_idle(musb, 0);
659  
660         spin_unlock_irqrestore(&musb->lock, flags);
661         *eof = 1;
662  
663 +       if(count < 0)
664 +               return -EINVAL;
665 +
666         return buffer - page;
667  }
668  
669 --- kernel-power-2.6.28.orig/drivers/usb/musb/musb_virthub.c
670 +++ kernel-power-2.6.28/drivers/usb/musb/musb_virthub.c
671 @@ -46,7 +46,7 @@
672  #include "musb_core.h"
673  
674  
675 -static void musb_port_suspend(struct musb *musb, bool do_suspend)
676 +void musb_port_suspend(struct musb *musb, bool do_suspend)
677  {
678         u8              power;
679         void __iomem    *mbase = musb->mregs;
680 @@ -106,11 +106,13 @@
681  
682                 /* later, GetPortStatus will stop RESUME signaling */
683                 musb->port1_status |= MUSB_PORT_STAT_RESUME;
684 -               musb->rh_timer = jiffies + msecs_to_jiffies(20);
685 +               /*OMAP documentation states range of 10-15 ms */
686 +               musb->rh_timer = jiffies + msecs_to_jiffies(13);
687 +               //              musb->rh_timer = jiffies + msecs_to_jiffies(20);
688         }
689  }
690  
691 -static void musb_port_reset(struct musb *musb, bool do_reset)
692 +void musb_port_reset(struct musb *musb, bool do_reset)
693  {
694         u8              power;
695         void __iomem    *mbase = musb->mregs;
696 @@ -131,7 +133,7 @@
697          */
698         power = musb_readb(mbase, MUSB_POWER);
699         if (do_reset) {
700 -
701 +               DBG(4, "root port reset started\n");
702                 /*
703                  * If RESUME is set, we must make sure it stays minimum 20 ms.
704                  * Then we must clear RESUME and wait a bit to let musb start
705 --- kernel-power-2.6.28.orig/drivers/usb/musb/omap2430.c
706 +++ kernel-power-2.6.28/drivers/usb/musb/omap2430.c
707 @@ -77,11 +77,14 @@
708  
709         switch (musb->xceiv->state) {
710         case OTG_STATE_A_WAIT_BCON:
711 +               if(host_mode(musb->mregs))
712 +                       break; /*Don't time out*/
713 +
714                 devctl &= ~MUSB_DEVCTL_SESSION;
715                 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
716  
717                 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
718 -               if (devctl & MUSB_DEVCTL_BDEVICE) {
719 +               if (!host_mode(musb->mregs)) {
720                         musb->xceiv->state = OTG_STATE_B_IDLE;
721                         MUSB_DEV_MODE(musb);
722                 } else {
723 @@ -109,11 +112,14 @@
724  #endif
725  #ifdef CONFIG_USB_MUSB_HDRC_HCD
726         case OTG_STATE_A_HOST:
727 +
728 +
729                 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
730 -               if (devctl &  MUSB_DEVCTL_BDEVICE)
731 +               if (!host_mode(musb->mregs))
732                         musb->xceiv->state = OTG_STATE_B_IDLE;
733 -               else
734 -                       musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
735 +               /*Don't time out if host*/
736 +               //              else
737 +               //      musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
738  #endif
739         default:
740                 break;
741 @@ -133,7 +139,7 @@
742         /* Never idle if active, or when VBUS timeout is not set as host */
743         if (musb->is_active || ((musb->a_wait_bcon == 0)
744                         && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) {
745 -               DBG(4, "%s active, deleting timer\n", otg_state_string(musb));
746 +               DBG(6, "%s active, deleting timer\n", otg_state_string(musb));
747                 del_timer(&musb_idle_timer);
748                 last_timer = jiffies;
749                 return;
750 @@ -143,13 +149,13 @@
751                 if (!timer_pending(&musb_idle_timer))
752                         last_timer = timeout;
753                 else {
754 -                       DBG(4, "Longer idle timer already pending, ignoring\n");
755 +                       DBG(6, "Longer idle timer already pending, ignoring\n");
756                         return;
757                 }
758         }
759         last_timer = timeout;
760  
761 -       DBG(4, "%s inactive, for idle timer for %lu ms\n",
762 +       DBG(6, "%s inactive, for idle timer for %lu ms\n",
763                 otg_state_string(musb),
764                 (unsigned long)jiffies_to_msecs(timeout - jiffies));
765         mod_timer(&musb_idle_timer, timeout);
766 @@ -182,8 +188,14 @@
767                 musb->xceiv->default_a = 1;
768                 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
769                 devctl |= MUSB_DEVCTL_SESSION;
770 -
771                 MUSB_HST_MODE(musb);
772 +               
773 +               if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) {
774 +                       /*Power is already applied. Skip VRISE and go directly to BCON.*/
775 +                       musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
776 +               }
777 +
778 +
779         } else {
780                 musb->is_active = 0;
781  
782 @@ -420,7 +432,7 @@
783         u8 r;
784         unsigned long   flags;
785  
786 -       DBG(3, "restoring register context\n");
787 +       DBG(3, "restoring register context for %s\n","musb_restore_ctx_and_resume");
788  
789         if (musb->board && musb->board->xceiv_power)
790                 musb->board->xceiv_power(1);
791 @@ -431,13 +443,17 @@
792         else
793                 clk_enable(musb->clock);
794  
795 -       /* Recover OTG control */
796 -       r = musb_ulpi_readb(musb->mregs, ISP1704_OTG_CTRL);
797 -       r |= ISP1704_OTG_CTRL_IDPULLUP | ISP1704_OTG_CTRL_DP_PULLDOWN;
798 -       musb_ulpi_writeb(musb->mregs, ISP1704_OTG_CTRL, r);
799 -
800 +       if(host_mode(musb->mregs)) {
801 +               musb_force_term(musb->mregs,MUSB_TERM_HOST_FULLSPEED);
802 +               r = musb_ulpi_readb(musb->mregs,ISP1704_FUNC_CTRL);
803 +       } else {
804 +               /* Recover OTG control */
805 +               r = musb_ulpi_readb(musb->mregs, ISP1704_OTG_CTRL);
806 +               r |= ISP1704_OTG_CTRL_IDPULLUP | ISP1704_OTG_CTRL_DP_PULLDOWN;
807 +               musb_ulpi_writeb(musb->mregs, ISP1704_OTG_CTRL, r);
808 +               r = ISP1704_FUNC_CTRL_FULL_SPEED;
809 +       }
810         /* Recover FUNC control */
811 -       r = ISP1704_FUNC_CTRL_FULL_SPEED;
812         r |= ISP1704_FUNC_CTRL_SUSPENDM | ISP1704_FUNC_CTRL_RESET;
813         musb_ulpi_writeb(musb->mregs, ISP1704_FUNC_CTRL, r);
814  
815 --- kernel-power-2.6.28.orig/drivers/usb/otg/otg.c
816 +++ kernel-power-2.6.28/drivers/usb/otg/otg.c
817 @@ -160,7 +160,8 @@
818  
819         /* add other match criteria here ... */
820  
821 -
822 +       return 1;
823 +       
824         /* OTG MESSAGE: report errors here, customize to match your product */
825         dev_err(&dev->dev, "device v%04x p%04x is not supported\n",
826                 le16_to_cpu(dev->descriptor.idVendor),
827 --- kernel-power-2.6.28.orig/drivers/usb/otg/twl4030-usb.c
828 +++ kernel-power-2.6.28/drivers/usb/otg/twl4030-usb.c
829 @@ -239,9 +239,9 @@
830  
831  enum linkstat {
832         USB_LINK_UNKNOWN = 0,
833 -       USB_LINK_NONE,
834 -       USB_LINK_VBUS,
835 -       USB_LINK_ID,
836 +       USB_LINK_NONE = 1,
837 +       USB_LINK_VBUS = 2,
838 +       USB_LINK_ID = 3,
839  };
840  
841  struct twl4030_usb {