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 | |
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')
-rw-r--r-- | drivers/usb/musb/musb_core.c | 41 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.h | 14 | ||||
-rw-r--r-- | drivers/usb/musb/omap2430.c | 2 |
3 files changed, 33 insertions, 24 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 @@ | |||
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 | ||
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 2b49c989f043..78116fdb5781 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/interrupt.h> | 40 | #include <linux/interrupt.h> |
41 | #include <linux/smp_lock.h> | 41 | #include <linux/smp_lock.h> |
42 | #include <linux/errno.h> | 42 | #include <linux/errno.h> |
43 | #include <linux/timer.h> | ||
43 | #include <linux/clk.h> | 44 | #include <linux/clk.h> |
44 | #include <linux/device.h> | 45 | #include <linux/device.h> |
45 | #include <linux/usb/ch9.h> | 46 | #include <linux/usb/ch9.h> |
@@ -180,10 +181,15 @@ enum musb_g_ep0_state { | |||
180 | MUSB_EP0_STAGE_ACKWAIT, /* after zlp, before statusin */ | 181 | MUSB_EP0_STAGE_ACKWAIT, /* after zlp, before statusin */ |
181 | } __attribute__ ((packed)); | 182 | } __attribute__ ((packed)); |
182 | 183 | ||
183 | /* OTG protocol constants */ | 184 | /* |
185 | * OTG protocol constants. See USB OTG 1.3 spec, | ||
186 | * sections 5.5 "Device Timings" and 6.6.5 "Timers". | ||
187 | */ | ||
184 | #define OTG_TIME_A_WAIT_VRISE 100 /* msec (max) */ | 188 | #define OTG_TIME_A_WAIT_VRISE 100 /* msec (max) */ |
185 | #define OTG_TIME_A_WAIT_BCON 0 /* 0=infinite; min 1000 msec */ | 189 | #define OTG_TIME_A_WAIT_BCON 1100 /* min 1 second */ |
186 | #define OTG_TIME_A_IDLE_BDIS 200 /* msec (min) */ | 190 | #define OTG_TIME_A_AIDL_BDIS 200 /* min 200 msec */ |
191 | #define OTG_TIME_B_ASE0_BRST 100 /* min 3.125 ms */ | ||
192 | |||
187 | 193 | ||
188 | /*************************** REGISTER ACCESS ********************************/ | 194 | /*************************** REGISTER ACCESS ********************************/ |
189 | 195 | ||
@@ -332,6 +338,8 @@ struct musb { | |||
332 | struct list_head control; /* of musb_qh */ | 338 | struct list_head control; /* of musb_qh */ |
333 | struct list_head in_bulk; /* of musb_qh */ | 339 | struct list_head in_bulk; /* of musb_qh */ |
334 | struct list_head out_bulk; /* of musb_qh */ | 340 | struct list_head out_bulk; /* of musb_qh */ |
341 | |||
342 | struct timer_list otg_timer; | ||
335 | #endif | 343 | #endif |
336 | 344 | ||
337 | /* called with IRQs blocked; ON/nonzero implies starting a session, | 345 | /* called with IRQs blocked; ON/nonzero implies starting a session, |
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index a2f443859358..48930f25c450 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #define get_cpu_rev() 2 | 44 | #define get_cpu_rev() 2 |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | #define MUSB_TIMEOUT_A_WAIT_BCON 1100 | ||
48 | 47 | ||
49 | static struct timer_list musb_idle_timer; | 48 | static struct timer_list musb_idle_timer; |
50 | 49 | ||
@@ -245,7 +244,6 @@ int __init musb_platform_init(struct musb *musb) | |||
245 | 244 | ||
246 | if (is_host_enabled(musb)) | 245 | if (is_host_enabled(musb)) |
247 | musb->board_set_vbus = omap_set_vbus; | 246 | musb->board_set_vbus = omap_set_vbus; |
248 | musb->a_wait_bcon = MUSB_TIMEOUT_A_WAIT_BCON; | ||
249 | 247 | ||
250 | setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); | 248 | setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); |
251 | 249 | ||