diff options
author | David Brownell <dbrownell@users.sourceforge.net> | 2009-03-31 12:32:12 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-15 21:44:40 -0700 |
commit | f7f9d63eac12b345d6243d1d608b7944a05be921 (patch) | |
tree | 4e4ca31d12739260656c2487babde560999c6eec /drivers/usb/musb/musb_core.c | |
parent | 84e250ffa76dddc1bad84e04248a27f442c25986 (diff) |
musb: otg timer cleanup
Minor cleanup of OTG timer handling:
* unify decls for OTG time constants, in the core header
* set up and use that timer in a more normal way
* move to the driver struct, so it's usable outside core
And tighten use and setup of T(a_wait_bcon) so that if it's used,
it's always valid. (If that timer expires, the A-device will
stop powering VBUS. For non-OTG systems, that will be a surprise.)
No behavioral changes, other than more consistency when applying
that core HNP timeout.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/musb/musb_core.c')
-rw-r--r-- | drivers/usb/musb/musb_core.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 2460c3986c96..8bd6bb1b04ef 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -112,6 +112,7 @@ #include "davinci.h" #endif +#define TA_WAIT_BCON(m) max_t(int, (m)->a_wait_bcon, OTG_TIME_A_WAIT_BCON) unsigned musb_debug; @@ -288,12 +289,6 @@ const char *otg_state_string(struct musb *musb) #ifdef CONFIG_USB_MUSB_OTG /* - * See also USB_OTG_1-3.pdf 6.6.5 Timers - * REVISIT: Are the other timers done in the hardware? - */ -#define TB_ASE0_BRST 100 /* Min 3.125 ms */ - -/* * Handles OTG hnp timeouts, such as b_ase0_brst */ void musb_otg_timer_func(unsigned long data) @@ -320,10 +315,8 @@ void musb_otg_timer_func(unsigned long data) spin_unlock_irqrestore(&musb->lock, flags); } -static DEFINE_TIMER(musb_otg_timer, musb_otg_timer_func, 0, 0); - /* - * Stops the B-device HNP state. Caller must take care of locking. + * Stops the HNP transition. Caller must take care of locking. */ void musb_hnp_stop(struct musb *musb) { @@ -661,11 +654,12 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, musb_g_reset(musb); /* FALLTHROUGH */ case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */ - DBG(1, "HNP: Setting timer as %s\n", - otg_state_string(musb)); - musb_otg_timer.data = (unsigned long)musb; - mod_timer(&musb_otg_timer, jiffies - + msecs_to_jiffies(100)); + /* never use invalid T(a_wait_bcon) */ + DBG(1, "HNP: in %s, %d msec timeout\n", + otg_state_string(musb), + TA_WAIT_BCON(musb)); + mod_timer(&musb->otg_timer, jiffies + + msecs_to_jiffies(TA_WAIT_BCON(musb))); break; case OTG_STATE_A_PERIPHERAL: musb_hnp_stop(musb); @@ -822,9 +816,9 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, #ifdef CONFIG_USB_MUSB_OTG musb->xceiv->state = OTG_STATE_B_WAIT_ACON; DBG(1, "HNP: Setting timer for b_ase0_brst\n"); - musb_otg_timer.data = (unsigned long)musb; - mod_timer(&musb_otg_timer, jiffies - + msecs_to_jiffies(TB_ASE0_BRST)); + mod_timer(&musb->otg_timer, jiffies + + msecs_to_jiffies( + OTG_TIME_B_ASE0_BRST)); #endif } break; @@ -1681,7 +1675,8 @@ musb_vbus_store(struct device *dev, struct device_attribute *attr, } spin_lock_irqsave(&musb->lock, flags); - musb->a_wait_bcon = val; + /* force T(a_wait_bcon) to be zero/unlimited *OR* valid */ + musb->a_wait_bcon = val ? max_t(int, val, OTG_TIME_A_WAIT_BCON) : 0 ; if (musb->xceiv->state == OTG_STATE_A_WAIT_BCON) musb->is_active = 0; musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(val)); @@ -1700,10 +1695,13 @@ musb_vbus_show(struct device *dev, struct device_attribute *attr, char *buf) spin_lock_irqsave(&musb->lock, flags); val = musb->a_wait_bcon; + /* FIXME get_vbus_status() is normally #defined as false... + * and is effectively TUSB-specific. + */ vbus = musb_platform_get_vbus_status(musb); spin_unlock_irqrestore(&musb->lock, flags); - return sprintf(buf, "Vbus %s, timeout %lu\n", + return sprintf(buf, "Vbus %s, timeout %lu msec\n", vbus ? "on" : "off", val); } static DEVICE_ATTR(vbus, 0644, musb_vbus_show, musb_vbus_store); @@ -1776,6 +1774,7 @@ allocate_instance(struct device *dev, hcd->uses_new_polling = 1; musb->vbuserr_retry = VBUSERR_RETRY_COUNT; + musb->a_wait_bcon = OTG_TIME_A_WAIT_BCON; #else musb = kzalloc(sizeof *musb, GFP_KERNEL); if (!musb) @@ -1970,6 +1969,10 @@ bad_config: if (status < 0) goto fail2; +#ifdef CONFIG_USB_OTG + setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb); +#endif + /* Init IRQ workqueue before request_irq */ INIT_WORK(&musb->irq_work, musb_irq_work); |