summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-rp-2.6.24/pxa2xx_udc-clock.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-kernel/linux/linux-rp-2.6.24/pxa2xx_udc-clock.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.24/pxa2xx_udc-clock.patch221
1 files changed, 221 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.24/pxa2xx_udc-clock.patch b/meta/recipes-kernel/linux/linux-rp-2.6.24/pxa2xx_udc-clock.patch
new file mode 100644
index 0000000000..14c496a31a
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.24/pxa2xx_udc-clock.patch
@@ -0,0 +1,221 @@
1---
2 drivers/usb/gadget/pxa2xx_udc.c | 88 ++++++++++++++++++++++------------------
3 drivers/usb/gadget/pxa2xx_udc.h | 4 +
4 2 files changed, 53 insertions(+), 39 deletions(-)
5
6--- g26.orig/drivers/usb/gadget/pxa2xx_udc.c 2008-02-19 12:47:06.000000000 -0800
7+++ g26/drivers/usb/gadget/pxa2xx_udc.c 2008-02-19 14:07:17.000000000 -0800
8@@ -103,6 +103,12 @@ static const char ep0name [] = "ep0";
9 #error "Can't configure both IXP and PXA"
10 #endif
11
12+/* IXP doesn't yet support <linux/clk.h> */
13+#define clk_get(dev,name) NULL
14+#define clk_enable(clk) do { } while (0)
15+#define clk_disable(clk) do { } while (0)
16+#define clk_put(clk) do { } while (0)
17+
18 #endif
19
20 #include "pxa2xx_udc.h"
21@@ -934,20 +940,31 @@ static void udc_disable(struct pxa2xx_ud
22 /* We disable the UDC -- and its 48 MHz clock -- whenever it's not
23 * in active use.
24 */
25-static int pullup(struct pxa2xx_udc *udc, int is_active)
26+static int pullup(struct pxa2xx_udc *udc)
27 {
28- is_active = is_active && udc->vbus && udc->pullup;
29+ int is_active = udc->vbus && udc->pullup && !udc->suspended;
30 DMSG("%s\n", is_active ? "active" : "inactive");
31- if (is_active)
32- udc_enable(udc);
33- else {
34- if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
35- DMSG("disconnect %s\n", udc->driver
36- ? udc->driver->driver.name
37- : "(no driver)");
38- stop_activity(udc, udc->driver);
39+ if (is_active) {
40+ if (!udc->active) {
41+ udc->active = 1;
42+ /* Enable clock for USB device */
43+ clk_enable(udc->clk);
44+ udc_enable(udc);
45 }
46- udc_disable(udc);
47+ } else {
48+ if (udc->active) {
49+ if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
50+ DMSG("disconnect %s\n", udc->driver
51+ ? udc->driver->driver.name
52+ : "(no driver)");
53+ stop_activity(udc, udc->driver);
54+ }
55+ udc_disable(udc);
56+ /* Disable clock for USB device */
57+ clk_disable(udc->clk);
58+ udc->active = 0;
59+ }
60+
61 }
62 return 0;
63 }
64@@ -958,9 +975,9 @@ static int pxa2xx_udc_vbus_session(struc
65 struct pxa2xx_udc *udc;
66
67 udc = container_of(_gadget, struct pxa2xx_udc, gadget);
68- udc->vbus = is_active = (is_active != 0);
69+ udc->vbus = (is_active != 0);
70 DMSG("vbus %s\n", is_active ? "supplied" : "inactive");
71- pullup(udc, is_active);
72+ pullup(udc);
73 return 0;
74 }
75
76@@ -975,9 +992,8 @@ static int pxa2xx_udc_pullup(struct usb_
77 if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
78 return -EOPNOTSUPP;
79
80- is_active = (is_active != 0);
81- udc->pullup = is_active;
82- pullup(udc, is_active);
83+ udc->pullup = (is_active != 0);
84+ pullup(udc);
85 return 0;
86 }
87
88@@ -1146,11 +1162,6 @@ static void udc_disable(struct pxa2xx_ud
89
90 udc_clear_mask_UDCCR(UDCCR_UDE);
91
92-#ifdef CONFIG_ARCH_PXA
93- /* Disable clock for USB device */
94- clk_disable(dev->clk);
95-#endif
96-
97 ep0_idle (dev);
98 dev->gadget.speed = USB_SPEED_UNKNOWN;
99 }
100@@ -1191,11 +1202,6 @@ static void udc_enable (struct pxa2xx_ud
101 {
102 udc_clear_mask_UDCCR(UDCCR_UDE);
103
104-#ifdef CONFIG_ARCH_PXA
105- /* Enable clock for USB device */
106- clk_enable(dev->clk);
107-#endif
108-
109 /* try to clear these bits before we enable the udc */
110 udc_ack_int_UDCCR(UDCCR_SUSIR|/*UDCCR_RSTIR|*/UDCCR_RESIR);
111
112@@ -1286,7 +1292,7 @@ fail:
113 * for set_configuration as well as eventual disconnect.
114 */
115 DMSG("registered gadget driver '%s'\n", driver->driver.name);
116- pullup(dev, 1);
117+ pullup(dev);
118 dump_state(dev);
119 return 0;
120 }
121@@ -1329,7 +1335,8 @@ int usb_gadget_unregister_driver(struct
122 return -EINVAL;
123
124 local_irq_disable();
125- pullup(dev, 0);
126+ dev->pullup = 0;
127+ pullup(dev);
128 stop_activity(dev, driver);
129 local_irq_enable();
130
131@@ -2131,13 +2138,11 @@ static int __init pxa2xx_udc_probe(struc
132 if (irq < 0)
133 return -ENODEV;
134
135-#ifdef CONFIG_ARCH_PXA
136 dev->clk = clk_get(&pdev->dev, "UDCCLK");
137 if (IS_ERR(dev->clk)) {
138 retval = PTR_ERR(dev->clk);
139 goto err_clk;
140 }
141-#endif
142
143 pr_debug("%s: IRQ %d%s%s\n", driver_name, irq,
144 dev->has_cfr ? "" : " (!cfr)",
145@@ -2250,10 +2255,8 @@ lubbock_fail0:
146 if (dev->mach->gpio_vbus)
147 gpio_free(dev->mach->gpio_vbus);
148 err_gpio_vbus:
149-#ifdef CONFIG_ARCH_PXA
150 clk_put(dev->clk);
151 err_clk:
152-#endif
153 return retval;
154 }
155
156@@ -2269,7 +2272,9 @@ static int __exit pxa2xx_udc_remove(stru
157 if (dev->driver)
158 return -EBUSY;
159
160- udc_disable(dev);
161+ dev->pullup = 0;
162+ pullup(dev);
163+
164 remove_proc_files();
165
166 if (dev->got_irq) {
167@@ -2289,9 +2294,7 @@ static int __exit pxa2xx_udc_remove(stru
168 if (dev->mach->gpio_pullup)
169 gpio_free(dev->mach->gpio_pullup);
170
171-#ifdef CONFIG_ARCH_PXA
172 clk_put(dev->clk);
173-#endif
174
175 platform_set_drvdata(pdev, NULL);
176 the_controller = NULL;
177@@ -2317,10 +2320,15 @@ static int __exit pxa2xx_udc_remove(stru
178 static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state)
179 {
180 struct pxa2xx_udc *udc = platform_get_drvdata(dev);
181+ unsigned long flags;
182
183 if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
184 WARN("USB host won't detect disconnect!\n");
185- pullup(udc, 0);
186+ udc->suspended = 1;
187+
188+ local_irq_save(flags);
189+ pullup(udc);
190+ local_irq_restore(flags);
191
192 return 0;
193 }
194@@ -2328,8 +2336,12 @@ static int pxa2xx_udc_suspend(struct pla
195 static int pxa2xx_udc_resume(struct platform_device *dev)
196 {
197 struct pxa2xx_udc *udc = platform_get_drvdata(dev);
198+ unsigned long flags;
199
200- pullup(udc, 1);
201+ udc->suspended = 0;
202+ local_irq_save(flags);
203+ pullup(udc);
204+ local_irq_restore(flags);
205
206 return 0;
207 }
208--- g26.orig/drivers/usb/gadget/pxa2xx_udc.h 2008-02-19 12:47:06.000000000 -0800
209+++ g26/drivers/usb/gadget/pxa2xx_udc.h 2008-02-19 12:57:42.000000000 -0800
210@@ -119,7 +119,9 @@ struct pxa2xx_udc {
211 has_cfr : 1,
212 req_pending : 1,
213 req_std : 1,
214- req_config : 1;
215+ req_config : 1,
216+ suspended : 1,
217+ active : 1;
218
219 #define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200))
220 struct timer_list timer;
221-