diff options
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0027-musb-otg-timer-cleanup.patch')
-rw-r--r-- | meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0027-musb-otg-timer-cleanup.patch | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0027-musb-otg-timer-cleanup.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0027-musb-otg-timer-cleanup.patch new file mode 100644 index 0000000000..f41b766cfe --- /dev/null +++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0027-musb-otg-timer-cleanup.patch | |||
@@ -0,0 +1,198 @@ | |||
1 | From b4b8c1e7604784b9877f07400ff2a718118ef05c Mon Sep 17 00:00:00 2001 | ||
2 | From: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> | ||
3 | Date: Tue, 31 Mar 2009 12:32:12 -0700 | ||
4 | Subject: [PATCH] musb: otg timer cleanup | ||
5 | |||
6 | Minor cleanup of OTG timer handling: | ||
7 | * unify decls for OTG time constants, in the core header | ||
8 | * set up and use that timer in a more normal way | ||
9 | * move to the driver struct, so it's usable outside core | ||
10 | |||
11 | And tighten use and setup of T(a_wait_bcon) so that if it's used, | ||
12 | it's always valid. (If that timer expires, the A-device will | ||
13 | stop powering VBUS. For non-OTG systems, that will be a surprise.) | ||
14 | No behavioral changes, other than more consistency when applying | ||
15 | that core HNP timeout. | ||
16 | |||
17 | Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org> | ||
18 | --- | ||
19 | drivers/usb/musb/musb_core.c | 41 ++++++++++++++++++++++------------------- | ||
20 | drivers/usb/musb/musb_core.h | 14 +++++++++++--- | ||
21 | drivers/usb/musb/omap2430.c | 2 -- | ||
22 | 3 files changed, 33 insertions(+), 24 deletions(-) | ||
23 | |||
24 | diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c | ||
25 | index ac150af..05c5dd3 100644 | ||
26 | --- a/drivers/usb/musb/musb_core.c | ||
27 | +++ b/drivers/usb/musb/musb_core.c | ||
28 | @@ -112,6 +112,7 @@ | ||
29 | #include "davinci.h" | ||
30 | #endif | ||
31 | |||
32 | +#define TA_WAIT_BCON(m) max_t(int, (m)->a_wait_bcon, OTG_TIME_A_WAIT_BCON) | ||
33 | |||
34 | |||
35 | unsigned musb_debug; | ||
36 | @@ -288,12 +289,6 @@ const char *otg_state_string(struct musb *musb) | ||
37 | #ifdef CONFIG_USB_MUSB_OTG | ||
38 | |||
39 | /* | ||
40 | - * See also USB_OTG_1-3.pdf 6.6.5 Timers | ||
41 | - * REVISIT: Are the other timers done in the hardware? | ||
42 | - */ | ||
43 | -#define TB_ASE0_BRST 100 /* Min 3.125 ms */ | ||
44 | - | ||
45 | -/* | ||
46 | * Handles OTG hnp timeouts, such as b_ase0_brst | ||
47 | */ | ||
48 | void musb_otg_timer_func(unsigned long data) | ||
49 | @@ -320,10 +315,8 @@ void musb_otg_timer_func(unsigned long data) | ||
50 | spin_unlock_irqrestore(&musb->lock, flags); | ||
51 | } | ||
52 | |||
53 | -static DEFINE_TIMER(musb_otg_timer, musb_otg_timer_func, 0, 0); | ||
54 | - | ||
55 | /* | ||
56 | - * Stops the B-device HNP state. Caller must take care of locking. | ||
57 | + * Stops the HNP transition. Caller must take care of locking. | ||
58 | */ | ||
59 | void musb_hnp_stop(struct musb *musb) | ||
60 | { | ||
61 | @@ -661,11 +654,12 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | ||
62 | musb_g_reset(musb); | ||
63 | /* FALLTHROUGH */ | ||
64 | case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */ | ||
65 | - DBG(1, "HNP: Setting timer as %s\n", | ||
66 | - otg_state_string(musb)); | ||
67 | - musb_otg_timer.data = (unsigned long)musb; | ||
68 | - mod_timer(&musb_otg_timer, jiffies | ||
69 | - + msecs_to_jiffies(100)); | ||
70 | + /* never use invalid T(a_wait_bcon) */ | ||
71 | + DBG(1, "HNP: in %s, %d msec timeout\n", | ||
72 | + otg_state_string(musb), | ||
73 | + TA_WAIT_BCON(musb)); | ||
74 | + mod_timer(&musb->otg_timer, jiffies | ||
75 | + + msecs_to_jiffies(TA_WAIT_BCON(musb))); | ||
76 | break; | ||
77 | case OTG_STATE_A_PERIPHERAL: | ||
78 | musb_hnp_stop(musb); | ||
79 | @@ -822,9 +816,9 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, | ||
80 | #ifdef CONFIG_USB_MUSB_OTG | ||
81 | musb->xceiv->state = OTG_STATE_B_WAIT_ACON; | ||
82 | DBG(1, "HNP: Setting timer for b_ase0_brst\n"); | ||
83 | - musb_otg_timer.data = (unsigned long)musb; | ||
84 | - mod_timer(&musb_otg_timer, jiffies | ||
85 | - + msecs_to_jiffies(TB_ASE0_BRST)); | ||
86 | + mod_timer(&musb->otg_timer, jiffies | ||
87 | + + msecs_to_jiffies( | ||
88 | + OTG_TIME_B_ASE0_BRST)); | ||
89 | #endif | ||
90 | } | ||
91 | break; | ||
92 | @@ -1680,7 +1674,8 @@ musb_vbus_store(struct device *dev, struct device_attribute *attr, | ||
93 | } | ||
94 | |||
95 | spin_lock_irqsave(&musb->lock, flags); | ||
96 | - musb->a_wait_bcon = val; | ||
97 | + /* force T(a_wait_bcon) to be zero/unlimited *OR* valid */ | ||
98 | + musb->a_wait_bcon = val ? max_t(int, val, OTG_TIME_A_WAIT_BCON) : 0 ; | ||
99 | if (musb->xceiv->state == OTG_STATE_A_WAIT_BCON) | ||
100 | musb->is_active = 0; | ||
101 | musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(val)); | ||
102 | @@ -1699,10 +1694,13 @@ musb_vbus_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
103 | |||
104 | spin_lock_irqsave(&musb->lock, flags); | ||
105 | val = musb->a_wait_bcon; | ||
106 | + /* FIXME get_vbus_status() is normally #defined as false... | ||
107 | + * and is effectively TUSB-specific. | ||
108 | + */ | ||
109 | vbus = musb_platform_get_vbus_status(musb); | ||
110 | spin_unlock_irqrestore(&musb->lock, flags); | ||
111 | |||
112 | - return sprintf(buf, "Vbus %s, timeout %lu\n", | ||
113 | + return sprintf(buf, "Vbus %s, timeout %lu msec\n", | ||
114 | vbus ? "on" : "off", val); | ||
115 | } | ||
116 | static DEVICE_ATTR(vbus, 0644, musb_vbus_show, musb_vbus_store); | ||
117 | @@ -1775,6 +1773,7 @@ allocate_instance(struct device *dev, | ||
118 | hcd->uses_new_polling = 1; | ||
119 | |||
120 | musb->vbuserr_retry = VBUSERR_RETRY_COUNT; | ||
121 | + musb->a_wait_bcon = OTG_TIME_A_WAIT_BCON; | ||
122 | #else | ||
123 | musb = kzalloc(sizeof *musb, GFP_KERNEL); | ||
124 | if (!musb) | ||
125 | @@ -1969,6 +1968,10 @@ bad_config: | ||
126 | if (status < 0) | ||
127 | goto fail2; | ||
128 | |||
129 | +#ifdef CONFIG_USB_OTG | ||
130 | + setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb); | ||
131 | +#endif | ||
132 | + | ||
133 | /* Init IRQ workqueue before request_irq */ | ||
134 | INIT_WORK(&musb->irq_work, musb_irq_work); | ||
135 | |||
136 | diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h | ||
137 | index c3ee348..cf3ccb0 100644 | ||
138 | --- a/drivers/usb/musb/musb_core.h | ||
139 | +++ b/drivers/usb/musb/musb_core.h | ||
140 | @@ -40,6 +40,7 @@ | ||
141 | #include <linux/interrupt.h> | ||
142 | #include <linux/smp_lock.h> | ||
143 | #include <linux/errno.h> | ||
144 | +#include <linux/timer.h> | ||
145 | #include <linux/clk.h> | ||
146 | #include <linux/device.h> | ||
147 | #include <linux/usb/ch9.h> | ||
148 | @@ -180,10 +181,15 @@ enum musb_g_ep0_state { | ||
149 | MUSB_EP0_STAGE_ACKWAIT, /* after zlp, before statusin */ | ||
150 | } __attribute__ ((packed)); | ||
151 | |||
152 | -/* OTG protocol constants */ | ||
153 | +/* | ||
154 | + * OTG protocol constants. See USB OTG 1.3 spec, | ||
155 | + * sections 5.5 "Device Timings" and 6.6.5 "Timers". | ||
156 | + */ | ||
157 | #define OTG_TIME_A_WAIT_VRISE 100 /* msec (max) */ | ||
158 | -#define OTG_TIME_A_WAIT_BCON 0 /* 0=infinite; min 1000 msec */ | ||
159 | -#define OTG_TIME_A_IDLE_BDIS 200 /* msec (min) */ | ||
160 | +#define OTG_TIME_A_WAIT_BCON 1100 /* min 1 second */ | ||
161 | +#define OTG_TIME_A_AIDL_BDIS 200 /* min 200 msec */ | ||
162 | +#define OTG_TIME_B_ASE0_BRST 100 /* min 3.125 ms */ | ||
163 | + | ||
164 | |||
165 | /*************************** REGISTER ACCESS ********************************/ | ||
166 | |||
167 | @@ -332,6 +338,8 @@ struct musb { | ||
168 | struct list_head control; /* of musb_qh */ | ||
169 | struct list_head in_bulk; /* of musb_qh */ | ||
170 | struct list_head out_bulk; /* of musb_qh */ | ||
171 | + | ||
172 | + struct timer_list otg_timer; | ||
173 | #endif | ||
174 | |||
175 | /* called with IRQs blocked; ON/nonzero implies starting a session, | ||
176 | diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c | ||
177 | index 5f67b03..3fbc807 100644 | ||
178 | --- a/drivers/usb/musb/omap2430.c | ||
179 | +++ b/drivers/usb/musb/omap2430.c | ||
180 | @@ -45,7 +45,6 @@ | ||
181 | #define get_cpu_rev() 2 | ||
182 | #endif | ||
183 | |||
184 | -#define MUSB_TIMEOUT_A_WAIT_BCON 1100 | ||
185 | |||
186 | static struct timer_list musb_idle_timer; | ||
187 | |||
188 | @@ -246,7 +245,6 @@ int __init musb_platform_init(struct musb *musb) | ||
189 | |||
190 | if (is_host_enabled(musb)) | ||
191 | musb->board_set_vbus = omap_set_vbus; | ||
192 | - musb->a_wait_bcon = MUSB_TIMEOUT_A_WAIT_BCON; | ||
193 | |||
194 | setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); | ||
195 | |||
196 | -- | ||
197 | 1.6.0.4 | ||
198 | |||