USB: fix DWC_OTG driver compile error
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / dwc_otg_hcd_linux.c
1 /* ==========================================================================
2  * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_linux.c $
3  * $Revision: #22 $
4  * $Date: 2012/12/21 $
5  * $Change: 2131568 $
6  *
7  * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
8  * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
9  * otherwise expressly agreed to in writing between Synopsys and you.
10  *
11  * The Software IS NOT an item of Licensed Software or Licensed Product under
12  * any End User Software License Agreement or Agreement for Licensed Product
13  * with Synopsys or any supplement thereto. You are permitted to use and
14  * redistribute this Software in source and binary forms, with or without
15  * modification, provided that redistributions of source code must retain this
16  * notice. You may not view, use, disclose, copy or distribute this file or
17  * any information contained herein except pursuant to this license grant from
18  * Synopsys. If you do not agree with this notice, including the disclaimer
19  * below, then you are not authorized to use the Software.
20  *
21  * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31  * DAMAGE.
32  * ========================================================================== */
33 #ifndef DWC_DEVICE_ONLY
34
35 /**
36  * @file
37  *
38  * This file contains the implementation of the HCD. In Linux, the HCD
39  * implements the hc_driver API.
40  */
41 #include <linux/kernel.h>
42 #include <linux/module.h>
43 #include <linux/moduleparam.h>
44 #include <linux/init.h>
45 #include <linux/device.h>
46 #include <linux/errno.h>
47 #include <linux/list.h>
48 #include <linux/interrupt.h>
49 #include <linux/string.h>
50 #include <linux/dma-mapping.h>
51 #include <linux/version.h>
52 #include <asm/io.h>
53 #include <linux/usb.h>
54 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
55 #include <../drivers/usb/core/hcd.h>
56 #else
57 #include <linux/usb/hcd.h>
58 #endif
59
60 #include "dwc_otg_hcd_if.h"
61 #include "dwc_otg_dbg.h"
62 #include "dwc_otg_driver.h"
63 #include "dwc_otg_hcd.h"
64 #include "dwc_otg_attr.h"
65 #include "usbdev_rk.h"
66
67 /**
68  * Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
69  * qualified with its direction (possible 32 endpoints per device).
70  */
71 #define dwc_ep_addr_to_endpoint(_bEndpointAddress_) ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
72                                                      ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
73
74 static const char dwc_otg_hcd_name[] = "dwc_otg_hcd";
75
76 /** @name Linux HC Driver API Functions */
77 /** @{ */
78 static int urb_enqueue(struct usb_hcd *hcd,
79 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
80                        struct usb_host_endpoint *ep,
81 #endif
82                        struct urb *urb, gfp_t mem_flags);
83 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
84 static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb);
85 #else
86 static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
87 #endif
88
89 static void endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep);
90 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
91 static void endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep);
92 #endif
93 static irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd);
94 extern int hcd_start(struct usb_hcd *hcd);
95 extern void hcd_stop(struct usb_hcd *hcd);
96 extern int hcd_suspend(struct usb_hcd *hcd);
97 extern int hcd_resume(struct usb_hcd *hcd);
98 static int get_frame_number(struct usb_hcd *hcd);
99 extern int hub_status_data(struct usb_hcd *hcd, char *buf);
100 extern int hub_control(struct usb_hcd *hcd,
101                        u16 typeReq,
102                        u16 wValue, u16 wIndex, char *buf, u16 wLength);
103
104 struct wrapper_priv_data {
105         dwc_otg_hcd_t *dwc_otg_hcd;
106 };
107
108 /** @} */
109
110 static struct hc_driver dwc_otg_hc_driver = {
111
112         .description = dwc_otg_hcd_name,
113         .product_desc = "DWC OTG Controller",
114         .hcd_priv_size = sizeof(struct wrapper_priv_data),
115
116         .irq = dwc_otg_hcd_irq,
117
118         .flags = HCD_MEMORY | HCD_USB2,
119
120         //.reset =              
121         .start = hcd_start,
122         //.suspend =            
123         //.resume =             
124         .stop = hcd_stop,
125
126         .urb_enqueue = urb_enqueue,
127         .urb_dequeue = urb_dequeue,
128         .endpoint_disable = endpoint_disable,
129 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
130         .endpoint_reset = endpoint_reset,
131 #endif
132         .get_frame_number = get_frame_number,
133
134         .hub_status_data = hub_status_data,
135         .hub_control = hub_control,
136         .bus_suspend = hcd_suspend ,              
137         .bus_resume = hcd_resume,       
138 };
139
140 /** Gets the dwc_otg_hcd from a struct usb_hcd */
141 static inline dwc_otg_hcd_t *hcd_to_dwc_otg_hcd(struct usb_hcd *hcd)
142 {
143         struct wrapper_priv_data *p;
144         p = (struct wrapper_priv_data *)(hcd->hcd_priv);
145         return p->dwc_otg_hcd;
146 }
147
148 /** Gets the struct usb_hcd that contains a dwc_otg_hcd_t. */
149 inline struct usb_hcd *dwc_otg_hcd_to_hcd(dwc_otg_hcd_t * dwc_otg_hcd)
150 {
151         return dwc_otg_hcd_get_priv_data(dwc_otg_hcd);
152 }
153 EXPORT_SYMBOL(dwc_otg_hcd_to_hcd);
154
155 /** Gets the usb_host_endpoint associated with an URB. */
156 inline struct usb_host_endpoint *dwc_urb_to_endpoint(struct urb *urb)
157 {
158         struct usb_device *dev = urb->dev;
159         int ep_num = usb_pipeendpoint(urb->pipe);
160
161         if (usb_pipein(urb->pipe))
162                 return dev->ep_in[ep_num];
163         else
164                 return dev->ep_out[ep_num];
165 }
166
167 static int _disconnect(dwc_otg_hcd_t * hcd)
168 {
169         struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
170
171         usb_hcd->self.is_b_host = 0;
172         return 0;
173 }
174
175 static int _start(dwc_otg_hcd_t * hcd)
176 {
177         struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
178
179         usb_hcd->self.is_b_host = dwc_otg_hcd_is_b_host(hcd);
180         hcd_start(usb_hcd);
181
182         return 0;
183 }
184
185 static int _hub_info(dwc_otg_hcd_t * hcd, void *urb_handle, uint32_t * hub_addr,
186                      uint32_t * port_addr)
187 {
188         struct urb *urb = (struct urb *)urb_handle;
189         if (urb->dev->tt) {
190                 *hub_addr = urb->dev->tt->hub->devnum;
191         } else {
192                 *hub_addr = 0;
193         }
194         *port_addr = urb->dev->ttport;
195         return 0;
196 }
197
198 static int _speed(dwc_otg_hcd_t * hcd, void *urb_handle)
199 {
200         struct urb *urb = (struct urb *)urb_handle;
201         return urb->dev->speed;
202 }
203
204 static int _get_b_hnp_enable(dwc_otg_hcd_t * hcd)
205 {
206         struct usb_hcd *usb_hcd = dwc_otg_hcd_to_hcd(hcd);
207         return usb_hcd->self.b_hnp_enable;
208 }
209
210 static void allocate_bus_bandwidth(struct usb_hcd *hcd, uint32_t bw,
211                                    struct urb *urb)
212 {
213         hcd_to_bus(hcd)->bandwidth_allocated += bw / urb->interval;
214         if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
215                 hcd_to_bus(hcd)->bandwidth_isoc_reqs++;
216         } else {
217                 hcd_to_bus(hcd)->bandwidth_int_reqs++;
218         }
219 }
220
221 static void free_bus_bandwidth(struct usb_hcd *hcd, uint32_t bw,
222                                struct urb *urb)
223 {
224         hcd_to_bus(hcd)->bandwidth_allocated -= bw / urb->interval;
225         if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
226                 hcd_to_bus(hcd)->bandwidth_isoc_reqs--;
227         } else {
228                 hcd_to_bus(hcd)->bandwidth_int_reqs--;
229         }
230 }
231
232 /**
233  * Sets the final status of an URB and returns it to the device driver. Any
234  * required cleanup of the URB is performed.
235  */
236 static int _complete(dwc_otg_hcd_t * hcd, void *urb_handle,
237                      dwc_otg_hcd_urb_t * dwc_otg_urb, int32_t status)
238 {
239         struct urb *urb = (struct urb *)urb_handle;
240 #ifdef DEBUG
241         if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
242                 DWC_PRINTF("%s: urb %p, device %d, ep %d %s, status=%d\n",
243                            __func__, urb, usb_pipedevice(urb->pipe),
244                            usb_pipeendpoint(urb->pipe),
245                            usb_pipein(urb->pipe) ? "IN" : "OUT", status);
246                 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
247                         int i;
248                         for (i = 0; i < urb->number_of_packets; i++) {
249                                 DWC_PRINTF("  ISO Desc %d status: %d\n",
250                                            i, urb->iso_frame_desc[i].status);
251                         }
252                 }
253         }
254 #endif
255
256         urb->actual_length = dwc_otg_hcd_urb_get_actual_length(dwc_otg_urb);
257         /* Convert status value. */
258         switch (status) {
259         case -DWC_E_PROTOCOL:
260                 status = -EPROTO;
261                 break;
262         case -DWC_E_IN_PROGRESS:
263                 status = -EINPROGRESS;
264                 break;
265         case -DWC_E_PIPE:
266                 status = -EPIPE;
267                 break;
268         case -DWC_E_IO:
269                 status = -EIO;
270                 break;
271         case -DWC_E_TIMEOUT:
272                 status = -ETIMEDOUT;
273                 break;
274         case -DWC_E_OVERFLOW:
275                 status = -EOVERFLOW;
276                 break;
277         default:
278                 if (status) {
279                         DWC_PRINTF("Uknown urb status %d\n", status);
280
281                 }
282         }
283
284         if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
285                 int i;
286
287                 urb->error_count = dwc_otg_hcd_urb_get_error_count(dwc_otg_urb);
288                 for (i = 0; i < urb->number_of_packets; ++i) {
289                         urb->iso_frame_desc[i].actual_length =
290                             dwc_otg_hcd_urb_get_iso_desc_actual_length
291                             (dwc_otg_urb, i);
292                         urb->iso_frame_desc[i].status =
293                             dwc_otg_hcd_urb_get_iso_desc_status(dwc_otg_urb, i);
294                 }
295         }
296
297         urb->status = status;
298         urb->hcpriv = NULL;
299         if (!status) {
300                 if ((urb->transfer_flags & URB_SHORT_NOT_OK) &&
301                     (urb->actual_length < urb->transfer_buffer_length)) {
302                         urb->status = -EREMOTEIO;
303                 }
304         }
305
306         if ((usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) ||
307             (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) {
308                 struct usb_host_endpoint *ep = dwc_urb_to_endpoint(urb);
309                 if (ep) {
310                         free_bus_bandwidth(dwc_otg_hcd_to_hcd(hcd),
311                                            dwc_otg_hcd_get_ep_bandwidth(hcd,
312                                                                         ep->hcpriv),
313                                            urb);
314                 }
315         }
316
317         DWC_FREE(dwc_otg_urb);
318
319         DWC_SPINUNLOCK(hcd->lock);
320 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
321         usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb);
322 #else
323         usb_hcd_giveback_urb(dwc_otg_hcd_to_hcd(hcd), urb, status);
324 #endif
325         DWC_SPINLOCK(hcd->lock);
326
327         return 0;
328 }
329
330 void dwc_otg_clear_halt(struct urb *_urb)
331 {
332         struct dwc_otg_qh *_qh;
333         struct usb_host_endpoint *ep = dwc_urb_to_endpoint(_urb);
334         if((ep)&&(ep->hcpriv))
335         {
336                 _qh =  (dwc_otg_qh_t *) ep->hcpriv;
337                 _qh->data_toggle = 0;
338         }
339 }
340
341 static struct dwc_otg_hcd_function_ops hcd_fops = {
342         .start = _start,
343         .disconnect = _disconnect,
344         .hub_info = _hub_info,
345         .speed = _speed,
346         .complete = _complete,
347         .get_b_hnp_enable = _get_b_hnp_enable,
348 };
349 static void dwc_otg_hcd_enable(struct work_struct *work)
350 {
351         dwc_otg_hcd_t *dwc_otg_hcd;
352         dwc_otg_core_if_t *core_if;
353         struct dwc_otg_platform_data *pldata;
354         dwc_otg_hcd = container_of(work, dwc_otg_hcd_t, host_enable_work.work);
355         core_if = dwc_otg_hcd->core_if;
356         pldata = core_if->otg_dev->pldata;
357         if(dwc_otg_hcd->host_enabled == dwc_otg_hcd->host_setenable){
358 //      DWC_PRINT("%s, enable flag %d\n", __func__, dwc_otg_hcd->host_setenable);
359                 goto out;
360         }
361             
362         if(dwc_otg_hcd->host_setenable == 2){// enable -> disable
363                 if(pldata->get_status(USB_STATUS_DPDM)){// usb device connected
364                         dwc_otg_hcd->host_setenable = 1;
365                         goto out;
366                 }
367                 DWC_PRINTF("%s, disable host controller\n", __func__);
368 #if 0
369                 if (_core_if->hcd_cb && _core_if->hcd_cb->disconnect) {
370                 _core_if->hcd_cb->disconnect( _core_if->hcd_cb->p );
371                 }
372 #endif
373                 pldata->soft_reset();
374                 dwc_otg_disable_host_interrupts( core_if );
375                 if(pldata->phy_suspend) 
376                         pldata->phy_suspend( pldata, USB_PHY_SUSPEND);
377                 udelay(3);
378                 pldata->clock_enable( pldata, 0);
379         }else if(dwc_otg_hcd->host_setenable == 1){
380                 DWC_PRINTF("%s, enable host controller\n", __func__);
381                 pldata->clock_enable( pldata, 1);
382                 if(pldata->phy_suspend) 
383                         pldata->phy_suspend( pldata, USB_PHY_ENABLED);
384                 mdelay(5);
385                 dwc_otg_core_init(core_if);
386                 dwc_otg_enable_global_interrupts(core_if);
387                 cil_hcd_start(core_if);
388         }
389         dwc_otg_hcd->host_enabled = dwc_otg_hcd->host_setenable;
390 out:
391         return;
392 }
393 static void dwc_otg_hcd_connect_detect(unsigned long pdata)
394 {
395         dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t *)pdata;
396         dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
397         unsigned long flags;
398         struct dwc_otg_platform_data *pldata;
399         pldata = core_if->otg_dev->pldata;
400         local_irq_save(flags);
401         if(pldata->get_status(USB_STATUS_DPDM)) // usb device connected   
402         {
403                 dwc_otg_hcd->host_setenable = 1;
404         }
405         else
406         {                                   // no device, suspend host    
407         if((dwc_otg_read_hprt0(core_if) & 1) == 0)
408                 dwc_otg_hcd->host_setenable = 2;
409         }
410         if((dwc_otg_hcd->host_enabled) && (dwc_otg_hcd->host_setenable != dwc_otg_hcd->host_enabled)){
411                 schedule_delayed_work(&dwc_otg_hcd->host_enable_work, 1);
412         }
413         mod_timer(&dwc_otg_hcd->connect_detect_timer,jiffies + (HZ<<1)); 
414         local_irq_restore(flags);
415         return;
416 }
417
418 /**
419  * Initializes the HCD. This function allocates memory for and initializes the
420  * static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the
421  * USB bus with the core and calls the hc_driver->start() function. It returns
422  * a negative error on failure.
423  */
424 int otg20_hcd_init( struct platform_device *_dev )
425 {
426         struct usb_hcd *hcd = NULL;
427         dwc_otg_hcd_t *dwc_otg_hcd = NULL;
428
429         dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
430         int retval = 0;
431         int irq;
432         static u64 usb_dmamask = 0xffffffffUL;
433
434         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
435
436         /* Set device flags indicating whether the HCD supports DMA. */
437         if (dwc_otg_is_dma_enable(otg_dev->core_if)) {
438
439                 _dev->dev.dma_mask = &usb_dmamask;
440                 _dev->dev.coherent_dma_mask = ~0;
441         } else {
442
443                 _dev->dev.dma_mask = (void *)0;
444                 _dev->dev.coherent_dma_mask = 0;
445         }
446
447         /*
448          * Allocate memory for the base HCD plus the DWC OTG HCD.
449          * Initialize the base HCD.
450          */
451 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
452         hcd = usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev, _dev->dev.bus_id);
453 #else
454         hcd = usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev, dev_name(&_dev->dev));
455         hcd->has_tt = 1;
456 //      hcd->uses_new_polling = 1;
457 //      hcd->poll_rh = 0;
458 #endif
459         if (!hcd) {
460                 retval = -ENOMEM;
461                 goto error1;
462         }
463
464         hcd->regs = otg_dev->os_dep.base;
465
466         /* Initialize the DWC OTG HCD. */
467         dwc_otg_hcd = dwc_otg_hcd_alloc_hcd();
468         if (!dwc_otg_hcd) {
469                 goto error2;
470         }
471         ((struct wrapper_priv_data *)(hcd->hcd_priv))->dwc_otg_hcd =
472             dwc_otg_hcd;
473         otg_dev->hcd = dwc_otg_hcd;
474
475         if (dwc_otg_hcd_init(dwc_otg_hcd, otg_dev->core_if)) {
476                 goto error2;
477         }
478
479         otg_dev->hcd->otg_dev = otg_dev;
480         hcd->self.otg_port = dwc_otg_hcd_otg_port(dwc_otg_hcd);
481 #if 0//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) //don't support for LM(with 2.6.20.1 kernel)
482         hcd->self.otg_version = dwc_otg_get_otg_version(otg_dev->core_if);
483         /* Don't support SG list at this point */
484         hcd->self.sg_tablesize = 0;
485 #endif
486 #if 0//LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
487         /* Do not to do HNP polling if not capable */
488         if (otg_dev->core_if->otg_ver)
489                 hcd->self.is_hnp_cap = dwc_otg_get_hnpcapable(otg_dev->core_if);
490 #endif
491         /*
492          * Finish generic HCD initialization and start the HCD. This function
493          * allocates the DMA buffer pool, registers the USB bus, requests the
494          * IRQ line, and calls hcd_start method.
495          */
496         irq = platform_get_irq(_dev,0);
497         retval = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED);
498         if (retval < 0) {
499                 goto error2;
500         }
501
502         dwc_otg_hcd_set_priv_data(dwc_otg_hcd, hcd);
503         dwc_otg_hcd->host_enabled = 1;
504
505         return 0;
506
507 error2:
508         usb_put_hcd(hcd);
509 error1:
510         return retval;
511 }
512
513
514 /**
515  * Initializes the HCD. This function allocates memory for and initializes the
516  * static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the
517  * USB bus with the core and calls the hc_driver->start() function. It returns
518  * a negative error on failure.
519  */
520 int host20_hcd_init( struct platform_device *_dev )
521 {
522         struct usb_hcd *hcd = NULL;
523         dwc_otg_hcd_t *dwc_otg_hcd = NULL;
524
525         dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
526         int retval = 0;
527         int irq;
528         static u64 usb_dmamask = 0xffffffffUL; 
529         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD INIT\n");
530
531         /* Set device flags indicating whether the HCD supports DMA. */
532         if (dwc_otg_is_dma_enable(otg_dev->core_if)) {
533
534                 _dev->dev.dma_mask = &usb_dmamask;
535                 _dev->dev.coherent_dma_mask = ~0;
536         } else {
537
538                 _dev->dev.dma_mask = (void *)0;
539                 _dev->dev.coherent_dma_mask = 0;
540         }
541
542         /*
543          * Allocate memory for the base HCD plus the DWC OTG HCD.
544          * Initialize the base HCD.
545          */
546 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
547         hcd = usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev, _dev->dev.bus_id);
548 #else
549         hcd = usb_create_hcd(&dwc_otg_hc_driver, &_dev->dev, dev_name(&_dev->dev));
550         hcd->has_tt = 1;
551 //      hcd->uses_new_polling = 1;
552 //      hcd->poll_rh = 0;
553 #endif
554         if (!hcd) {
555                 retval = -ENOMEM;
556                 goto error1;
557         }
558
559         hcd->regs = otg_dev->os_dep.base;
560
561         /* Initialize the DWC OTG HCD. */
562         dwc_otg_hcd = dwc_otg_hcd_alloc_hcd();
563         if (!dwc_otg_hcd) {
564                 goto error2;
565         }
566         ((struct wrapper_priv_data *)(hcd->hcd_priv))->dwc_otg_hcd =
567             dwc_otg_hcd;
568         otg_dev->hcd = dwc_otg_hcd;
569
570         if (dwc_otg_hcd_init(dwc_otg_hcd, otg_dev->core_if)) {
571                 goto error2;
572         }
573
574         otg_dev->hcd->otg_dev = otg_dev;
575         hcd->self.otg_port = dwc_otg_hcd_otg_port(dwc_otg_hcd);
576 #if 0//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) //don't support for LM(with 2.6.20.1 kernel)
577         hcd->self.otg_version = dwc_otg_get_otg_version(otg_dev->core_if);
578         /* Don't support SG list at this point */
579         hcd->self.sg_tablesize = 0;
580 #endif
581 #if 0//LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
582         /* Do not to do HNP polling if not capable */
583         if (otg_dev->core_if->otg_ver)
584                 hcd->self.is_hnp_cap = dwc_otg_get_hnpcapable(otg_dev->core_if);
585 #endif
586         /*
587          * Finish generic HCD initialization and start the HCD. This function
588          * allocates the DMA buffer pool, registers the USB bus, requests the
589          * IRQ line, and calls hcd_start method.
590          */
591         irq = platform_get_irq(_dev,0);
592         retval = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED);
593         if (retval < 0) {
594                 goto error2;
595         }
596
597         dwc_otg_hcd_set_priv_data(dwc_otg_hcd, hcd);
598
599         dwc_otg_hcd->host_enabled = 1;
600         dwc_otg_hcd->host_setenable = 1;
601         dwc_otg_hcd->connect_detect_timer.function = dwc_otg_hcd_connect_detect;
602         dwc_otg_hcd->connect_detect_timer.data = (unsigned long)(dwc_otg_hcd);
603         init_timer( &dwc_otg_hcd->connect_detect_timer);
604         mod_timer(&dwc_otg_hcd->connect_detect_timer, jiffies+(HZ<<3)); 
605     
606         INIT_DELAYED_WORK(&dwc_otg_hcd->host_enable_work, dwc_otg_hcd_enable);
607         return 0;
608
609 error2:
610         usb_put_hcd(hcd);
611 error1:
612         return retval;
613 }
614
615 /**
616  * Removes the HCD.
617  * Frees memory and resources associated with the HCD and deregisters the bus.
618  */
619 void hcd_remove(
620
621                        struct platform_device *_dev
622     )
623 {
624
625         dwc_otg_device_t *otg_dev = dwc_get_device_platform_data(_dev);
626         dwc_otg_hcd_t *dwc_otg_hcd;
627         struct usb_hcd *hcd;
628
629         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD REMOVE\n");
630
631         if (!otg_dev) {
632                 DWC_DEBUGPL(DBG_ANY, "%s: otg_dev NULL!\n", __func__);
633                 return;
634         }
635
636         dwc_otg_hcd = otg_dev->hcd;
637
638         if (!dwc_otg_hcd) {
639                 DWC_DEBUGPL(DBG_ANY, "%s: otg_dev->hcd NULL!\n", __func__);
640                 return;
641         }
642
643         hcd = dwc_otg_hcd_to_hcd(dwc_otg_hcd);
644
645         if (!hcd) {
646                 DWC_DEBUGPL(DBG_ANY,
647                             "%s: dwc_otg_hcd_to_hcd(dwc_otg_hcd) NULL!\n",
648                             __func__);
649                 return;
650         }
651         usb_remove_hcd(hcd);
652         dwc_otg_hcd_set_priv_data(dwc_otg_hcd, NULL);
653         dwc_otg_hcd_remove(dwc_otg_hcd);
654         usb_put_hcd(hcd);
655 }
656
657 /* =========================================================================
658  *  Linux HC Driver Functions
659  * ========================================================================= */
660
661 /** Initializes the DWC_otg controller and its root hub and prepares it for host
662  * mode operation. Activates the root port. Returns 0 on success and a negative
663  * error code on failure. */
664 int hcd_start(struct usb_hcd *hcd)
665 {
666         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
667         struct usb_bus *bus;
668
669         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD START\n");
670         bus = hcd_to_bus(hcd);
671
672         hcd->state = HC_STATE_RUNNING;
673         if (dwc_otg_hcd_start(dwc_otg_hcd, &hcd_fops)) {
674                 if (dwc_otg_hcd->core_if->otg_ver)
675                         dwc_otg_hcd->core_if->op_state = B_PERIPHERAL;
676                 return 0;
677         }
678
679         /* Initialize and connect root hub if one is not already attached */
680         if (bus->root_hub) {
681                 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD Has Root Hub\n");
682                 /* Inform the HUB driver to resume. */
683                 usb_hcd_resume_root_hub(hcd);
684         }
685
686         return 0;
687 }
688
689 /**
690  * Halts the DWC_otg host mode operations in a clean manner. USB transfers are
691  * stopped.
692  */
693 void hcd_stop(struct usb_hcd *hcd)
694 {
695         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
696
697         dwc_otg_hcd_stop(dwc_otg_hcd);
698 }
699
700
701 static int dwc_otg_hcd_suspend(struct usb_hcd *hcd)
702 {
703         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (hcd);
704         dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
705         hprt0_data_t hprt0;
706         pcgcctl_data_t pcgcctl;
707         struct dwc_otg_platform_data *pldata;
708         pldata = core_if->otg_dev->pldata;
709
710         if(core_if->op_state == B_PERIPHERAL){
711                 DWC_PRINTF("%s, usb device mode\n", __func__);
712                 return 0;
713         }
714
715         if(!(dwc_otg_hcd->host_enabled&1))
716                 return 0;
717
718         hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
719 #ifdef CONFIG_PM_RUNTIME    
720         if((!hprt0.b.prtena) && (!hprt0.b.prtpwr))
721                 return 0;
722 #endif        
723         DWC_PRINTF("%s suspend, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
724
725         if(hprt0.b.prtconnsts){ // usb device connected
726                 if(!hprt0.b.prtsusp)
727                 {
728                         hprt0.b.prtsusp = 1;
729                         hprt0.b.prtena = 0;
730                         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
731                 }
732                 udelay(10);
733                 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
734
735                 if(!hprt0.b.prtsusp)
736                 {
737                         hprt0.b.prtsusp = 1;
738                         hprt0.b.prtena = 0;
739                         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
740                 }
741                 mdelay(5);
742
743                 pcgcctl.d32 = DWC_READ_REG32(core_if->pcgcctl);
744                 //Partial Power-Down mode not enable
745                 pcgcctl.b.pwrclmp = 0;
746                 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
747                 udelay(1);
748                 //pcgcctl.b.rstpdwnmodule = 1;//reset PDM
749                 pcgcctl.b.stoppclk = 1;//stop phy clk
750                 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
751         }
752 #if 0 //ndef CONFIG_DWC_REMOTE_WAKEUP
753         else{ //no device connect
754                 if(pldata->phy_suspend) 
755                 pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
756         }
757
758         if (pldata->clock_enable)
759                 pldata->clock_enable(pldata, 0);
760  #endif
761         udelay(3);
762
763         return 0;
764 }
765
766
767 static int dwc_otg_hcd_resume(struct usb_hcd *hcd)
768 {
769         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd (hcd);
770         dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
771         hprt0_data_t hprt0;
772         pcgcctl_data_t pcgcctl;
773         gintmsk_data_t gintmsk;
774         struct dwc_otg_platform_data *pldata;
775         pldata = core_if->otg_dev->pldata;
776         
777         if(core_if->op_state == B_PERIPHERAL){
778                 DWC_PRINTF("%s, usb device mode\n", __func__);
779                 return 0;
780         }
781
782 //#ifdef CONFIG_PM_RUNTIME    
783         if(!(dwc_otg_hcd->host_enabled&1))
784                 return 0;
785 //#endif
786
787 #if 0 //ndef CONFIG_DWC_REMOTE_WAKEUP
788         if (pldata->clock_enable) 
789                 pldata->clock_enable( pldata, 1);
790 #endif
791
792         hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0); 
793 #ifdef CONFIG_PM_RUNTIME
794         //USB HCD already resumed by remote wakeup, return now
795         if((!hprt0.b.prtsusp) && (hprt0.b.prtena))
796                 return 0;
797 #endif
798
799         //power on
800         pcgcctl.d32 = DWC_READ_REG32(core_if->pcgcctl);;
801         pcgcctl.b.stoppclk = 0;//restart phy clk
802         DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
803         udelay(1);
804         pcgcctl.b.pwrclmp = 0;//power clamp
805         DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
806         udelay(2);
807
808         gintmsk.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
809         gintmsk.b.portintr = 0;
810         DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
811         
812         hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
813
814 #ifdef CONFIG_PM_RUNTIME
815         if((!hprt0.b.prtena) && (!hprt0.b.prtpwr))
816                 return 0;
817 #endif
818         DWC_PRINTF("%s resume, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
819         
820         if(hprt0.b.prtconnsts){
821                 //hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
822                 //DWC_PRINT("%s, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
823                 hprt0.b.prtpwr = 1;    
824                 hprt0.b.prtres = 1;
825                 hprt0.b.prtena = 0;
826                 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
827                 mdelay(20);
828                 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);    
829                 //DWC_PRINT("%s, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
830                 //hprt0.d32 = 0;
831                 hprt0.b.prtpwr = 1;    
832                 hprt0.b.prtres = 0;
833                 hprt0.b.prtena = 0;
834                 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
835                 hprt0.d32 = 0;
836                 hprt0.b.prtpwr = 1;
837                 hprt0.b.prtena = 0;
838                 hprt0.b.prtconndet = 1;
839                 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
840
841                 //hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);  
842                 //DWC_PRINT("%s, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
843         
844                 mdelay(10);
845         }
846 #if 0 //ndef CONFIG_DWC_REMOTE_WAKEUP
847         else{
848                 if(pldata->phy_suspend) 
849                 pldata->phy_suspend( pldata, USB_PHY_ENABLED);
850         }
851 #endif
852         gintmsk.b.portintr = 1;
853         DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
854
855         return 0;
856 }
857
858 /** HCD Suspend */
859 int hcd_suspend(struct usb_hcd *hcd)
860 {
861         //dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
862
863         DWC_DEBUGPL(DBG_HCD, "HCD SUSPEND\n");
864
865         dwc_otg_hcd_suspend(hcd);
866
867         return 0;
868 }
869
870 /** HCD resume */
871 int hcd_resume(struct usb_hcd *hcd)
872 {
873         //dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
874
875         DWC_DEBUGPL(DBG_HCD, "HCD RESUME\n");
876         
877         dwc_otg_hcd_resume(hcd);
878
879         return 0;
880 }
881
882
883 /** Returns the current frame number. */
884 static int get_frame_number(struct usb_hcd *hcd)
885 {
886         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
887
888         return dwc_otg_hcd_get_frame_number(dwc_otg_hcd);
889 }
890
891 #ifdef DEBUG
892 static void dump_urb_info(struct urb *urb, char *fn_name)
893 {
894         DWC_PRINTF("%s, urb %p\n", fn_name, urb);
895         DWC_PRINTF("  Device address: %d\n", usb_pipedevice(urb->pipe));
896         DWC_PRINTF("  Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
897                    (usb_pipein(urb->pipe) ? "IN" : "OUT"));
898         DWC_PRINTF("  Endpoint type: %s\n", ( {
899                                              char *pipetype;
900                                              switch (usb_pipetype(urb->pipe)) {
901 case PIPE_CONTROL:
902 pipetype = "CONTROL"; break; case PIPE_BULK:
903 pipetype = "BULK"; break; case PIPE_INTERRUPT:
904 pipetype = "INTERRUPT"; break; case PIPE_ISOCHRONOUS:
905 pipetype = "ISOCHRONOUS"; break; default:
906                                              pipetype = "UNKNOWN"; break;};
907                                              pipetype;}
908                    )) ;
909         DWC_PRINTF("  Speed: %s\n", ( {
910                                      char *speed; switch (urb->dev->speed) {
911 case USB_SPEED_HIGH:
912 speed = "HIGH"; break; case USB_SPEED_FULL:
913 speed = "FULL"; break; case USB_SPEED_LOW:
914 speed = "LOW"; break; default:
915                                      speed = "UNKNOWN"; break;};
916                                      speed;}
917                    )) ;
918         DWC_PRINTF("  Max packet size: %d\n",
919                    usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
920         DWC_PRINTF("  Data buffer length: %d\n", urb->transfer_buffer_length);
921         DWC_PRINTF("  Transfer buffer: %p, Transfer DMA: %p\n",
922                    urb->transfer_buffer, (void *)urb->transfer_dma);
923         DWC_PRINTF("  Setup buffer: %p, Setup DMA: %p\n",
924                    urb->setup_packet, (void *)urb->setup_dma);
925         DWC_PRINTF("  Interval: %d\n", urb->interval);
926         if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
927                 int i;
928                 for (i = 0; i < urb->number_of_packets; i++) {
929                         DWC_PRINTF("  ISO Desc %d:\n", i);
930                         DWC_PRINTF("    offset: %d, length %d\n",
931                                    urb->iso_frame_desc[i].offset,
932                                    urb->iso_frame_desc[i].length);
933                 }
934         }
935 }
936
937 #endif
938
939 /** Starts processing a USB transfer request specified by a USB Request Block
940  * (URB). mem_flags indicates the type of memory allocation to use while
941  * processing this URB. */
942 static int urb_enqueue(struct usb_hcd *hcd,
943 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
944                        struct usb_host_endpoint *ep,
945 #endif
946                        struct urb *urb, gfp_t mem_flags)
947 {
948         int retval = 0;
949 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
950         struct usb_host_endpoint *ep = urb->ep;
951 #endif
952         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
953         dwc_otg_hcd_urb_t *dwc_otg_urb;
954         int i;
955         int alloc_bandwidth = 0;
956         uint8_t ep_type = 0;
957         uint32_t flags = 0;
958         void *buf;
959
960 #ifdef DEBUG
961         if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
962                 dump_urb_info(urb, "urb_enqueue");
963         }
964 #endif
965
966         if(atomic_read(&urb->use_count)>1){
967                 retval = -EPERM;
968                 printk("%s urb %p already in queue, qtd %p, count%d\n", 
969                         __func__, urb, urb->hcpriv, atomic_read(&urb->use_count));
970                  return retval;
971         }
972
973         if ((usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
974             || (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) {
975                 if (!dwc_otg_hcd_is_bandwidth_allocated
976                     (dwc_otg_hcd, &ep->hcpriv)) {
977                         alloc_bandwidth = 1;
978                 }
979         }
980
981         switch (usb_pipetype(urb->pipe)) {
982         case PIPE_CONTROL:
983                 ep_type = USB_ENDPOINT_XFER_CONTROL;
984                 break;
985         case PIPE_ISOCHRONOUS:
986                 ep_type = USB_ENDPOINT_XFER_ISOC;
987                 break;
988         case PIPE_BULK:
989                 ep_type = USB_ENDPOINT_XFER_BULK;
990                 break;
991         case PIPE_INTERRUPT:
992                 ep_type = USB_ENDPOINT_XFER_INT;
993                 break;
994         default:
995                 DWC_WARN("Wrong ep type\n");
996         }
997
998         dwc_otg_urb = dwc_otg_hcd_urb_alloc(dwc_otg_hcd,
999                                             urb->number_of_packets,
1000                                             mem_flags == GFP_ATOMIC ? 1 : 0);
1001
1002         dwc_otg_hcd_urb_set_pipeinfo(dwc_otg_urb, usb_pipedevice(urb->pipe),
1003                                      usb_pipeendpoint(urb->pipe), ep_type,
1004                                      usb_pipein(urb->pipe),
1005                                      usb_maxpacket(urb->dev, urb->pipe,
1006                                                    !(usb_pipein(urb->pipe))));
1007
1008         if((uint32_t)urb->transfer_buffer & 3){
1009                 DWC_PRINTF("%s urb->transfer_buffer address not align to 4-byte 0x%x\n", 
1010                           __func__, (uint32_t)urb->transfer_buffer);
1011         }
1012
1013         buf = urb->transfer_buffer;
1014
1015         if (hcd->self.uses_dma) {
1016                 /*
1017                  * Calculate virtual address from physical address,
1018                  * because some class driver may not fill transfer_buffer.
1019                  * In Buffer DMA mode virual address is used,
1020                  * when handling non DWORD aligned buffers.
1021                  */
1022                 buf = phys_to_virt(urb->transfer_dma);
1023         }
1024
1025         if (!(urb->transfer_flags & URB_NO_INTERRUPT))
1026                 flags |= URB_GIVEBACK_ASAP;
1027         if (urb->transfer_flags & URB_ZERO_PACKET)
1028                 flags |= URB_SEND_ZERO_PACKET;
1029
1030         dwc_otg_hcd_urb_set_params(dwc_otg_urb, urb, buf,
1031                                    urb->transfer_dma,
1032                                    urb->transfer_buffer_length,
1033                                    urb->setup_packet,
1034                                    urb->setup_dma, flags, urb->interval);
1035
1036         for (i = 0; i < urb->number_of_packets; ++i) {
1037                 dwc_otg_hcd_urb_set_iso_desc_params(dwc_otg_urb, i,
1038                                                     urb->
1039                                                     iso_frame_desc[i].offset,
1040                                                     urb->
1041                                                     iso_frame_desc[i].length);
1042         }
1043
1044         urb->hcpriv = dwc_otg_urb;
1045         retval = dwc_otg_hcd_urb_enqueue(dwc_otg_hcd, dwc_otg_urb, &ep->hcpriv,
1046                                          mem_flags == GFP_ATOMIC ? 1 : 0);
1047         if (!retval) {
1048                 if (alloc_bandwidth) {
1049                         allocate_bus_bandwidth(hcd,
1050                                                dwc_otg_hcd_get_ep_bandwidth
1051                                                (dwc_otg_hcd, ep->hcpriv), urb);
1052                 }
1053         } else {
1054                 if (retval == -DWC_E_NO_DEVICE) {
1055                         retval = -ENODEV;
1056                 }
1057         }
1058
1059         return retval;
1060 }
1061
1062 /** Aborts/cancels a USB transfer request. Always returns 0 to indicate
1063  * success.  */
1064 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
1065 static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
1066 #else
1067 static int urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
1068 #endif
1069 {
1070         dwc_irqflags_t flags;
1071         dwc_otg_hcd_t *dwc_otg_hcd;
1072         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD URB Dequeue\n");
1073
1074         dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
1075
1076 #ifdef DEBUG
1077         if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
1078                 dump_urb_info(urb, "urb_dequeue");
1079         }
1080 #endif
1081
1082         DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
1083
1084         if(((uint32_t)urb&0xf0000000)==0){
1085                 DWC_PRINTF("%s error: urb is %p!!!\n", __func__, urb);
1086                 goto out1;
1087         }
1088         
1089         if(((uint32_t)urb->hcpriv&0xf0000000) == 0){
1090                 DWC_PRINTF("%s error: urb->hcpriv %p urb %p, count %d!!!\n",__func__, 
1091                            urb->hcpriv, urb, atomic_read(&urb->use_count));
1092                 if((atomic_read(&urb->use_count)) == 1)
1093                         goto out2;
1094                 else{
1095                         DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
1096                         return 0;
1097                 }
1098         }
1099         
1100         dwc_otg_hcd_urb_dequeue(dwc_otg_hcd, urb->hcpriv);
1101
1102 out2:
1103         DWC_FREE(urb->hcpriv);
1104         urb->hcpriv = NULL;
1105         DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
1106
1107         /* Higher layer software sets URB status. */
1108 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
1109         usb_hcd_giveback_urb(hcd, urb);
1110 #else
1111         usb_hcd_giveback_urb(hcd, urb, status);
1112 #endif
1113         if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB)) {
1114                 DWC_PRINTF("Called usb_hcd_giveback_urb()\n");
1115                 DWC_PRINTF("  urb->status = %d\n", urb->status);
1116         }
1117 out1:
1118         return 0;
1119 }
1120
1121 /* Frees resources in the DWC_otg controller related to a given endpoint. Also
1122  * clears state in the HCD related to the endpoint. Any URBs for the endpoint
1123  * must already be dequeued. */
1124 static void endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
1125 {
1126         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
1127
1128         DWC_DEBUGPL(DBG_HCD,
1129                     "DWC OTG HCD EP DISABLE: _bEndpointAddress=0x%02x, "
1130                     "endpoint=%d\n", ep->desc.bEndpointAddress,
1131                     dwc_ep_addr_to_endpoint(ep->desc.bEndpointAddress));
1132         dwc_otg_hcd_endpoint_disable(dwc_otg_hcd, ep->hcpriv, 250);
1133         ep->hcpriv = NULL;
1134 }
1135
1136 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
1137 /* Resets endpoint specific parameter values, in current version used to reset 
1138  * the data toggle(as a WA). This function can be called from usb_clear_halt routine */
1139 static void endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
1140 {
1141         dwc_irqflags_t flags;
1142         struct usb_device *udev = NULL;
1143         int epnum = usb_endpoint_num(&ep->desc);
1144         int is_out = usb_endpoint_dir_out(&ep->desc);
1145         int is_control = usb_endpoint_xfer_control(&ep->desc);
1146         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
1147
1148         struct platform_device *_dev = dwc_otg_hcd->otg_dev->os_dep.pdev;
1149         if (_dev)
1150                 udev = to_usb_device(&_dev->dev);
1151         else
1152                 return;
1153
1154         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD EP RESET: Endpoint Num=0x%02d\n", epnum);
1155
1156         DWC_SPINLOCK_IRQSAVE(dwc_otg_hcd->lock, &flags);
1157         usb_settoggle(udev, epnum, is_out, 0);
1158         if (is_control)
1159                 usb_settoggle(udev, epnum, !is_out, 0);
1160
1161         if (ep->hcpriv) {
1162                 dwc_otg_hcd_endpoint_reset(dwc_otg_hcd, ep->hcpriv);
1163         }
1164         DWC_SPINUNLOCK_IRQRESTORE(dwc_otg_hcd->lock, flags);
1165 }
1166 #endif
1167
1168 /** Handles host mode interrupts for the DWC_otg controller. Returns IRQ_NONE if
1169  * there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
1170  * interrupt.
1171  *
1172  * This function is called by the USB core when an interrupt occurs */
1173 static irqreturn_t dwc_otg_hcd_irq(struct usb_hcd *hcd)
1174 {
1175         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
1176         int32_t retval = dwc_otg_hcd_handle_intr(dwc_otg_hcd);
1177         if (retval != 0) {
1178                 //S3C2410X_CLEAR_EINTPEND();
1179         }
1180         return IRQ_RETVAL(retval);
1181 }
1182
1183 /** Creates Status Change bitmap for the root hub and root port. The bitmap is
1184  * returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
1185  * is the status change indicator for the single root port. Returns 1 if either
1186  * change indicator is 1, otherwise returns 0. */
1187 int hub_status_data(struct usb_hcd *hcd, char *buf)
1188 {
1189         dwc_otg_hcd_t *dwc_otg_hcd = hcd_to_dwc_otg_hcd(hcd);
1190
1191         buf[0] = 0;
1192         buf[0] |= (dwc_otg_hcd_is_status_changed(dwc_otg_hcd, 1)) << 1;
1193
1194         return (buf[0] != 0);
1195 }
1196
1197 /** Handles hub class-specific requests. */
1198 int hub_control(struct usb_hcd *hcd,
1199                 u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength)
1200 {
1201         int retval;
1202
1203         retval = dwc_otg_hcd_hub_control(hcd_to_dwc_otg_hcd(hcd),
1204                                          typeReq, wValue, wIndex, buf, wLength);
1205
1206         switch (retval) {
1207         case -DWC_E_INVALID:
1208                 retval = -EINVAL;
1209                 break;
1210         }
1211
1212         return retval;
1213 }
1214
1215 #endif /* DWC_DEVICE_ONLY */