summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0028-musb-make-initial-HNP-roleswitch-work-v2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0028-musb-make-initial-HNP-roleswitch-work-v2.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0028-musb-make-initial-HNP-roleswitch-work-v2.patch133
1 files changed, 133 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0028-musb-make-initial-HNP-roleswitch-work-v2.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0028-musb-make-initial-HNP-roleswitch-work-v2.patch
new file mode 100644
index 0000000000..6269016223
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0028-musb-make-initial-HNP-roleswitch-work-v2.patch
@@ -0,0 +1,133 @@
1From a637c5056ef52fbb7c41eb7537a9ec3d150231ad Mon Sep 17 00:00:00 2001
2From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
3Date: Thu, 2 Apr 2009 10:16:11 -0700
4Subject: [PATCH] musb: make initial HNP roleswitch work (v2)
5
6Minor HNP bugfixes, so the initial role switch works:
7
8 - A-Device:
9 * disconnect-during-suspend enters A_PERIPHERAL state
10 * kill OTG timer after reset as A_PERIPHERAL ...
11 * ... and also pass that reset to the gadget
12 * once HNP succeeds, clear the "ignore_disconnect" flag
13 * from A_PERIPHERAL, disconnect transitions to A_WAIT_BCON
14
15 - B-Device:
16 * kill OTG timer on entry to B_HOST state (HNP succeeded)
17 * once HNP succeeds, clear "ignore_disconnect" flag
18 * kick the root hub only _after_ the state is adjusted
19
20Other state transitions are left alone. Notably, exit paths from
21the "roles have switched" state ... A_PERIPHERAL handling of that
22stays seriously broken.
23
24Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
25---
26 drivers/usb/musb/musb_core.c | 27 ++++++++++++++++-----------
27 drivers/usb/musb/musb_gadget.c | 2 +-
28 drivers/usb/musb/musb_virthub.c | 11 ++++++++++-
29 3 files changed, 27 insertions(+), 13 deletions(-)
30
31diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
32index 05c5dd3..9dc995a 100644
33--- a/drivers/usb/musb/musb_core.c
34+++ b/drivers/usb/musb/musb_core.c
35@@ -587,28 +587,23 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
36 if (devctl & MUSB_DEVCTL_LSDEV)
37 musb->port1_status |= USB_PORT_STAT_LOW_SPEED;
38
39- if (hcd->status_urb)
40- usb_hcd_poll_rh_status(hcd);
41- else
42- usb_hcd_resume_root_hub(hcd);
43-
44- MUSB_HST_MODE(musb);
45-
46 /* indicate new connection to OTG machine */
47 switch (musb->xceiv->state) {
48 case OTG_STATE_B_PERIPHERAL:
49 if (int_usb & MUSB_INTR_SUSPEND) {
50 DBG(1, "HNP: SUSPEND+CONNECT, now b_host\n");
51- musb->xceiv->state = OTG_STATE_B_HOST;
52- hcd->self.is_b_host = 1;
53 int_usb &= ~MUSB_INTR_SUSPEND;
54+ goto b_host;
55 } else
56 DBG(1, "CONNECT as b_peripheral???\n");
57 break;
58 case OTG_STATE_B_WAIT_ACON:
59- DBG(1, "HNP: Waiting to switch to b_host state\n");
60+ DBG(1, "HNP: CONNECT, now b_host\n");
61+b_host:
62 musb->xceiv->state = OTG_STATE_B_HOST;
63 hcd->self.is_b_host = 1;
64+ musb->ignore_disconnect = 0;
65+ del_timer(&musb->otg_timer);
66 break;
67 default:
68 if ((devctl & MUSB_DEVCTL_VBUS)
69@@ -618,6 +613,14 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
70 }
71 break;
72 }
73+
74+ /* poke the root hub */
75+ MUSB_HST_MODE(musb);
76+ if (hcd->status_urb)
77+ usb_hcd_poll_rh_status(hcd);
78+ else
79+ usb_hcd_resume_root_hub(hcd);
80+
81 DBG(1, "CONNECT (%s) devctl %02x\n",
82 otg_state_string(musb), devctl);
83 }
84@@ -662,7 +665,9 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,
85 + msecs_to_jiffies(TA_WAIT_BCON(musb)));
86 break;
87 case OTG_STATE_A_PERIPHERAL:
88- musb_hnp_stop(musb);
89+ musb->ignore_disconnect = 0;
90+ del_timer(&musb->otg_timer);
91+ musb_g_reset(musb);
92 break;
93 case OTG_STATE_B_WAIT_ACON:
94 DBG(1, "HNP: RESET (%s), to b_peripheral\n",
95diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
96index 2fbfba5..7dd3d59 100644
97--- a/drivers/usb/musb/musb_gadget.c
98+++ b/drivers/usb/musb/musb_gadget.c
99@@ -1964,7 +1964,7 @@ void musb_g_disconnect(struct musb *musb)
100 musb->xceiv->state = OTG_STATE_A_IDLE;
101 break;
102 case OTG_STATE_A_PERIPHERAL:
103- musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
104+ musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
105 break;
106 case OTG_STATE_B_WAIT_ACON:
107 case OTG_STATE_B_HOST:
108diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c
109index 7e7900f..14f7cf3 100644
110--- a/drivers/usb/musb/musb_virthub.c
111+++ b/drivers/usb/musb/musb_virthub.c
112@@ -187,8 +187,17 @@ void musb_root_disconnect(struct musb *musb)
113 musb->is_active = 0;
114
115 switch (musb->xceiv->state) {
116- case OTG_STATE_A_HOST:
117 case OTG_STATE_A_SUSPEND:
118+#ifdef CONFIG_USB_MUSB_OTG
119+ if (is_otg_enabled(musb)
120+ && musb->xceiv->host->b_hnp_enable) {
121+ musb->xceiv->state = OTG_STATE_A_PERIPHERAL;
122+ musb->g.is_a_peripheral = 1;
123+ break;
124+ }
125+#endif
126+ /* FALLTHROUGH */
127+ case OTG_STATE_A_HOST:
128 musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
129 musb->is_active = 0;
130 break;
131--
1321.6.0.4
133