diff options
author | David Brownell <dbrownell@users.sourceforge.net> | 2009-03-31 15:32:12 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-16 00:44:40 -0400 |
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 2460c3986c9..8bd6bb1b04e 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -112,6 +112,7 @@ | |||
112 | #include "davinci.h" | 112 | #include "davinci.h" |
113 | #endif | 113 | #endif |
114 | 114 | ||
115 | #define TA_WAIT_BCON(m) max_t(int, (m)->a_wait_bcon, OTG_TIME_A_WAIT_BCON) | ||
115 | 116 | ||
116 | 117 | ||
117 | unsigned musb_debug; | 118 | unsigned musb_debug; |
@@ -288,12 +289,6 @@ const char *otg_state_string(struct musb *musb) | |||
288 | #ifdef CONFIG_USB_MUSB_OTG | 289 | #ifdef CONFIG_USB_MUSB_OTG |
289 | 290 | ||
290 | /* | 291 | /* |
291 | * See also USB_OTG_1-3.pdf 6.6.5 Timers | ||
292 | * REVISIT: Are the other timers done in the hardware? | ||
293 | */ | ||
294 | #define TB_ASE0_BRST 100 /* Min 3.125 ms */ | ||
295 | |||
296 | /* | ||
297 | * Handles OTG hnp timeouts, such as b_ase0_brst | 292 | * Handles OTG hnp timeouts, such as b_ase0_brst |
298 | */ | 293 | */ |
299 | void musb_otg_timer_func(unsigned long data) | 294 | void musb_otg_timer_func(unsigned long data) |
@@ -320,10 +315,8 @@ void musb_otg_timer_func(unsigned long data) | |||
320 | spin_unlock_irqrestore(&musb->lock, flags); | 315 | spin_unlock_irqrestore(&musb->lock, flags); |
321 | } | 316 | } |
322 | 317 | ||
323 | static DEFINE_TIMER(musb_otg_timer, musb_otg_timer_func, 0, 0); | ||
324 | |||
325 | /* | 318 | /* |
326 | * Stops the B-device HNP state. Caller must take care of locking. | 319 | * Stops the HNP transition. Caller must take care of locking. |
327 | */ | 320 | */ |
328 | void musb_hnp_stop(struct musb *musb) | 321 | void musb_hnp_stop(struct musb *musb) |
329 | { | 322 | { |
@@ -661,11 +654,12 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
661 | musb_g_reset(musb); | 654 | musb_g_reset(musb); |
662 | /* FALLTHROUGH */ | 655 | /* FALLTHROUGH */ |
663 | case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */ | 656 | case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */ |
664 | DBG(1, "HNP: Setting timer as %s\n", | 657 | /* never use invalid T(a_wait_bcon) */ |
665 | otg_state_string(musb)); | 658 | DBG(1, "HNP: in %s, %d msec timeout\n", |
666 | musb_otg_timer.data = (unsigned long)musb; | 659 | otg_state_string(musb), |
667 | mod_timer(&musb_otg_timer, jiffies | 660 | TA_WAIT_BCON(musb)); |
668 | + msecs_to_jiffies(100)); | 661 | mod_timer(&musb->otg_timer, jiffies |
662 | + msecs_to_jiffies(TA_WAIT_BCON(musb))); | ||
669 | break; | 663 | break; |
670 | case OTG_STATE_A_PERIPHERAL: | 664 | case OTG_STATE_A_PERIPHERAL: |
671 | musb_hnp_stop(musb); | 665 | musb_hnp_stop(musb); |
@@ -822,9 +816,9 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, | |||
822 | #ifdef CONFIG_USB_MUSB_OTG | 816 | #ifdef CONFIG_USB_MUSB_OTG |
823 | musb->xceiv->state = OTG_STATE_B_WAIT_ACON; | 817 | musb->xceiv->state = OTG_STATE_B_WAIT_ACON; |
824 | DBG(1, "HNP: Setting timer for b_ase0_brst\n"); | 818 | DBG(1, "HNP: Setting timer for b_ase0_brst\n"); |
825 | musb_otg_timer.data = (unsigned long)musb; | 819 | mod_timer(&musb->otg_timer, jiffies |
826 | mod_timer(&musb_otg_timer, jiffies | 820 | + msecs_to_jiffies( |
827 | + msecs_to_jiffies(TB_ASE0_BRST)); | 821 | OTG_TIME_B_ASE0_BRST)); |
828 | #endif | 822 | #endif |
829 | } | 823 | } |
830 | break; | 824 | break; |
@@ -1681,7 +1675,8 @@ musb_vbus_store(struct device *dev, struct device_attribute *attr, | |||
1681 | } | 1675 | } |
1682 | 1676 | ||
1683 | spin_lock_irqsave(&musb->lock, flags); | 1677 | spin_lock_irqsave(&musb->lock, flags); |
1684 | musb->a_wait_bcon = val; | 1678 | /* force T(a_wait_bcon) to be zero/unlimited *OR* valid */ |
1679 | musb->a_wait_bcon = val ? max_t(int, val, OTG_TIME_A_WAIT_BCON) : 0 ; | ||
1685 | if (musb->xceiv->state == OTG_STATE_A_WAIT_BCON) | 1680 | if (musb->xceiv->state == OTG_STATE_A_WAIT_BCON) |
1686 | musb->is_active = 0; | 1681 | musb->is_active = 0; |
1687 | musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(val)); | 1682 | 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) | |||
1700 | 1695 | ||
1701 | spin_lock_irqsave(&musb->lock, flags); | 1696 | spin_lock_irqsave(&musb->lock, flags); |
1702 | val = musb->a_wait_bcon; | 1697 | val = musb->a_wait_bcon; |
1698 | /* FIXME get_vbus_status() is normally #defined as false... | ||
1699 | * and is effectively TUSB-specific. | ||
1700 | */ | ||
1703 | vbus = musb_platform_get_vbus_status(musb); | 1701 | vbus = musb_platform_get_vbus_status(musb); |
1704 | spin_unlock_irqrestore(&musb->lock, flags); | 1702 | spin_unlock_irqrestore(&musb->lock, flags); |
1705 | 1703 | ||
1706 | return sprintf(buf, "Vbus %s, timeout %lu\n", | 1704 | return sprintf(buf, "Vbus %s, timeout %lu msec\n", |
1707 | vbus ? "on" : "off", val); | 1705 | vbus ? "on" : "off", val); |
1708 | } | 1706 | } |
1709 | static DEVICE_ATTR(vbus, 0644, musb_vbus_show, musb_vbus_store); | 1707 | static DEVICE_ATTR(vbus, 0644, musb_vbus_show, musb_vbus_store); |
@@ -1776,6 +1774,7 @@ allocate_instance(struct device *dev, | |||
1776 | hcd->uses_new_polling = 1; | 1774 | hcd->uses_new_polling = 1; |
1777 | 1775 | ||
1778 | musb->vbuserr_retry = VBUSERR_RETRY_COUNT; | 1776 | musb->vbuserr_retry = VBUSERR_RETRY_COUNT; |
1777 | musb->a_wait_bcon = OTG_TIME_A_WAIT_BCON; | ||
1779 | #else | 1778 | #else |
1780 | musb = kzalloc(sizeof *musb, GFP_KERNEL); | 1779 | musb = kzalloc(sizeof *musb, GFP_KERNEL); |
1781 | if (!musb) | 1780 | if (!musb) |
@@ -1970,6 +1969,10 @@ bad_config: | |||
1970 | if (status < 0) | 1969 | if (status < 0) |
1971 | goto fail2; | 1970 | goto fail2; |
1972 | 1971 | ||
1972 | #ifdef CONFIG_USB_OTG | ||
1973 | setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb); | ||
1974 | #endif | ||
1975 | |||
1973 | /* Init IRQ workqueue before request_irq */ | 1976 | /* Init IRQ workqueue before request_irq */ |
1974 | INIT_WORK(&musb->irq_work, musb_irq_work); | 1977 | INIT_WORK(&musb->irq_work, musb_irq_work); |
1975 | 1978 | ||