aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0029-musb-support-disconnect-after-HNP-roleswitch.patch
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0029-musb-support-disconnect-after-HNP-roleswitch.patch
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadopenembedded-core-contrib-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0029-musb-support-disconnect-after-HNP-roleswitch.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0029-musb-support-disconnect-after-HNP-roleswitch.patch145
1 files changed, 145 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0029-musb-support-disconnect-after-HNP-roleswitch.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0029-musb-support-disconnect-after-HNP-roleswitch.patch
new file mode 100644
index 0000000000..fc34fb983e
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0029-musb-support-disconnect-after-HNP-roleswitch.patch
@@ -0,0 +1,145 @@
+From 4288b7df4ae6629a4fb14aca2c489da01d4d19c3 Mon Sep 17 00:00:00 2001
+From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
+Date: Tue, 31 Mar 2009 12:35:09 -0700
+Subject: [PATCH] musb: support disconnect after HNP roleswitch
+
+Adjust HNP state machines in MUSB driver so that they handle the
+case where the cable is disconnected. The A-side machine was
+very wrong (unrecoverable); the B-Side was much less so.
+
+ - A_PERIPHERAL ... as usual, the non-observability of the ID
+ pin through Mentor's registers makes trouble. We can't go
+ directly to A_WAIT_VFALL to end the session and start the
+ disconnect processing. We can however sense link suspending,
+ go to A_WAIT_BCON, and from there use OTG timeouts to finally
+ trigger that A_WAIT_VFALL transition. (Hoping that nobody
+ reconnects quickly to that port and notices the wrong state.)
+
+ - B_HOST ... actually clear the Host Request (HR) bit as the
+ messages say, disconnect the peripheral from the root hub,
+ and don't detour through a suspend state. (In some cases
+ this would eventually have cleaned up.)
+
+Also adjust the A_SUSPEND transition to respect the A_AIDL_BDIS
+timeout, so if HNP doesn't trigger quickly enough the A_WAIT_VFALL
+transition happens as it should.
+
+Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
+---
+ drivers/usb/musb/musb_core.c | 41 +++++++++++++++++++++++++++-----------
+ drivers/usb/musb/musb_gadget.c | 2 +
+ drivers/usb/musb/musb_virthub.c | 4 +++
+ 3 files changed, 35 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
+index 9dc995a..5770ccb 100644
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -304,9 +304,11 @@ void musb_otg_timer_func(unsigned long data)
+ musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
+ musb->is_active = 0;
+ break;
++ case OTG_STATE_A_SUSPEND:
+ case OTG_STATE_A_WAIT_BCON:
+- DBG(1, "HNP: a_wait_bcon timeout; back to a_host\n");
+- musb_hnp_stop(musb);
++ DBG(1, "HNP: %s timeout\n", otg_state_string(musb));
++ musb_set_vbus(musb, 0);
++ musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
+ break;
+ default:
+ DBG(1, "HNP: Unhandled mode %s\n", otg_state_string(musb));
+@@ -324,15 +326,12 @@ void musb_hnp_stop(struct musb *musb)
+ void __iomem *mbase = musb->mregs;
+ u8 reg;
+
++ DBG(1, "HNP: stop from %s\n", otg_state_string(musb));
++
+ switch (musb->xceiv->state) {
+ case OTG_STATE_A_PERIPHERAL:
+- case OTG_STATE_A_WAIT_VFALL:
+- case OTG_STATE_A_WAIT_BCON:
+- DBG(1, "HNP: Switching back to A-host\n");
+ musb_g_disconnect(musb);
+- musb->xceiv->state = OTG_STATE_A_IDLE;
+- MUSB_HST_MODE(musb);
+- musb->is_active = 0;
++ DBG(1, "HNP: back to %s\n", otg_state_string(musb));
+ break;
+ case OTG_STATE_B_HOST:
+ DBG(1, "HNP: Disabling HR\n");
+@@ -775,7 +774,16 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb,
+ #endif /* HOST */
+ #ifdef CONFIG_USB_MUSB_OTG
+ case OTG_STATE_B_HOST:
+- musb_hnp_stop(musb);
++ /* REVISIT this behaves for "real disconnect"
++ * cases; make sure the other transitions from
++ * from B_HOST act right too. The B_HOST code
++ * in hnp_stop() is currently not used...
++ */
++ musb_root_disconnect(musb);
++ musb_to_hcd(musb)->self.is_b_host = 0;
++ musb->xceiv->state = OTG_STATE_B_PERIPHERAL;
++ MUSB_DEV_MODE(musb);
++ musb_g_disconnect(musb);
+ break;
+ case OTG_STATE_A_PERIPHERAL:
+ musb_hnp_stop(musb);
+@@ -807,10 +815,19 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb,
+ switch (musb->xceiv->state) {
+ #ifdef CONFIG_USB_MUSB_OTG
+ case OTG_STATE_A_PERIPHERAL:
+- /*
+- * We cannot stop HNP here, devctl BDEVICE might be
+- * still set.
++ /* We also come here if the cable is removed, since
++ * this silicon doesn't report ID-no-longer-grounded.
++ *
++ * We depend on T(a_wait_bcon) to shut us down, and
++ * hope users don't do anything dicey during this
++ * undesired detour through A_WAIT_BCON.
+ */
++ musb_hnp_stop(musb);
++ usb_hcd_resume_root_hub(musb_to_hcd(musb));
++ musb_root_disconnect(musb);
++ musb_platform_try_idle(musb, jiffies
++ + msecs_to_jiffies(musb->a_wait_bcon
++ ? : OTG_TIME_A_WAIT_BCON));
+ break;
+ #endif
+ case OTG_STATE_B_PERIPHERAL:
+diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
+index 7dd3d59..8b3c4e2 100644
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -1962,9 +1962,11 @@ void musb_g_disconnect(struct musb *musb)
+ DBG(2, "Unhandled disconnect %s, setting a_idle\n",
+ otg_state_string(musb));
+ musb->xceiv->state = OTG_STATE_A_IDLE;
++ MUSB_HST_MODE(musb);
+ break;
+ case OTG_STATE_A_PERIPHERAL:
+ musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
++ MUSB_HST_MODE(musb);
+ break;
+ case OTG_STATE_B_WAIT_ACON:
+ case OTG_STATE_B_HOST:
+diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c
+index 14f7cf3..e8ef925 100644
+--- a/drivers/usb/musb/musb_virthub.c
++++ b/drivers/usb/musb/musb_virthub.c
+@@ -83,6 +83,10 @@ static void musb_port_suspend(struct musb *musb, bool do_suspend)
+ musb->xceiv->state = OTG_STATE_A_SUSPEND;
+ musb->is_active = is_otg_enabled(musb)
+ && musb->xceiv->host->b_hnp_enable;
++ if (musb->is_active)
++ mod_timer(&musb->otg_timer, jiffies
++ + msecs_to_jiffies(
++ OTG_TIME_A_AIDL_BDIS));
+ musb_platform_try_idle(musb, 0);
+ break;
+ #ifdef CONFIG_USB_MUSB_OTG
+--
+1.6.0.4
+