merge of '178eac00dc5aa8338d42e8e203633bec7817bbf6'
[vuplus_openembedded] / packages / linux / linux-rp-2.6.24 / tosa / 0018-Fix-the-pxa2xx_udc-to-balance-calls-to-clk_enable-cl.patch
1 From b9a0fdbf333b461682d5da8b9aaa42f4de91ffcf Mon Sep 17 00:00:00 2001
2 From: Dmitry Baryshkov <dbaryshkov@gmail.com>
3 Date: Sun, 10 Feb 2008 03:29:17 +0300
4 Subject: [PATCH 18/64] Fix the pxa2xx_udc to balance calls to clk_enable/clk_disable
5
6 Signed-off-by: Dmitry Baryshkov dbaryshkov@gmail.com
7 ---
8  drivers/usb/gadget/pxa2xx_udc.c |   84 +++++++++++++++++++++++----------------
9  drivers/usb/gadget/pxa2xx_udc.h |    6 ++-
10  2 files changed, 54 insertions(+), 36 deletions(-)
11
12 diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
13 index 2900556..8e32d07 100644
14 --- a/drivers/usb/gadget/pxa2xx_udc.c
15 +++ b/drivers/usb/gadget/pxa2xx_udc.c
16 @@ -680,7 +680,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
17  
18         /* kickstart this i/o queue? */
19         if (list_empty(&ep->queue) && !ep->stopped) {
20 -               if (ep->desc == 0 /* ep0 */) {
21 +               if (ep->desc == NULL /* ep0 */) {
22                         unsigned        length = _req->length;
23  
24                         switch (dev->ep0state) {
25 @@ -734,7 +734,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
26         }
27  
28         /* pio or dma irq handler advances the queue. */
29 -       if (likely (req != 0))
30 +       if (likely (req != NULL))
31                 list_add_tail(&req->queue, &ep->queue);
32         local_irq_restore(flags);
33  
34 @@ -934,20 +934,35 @@ static void udc_disable(struct pxa2xx_udc *);
35  /* We disable the UDC -- and its 48 MHz clock -- whenever it's not
36   * in active use.
37   */
38 -static int pullup(struct pxa2xx_udc *udc, int is_active)
39 +static int pullup(struct pxa2xx_udc *udc)
40  {
41 -       is_active = is_active && udc->vbus && udc->pullup;
42 +       int is_active = udc->vbus && udc->pullup && ! udc->suspended;
43         DMSG("%s\n", is_active ? "active" : "inactive");
44 -       if (is_active)
45 -               udc_enable(udc);
46 -       else {
47 -               if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
48 -                       DMSG("disconnect %s\n", udc->driver
49 -                               ? udc->driver->driver.name
50 -                               : "(no driver)");
51 -                       stop_activity(udc, udc->driver);
52 +       if (is_active) {
53 +               if (!udc->active) {
54 +                       udc->active = 1;
55 +#ifdef CONFIG_ARCH_PXA
56 +                       /* Enable clock for USB device */
57 +                       clk_enable(udc->clk);
58 +#endif
59 +                       udc_enable(udc);
60                 }
61 -               udc_disable(udc);
62 +       } else {
63 +               if (udc->active) {
64 +                       if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
65 +                               DMSG("disconnect %s\n", udc->driver
66 +                                       ? udc->driver->driver.name
67 +                                       : "(no driver)");
68 +                               stop_activity(udc, udc->driver);
69 +                       }
70 +                       udc_disable(udc);
71 +#ifdef CONFIG_ARCH_PXA
72 +                       /* Disable clock for USB device */
73 +                       clk_disable(udc->clk);
74 +#endif
75 +                       udc->active = 0;
76 +               }
77 +
78         }
79         return 0;
80  }
81 @@ -958,9 +973,9 @@ static int pxa2xx_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
82         struct pxa2xx_udc       *udc;
83  
84         udc = container_of(_gadget, struct pxa2xx_udc, gadget);
85 -       udc->vbus = is_active = (is_active != 0);
86 +       udc->vbus = (is_active != 0);
87         DMSG("vbus %s\n", is_active ? "supplied" : "inactive");
88 -       pullup(udc, is_active);
89 +       pullup(udc);
90         return 0;
91  }
92  
93 @@ -975,9 +990,8 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active)
94         if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
95                 return -EOPNOTSUPP;
96  
97 -       is_active = (is_active != 0);
98 -       udc->pullup = is_active;
99 -       pullup(udc, is_active);
100 +       udc->pullup = (is_active != 0);
101 +       pullup(udc);
102         return 0;
103  }
104  
105 @@ -998,7 +1012,7 @@ static const struct usb_gadget_ops pxa2xx_udc_ops = {
106  
107  static struct pxa2xx_udc memory;
108  static int
109 -udc_seq_show(struct seq_file *m, void *d)
110 +udc_seq_show(struct seq_file *m, void *_d)
111  {
112         struct pxa2xx_udc       *dev = m->private;
113         unsigned long           flags;
114 @@ -1145,11 +1159,6 @@ static void udc_disable(struct pxa2xx_udc *dev)
115  
116         udc_clear_mask_UDCCR(UDCCR_UDE);
117  
118 -#ifdef CONFIG_ARCH_PXA
119 -        /* Disable clock for USB device */
120 -       clk_disable(dev->clk);
121 -#endif
122 -
123         ep0_idle (dev);
124         dev->gadget.speed = USB_SPEED_UNKNOWN;
125  }
126 @@ -1190,11 +1199,6 @@ static void udc_enable (struct pxa2xx_udc *dev)
127  {
128         udc_clear_mask_UDCCR(UDCCR_UDE);
129  
130 -#ifdef CONFIG_ARCH_PXA
131 -        /* Enable clock for USB device */
132 -       clk_enable(dev->clk);
133 -#endif
134 -
135         /* try to clear these bits before we enable the udc */
136         udc_ack_int_UDCCR(UDCCR_SUSIR|/*UDCCR_RSTIR|*/UDCCR_RESIR);
137  
138 @@ -1285,7 +1289,7 @@ fail:
139          * for set_configuration as well as eventual disconnect.
140          */
141         DMSG("registered gadget driver '%s'\n", driver->driver.name);
142 -       pullup(dev, 1);
143 +       pullup(dev);
144         dump_state(dev);
145         return 0;
146  }
147 @@ -1328,7 +1332,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
148                 return -EINVAL;
149  
150         local_irq_disable();
151 -       pullup(dev, 0);
152 +       dev->pullup = 0;
153 +       pullup(dev);
154         stop_activity(dev, driver);
155         local_irq_enable();
156  
157 @@ -2267,7 +2272,9 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
158         if (dev->driver)
159                 return -EBUSY;
160  
161 -       udc_disable(dev);
162 +       dev->pullup = 0;
163 +       pullup(dev);
164 +
165         remove_debug_files(dev);
166  
167         if (dev->got_irq) {
168 @@ -2315,10 +2322,15 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
169  static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state)
170  {
171         struct pxa2xx_udc       *udc = platform_get_drvdata(dev);
172 +       unsigned long flags;
173  
174         if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
175                 WARN("USB host won't detect disconnect!\n");
176 -       pullup(udc, 0);
177 +       udc->suspended = 1;
178 +
179 +       local_irq_save(flags);
180 +       pullup(udc);
181 +       local_irq_restore(flags);
182  
183         return 0;
184  }
185 @@ -2326,8 +2338,12 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state)
186  static int pxa2xx_udc_resume(struct platform_device *dev)
187  {
188         struct pxa2xx_udc       *udc = platform_get_drvdata(dev);
189 +       unsigned long flags;
190  
191 -       pullup(udc, 1);
192 +       udc->suspended = 0;
193 +       local_irq_save(flags);
194 +       pullup(udc);
195 +       local_irq_restore(flags);
196  
197         return 0;
198  }
199 diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h
200 index c08b1a2..93586b2 100644
201 --- a/drivers/usb/gadget/pxa2xx_udc.h
202 +++ b/drivers/usb/gadget/pxa2xx_udc.h
203 @@ -119,7 +119,9 @@ struct pxa2xx_udc {
204                                                 has_cfr : 1,
205                                                 req_pending : 1,
206                                                 req_std : 1,
207 -                                               req_config : 1;
208 +                                               req_config : 1,
209 +                                               suspended : 1,
210 +                                               active : 1;
211  
212  #define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200))
213         struct timer_list                       timer;
214 @@ -239,7 +241,7 @@ dump_state(struct pxa2xx_udc *dev)
215                 dev->stats.read.bytes, dev->stats.read.ops);
216  
217         for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) {
218 -               if (dev->ep [i].desc == 0)
219 +               if (dev->ep [i].desc == NULL)
220                         continue;
221                 DMSG ("udccs%d = %02x\n", i, *dev->ep->reg_udccs);
222         }
223 -- 
224 1.5.3.8
225