diff options
author | Anatolij Gustschin <agust@denx.de> | 2011-04-18 16:02:00 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-05-02 19:59:38 -0400 |
commit | 83722bc9430424de1614ff31696f73a40b3d81a9 (patch) | |
tree | 4ff0ffe40e080ee03b9ede04b3e943b79335335f | |
parent | 0807c500a1a6d7fa20cbd7bbe7fea14a66112463 (diff) |
USB: extend ehci-fsl and fsl_udc_core driver for OTG operation
Signed-off-by: Anatolij Gustschin <agust@denx.de>
Cc: Li Yang <leoli@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/gadget/fsl_udc_core.c | 147 | ||||
-rw-r--r-- | drivers/usb/gadget/fsl_usb2_udc.h | 2 | ||||
-rw-r--r-- | drivers/usb/host/ehci-fsl.c | 66 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 8 | ||||
-rw-r--r-- | drivers/usb/host/ehci.h | 4 | ||||
-rw-r--r-- | include/linux/fsl_devices.h | 1 |
6 files changed, 213 insertions, 15 deletions
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 28b3a9f25f3b..999eafe89653 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c | |||
@@ -353,6 +353,19 @@ static void dr_controller_stop(struct fsl_udc *udc) | |||
353 | { | 353 | { |
354 | unsigned int tmp; | 354 | unsigned int tmp; |
355 | 355 | ||
356 | pr_debug("%s\n", __func__); | ||
357 | |||
358 | /* if we're in OTG mode, and the Host is currently using the port, | ||
359 | * stop now and don't rip the controller out from under the | ||
360 | * ehci driver | ||
361 | */ | ||
362 | if (udc->gadget.is_otg) { | ||
363 | if (!(fsl_readl(&dr_regs->otgsc) & OTGSC_STS_USB_ID)) { | ||
364 | pr_debug("udc: Leaving early\n"); | ||
365 | return; | ||
366 | } | ||
367 | } | ||
368 | |||
356 | /* disable all INTR */ | 369 | /* disable all INTR */ |
357 | fsl_writel(0, &dr_regs->usbintr); | 370 | fsl_writel(0, &dr_regs->usbintr); |
358 | 371 | ||
@@ -1668,6 +1681,9 @@ static void port_change_irq(struct fsl_udc *udc) | |||
1668 | { | 1681 | { |
1669 | u32 speed; | 1682 | u32 speed; |
1670 | 1683 | ||
1684 | if (udc->bus_reset) | ||
1685 | udc->bus_reset = 0; | ||
1686 | |||
1671 | /* Bus resetting is finished */ | 1687 | /* Bus resetting is finished */ |
1672 | if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) { | 1688 | if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) { |
1673 | /* Get the speed */ | 1689 | /* Get the speed */ |
@@ -1775,6 +1791,8 @@ static void reset_irq(struct fsl_udc *udc) | |||
1775 | 1791 | ||
1776 | if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) { | 1792 | if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) { |
1777 | VDBG("Bus reset"); | 1793 | VDBG("Bus reset"); |
1794 | /* Bus is reseting */ | ||
1795 | udc->bus_reset = 1; | ||
1778 | /* Reset all the queues, include XD, dTD, EP queue | 1796 | /* Reset all the queues, include XD, dTD, EP queue |
1779 | * head and TR Queue */ | 1797 | * head and TR Queue */ |
1780 | reset_queues(udc); | 1798 | reset_queues(udc); |
@@ -1852,6 +1870,7 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc) | |||
1852 | 1870 | ||
1853 | /* Reset Received */ | 1871 | /* Reset Received */ |
1854 | if (irq_src & USB_STS_RESET) { | 1872 | if (irq_src & USB_STS_RESET) { |
1873 | VDBG("reset int"); | ||
1855 | reset_irq(udc); | 1874 | reset_irq(udc); |
1856 | status = IRQ_HANDLED; | 1875 | status = IRQ_HANDLED; |
1857 | } | 1876 | } |
@@ -1909,11 +1928,30 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
1909 | goto out; | 1928 | goto out; |
1910 | } | 1929 | } |
1911 | 1930 | ||
1912 | /* Enable DR IRQ reg and Set usbcmd reg Run bit */ | 1931 | if (udc_controller->transceiver) { |
1913 | dr_controller_run(udc_controller); | 1932 | /* Suspend the controller until OTG enable it */ |
1914 | udc_controller->usb_state = USB_STATE_ATTACHED; | 1933 | udc_controller->stopped = 1; |
1915 | udc_controller->ep0_state = WAIT_FOR_SETUP; | 1934 | printk(KERN_INFO "Suspend udc for OTG auto detect\n"); |
1916 | udc_controller->ep0_dir = 0; | 1935 | |
1936 | /* connect to bus through transceiver */ | ||
1937 | if (udc_controller->transceiver) { | ||
1938 | retval = otg_set_peripheral(udc_controller->transceiver, | ||
1939 | &udc_controller->gadget); | ||
1940 | if (retval < 0) { | ||
1941 | ERR("can't bind to transceiver\n"); | ||
1942 | driver->unbind(&udc_controller->gadget); | ||
1943 | udc_controller->gadget.dev.driver = 0; | ||
1944 | udc_controller->driver = 0; | ||
1945 | return retval; | ||
1946 | } | ||
1947 | } | ||
1948 | } else { | ||
1949 | /* Enable DR IRQ reg and set USBCMD reg Run bit */ | ||
1950 | dr_controller_run(udc_controller); | ||
1951 | udc_controller->usb_state = USB_STATE_ATTACHED; | ||
1952 | udc_controller->ep0_state = WAIT_FOR_SETUP; | ||
1953 | udc_controller->ep0_dir = 0; | ||
1954 | } | ||
1917 | printk(KERN_INFO "%s: bind to driver %s\n", | 1955 | printk(KERN_INFO "%s: bind to driver %s\n", |
1918 | udc_controller->gadget.name, driver->driver.name); | 1956 | udc_controller->gadget.name, driver->driver.name); |
1919 | 1957 | ||
@@ -2374,17 +2412,30 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2374 | spin_lock_init(&udc_controller->lock); | 2412 | spin_lock_init(&udc_controller->lock); |
2375 | udc_controller->stopped = 1; | 2413 | udc_controller->stopped = 1; |
2376 | 2414 | ||
2415 | #ifdef CONFIG_USB_OTG | ||
2416 | if (pdata->operating_mode == FSL_USB2_DR_OTG) { | ||
2417 | udc_controller->transceiver = otg_get_transceiver(); | ||
2418 | if (!udc_controller->transceiver) { | ||
2419 | ERR("Can't find OTG driver!\n"); | ||
2420 | ret = -ENODEV; | ||
2421 | goto err_kfree; | ||
2422 | } | ||
2423 | } | ||
2424 | #endif | ||
2425 | |||
2377 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2426 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2378 | if (!res) { | 2427 | if (!res) { |
2379 | ret = -ENXIO; | 2428 | ret = -ENXIO; |
2380 | goto err_kfree; | 2429 | goto err_kfree; |
2381 | } | 2430 | } |
2382 | 2431 | ||
2383 | if (!request_mem_region(res->start, res->end - res->start + 1, | 2432 | if (pdata->operating_mode == FSL_USB2_DR_DEVICE) { |
2384 | driver_name)) { | 2433 | if (!request_mem_region(res->start, res->end - res->start + 1, |
2385 | ERR("request mem region for %s failed\n", pdev->name); | 2434 | driver_name)) { |
2386 | ret = -EBUSY; | 2435 | ERR("request mem region for %s failed\n", pdev->name); |
2387 | goto err_kfree; | 2436 | ret = -EBUSY; |
2437 | goto err_kfree; | ||
2438 | } | ||
2388 | } | 2439 | } |
2389 | 2440 | ||
2390 | dr_regs = ioremap(res->start, resource_size(res)); | 2441 | dr_regs = ioremap(res->start, resource_size(res)); |
@@ -2455,9 +2506,11 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2455 | goto err_free_irq; | 2506 | goto err_free_irq; |
2456 | } | 2507 | } |
2457 | 2508 | ||
2458 | /* initialize usb hw reg except for regs for EP, | 2509 | if (!udc_controller->transceiver) { |
2459 | * leave usbintr reg untouched */ | 2510 | /* initialize usb hw reg except for regs for EP, |
2460 | dr_controller_setup(udc_controller); | 2511 | * leave usbintr reg untouched */ |
2512 | dr_controller_setup(udc_controller); | ||
2513 | } | ||
2461 | 2514 | ||
2462 | fsl_udc_clk_finalize(pdev); | 2515 | fsl_udc_clk_finalize(pdev); |
2463 | 2516 | ||
@@ -2477,6 +2530,9 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2477 | if (ret < 0) | 2530 | if (ret < 0) |
2478 | goto err_free_irq; | 2531 | goto err_free_irq; |
2479 | 2532 | ||
2533 | if (udc_controller->transceiver) | ||
2534 | udc_controller->gadget.is_otg = 1; | ||
2535 | |||
2480 | /* setup QH and epctrl for ep0 */ | 2536 | /* setup QH and epctrl for ep0 */ |
2481 | ep0_setup(udc_controller); | 2537 | ep0_setup(udc_controller); |
2482 | 2538 | ||
@@ -2521,7 +2577,8 @@ err_iounmap: | |||
2521 | err_iounmap_noclk: | 2577 | err_iounmap_noclk: |
2522 | iounmap(dr_regs); | 2578 | iounmap(dr_regs); |
2523 | err_release_mem_region: | 2579 | err_release_mem_region: |
2524 | release_mem_region(res->start, res->end - res->start + 1); | 2580 | if (pdata->operating_mode == FSL_USB2_DR_DEVICE) |
2581 | release_mem_region(res->start, res->end - res->start + 1); | ||
2525 | err_kfree: | 2582 | err_kfree: |
2526 | kfree(udc_controller); | 2583 | kfree(udc_controller); |
2527 | udc_controller = NULL; | 2584 | udc_controller = NULL; |
@@ -2555,7 +2612,8 @@ static int __exit fsl_udc_remove(struct platform_device *pdev) | |||
2555 | dma_pool_destroy(udc_controller->td_pool); | 2612 | dma_pool_destroy(udc_controller->td_pool); |
2556 | free_irq(udc_controller->irq, udc_controller); | 2613 | free_irq(udc_controller->irq, udc_controller); |
2557 | iounmap(dr_regs); | 2614 | iounmap(dr_regs); |
2558 | release_mem_region(res->start, res->end - res->start + 1); | 2615 | if (pdata->operating_mode == FSL_USB2_DR_DEVICE) |
2616 | release_mem_region(res->start, res->end - res->start + 1); | ||
2559 | 2617 | ||
2560 | device_unregister(&udc_controller->gadget.dev); | 2618 | device_unregister(&udc_controller->gadget.dev); |
2561 | /* free udc --wait for the release() finished */ | 2619 | /* free udc --wait for the release() finished */ |
@@ -2598,6 +2656,62 @@ static int fsl_udc_resume(struct platform_device *pdev) | |||
2598 | return 0; | 2656 | return 0; |
2599 | } | 2657 | } |
2600 | 2658 | ||
2659 | static int fsl_udc_otg_suspend(struct device *dev, pm_message_t state) | ||
2660 | { | ||
2661 | struct fsl_udc *udc = udc_controller; | ||
2662 | u32 mode, usbcmd; | ||
2663 | |||
2664 | mode = fsl_readl(&dr_regs->usbmode) & USB_MODE_CTRL_MODE_MASK; | ||
2665 | |||
2666 | pr_debug("%s(): mode 0x%x stopped %d\n", __func__, mode, udc->stopped); | ||
2667 | |||
2668 | /* | ||
2669 | * If the controller is already stopped, then this must be a | ||
2670 | * PM suspend. Remember this fact, so that we will leave the | ||
2671 | * controller stopped at PM resume time. | ||
2672 | */ | ||
2673 | if (udc->stopped) { | ||
2674 | pr_debug("gadget already stopped, leaving early\n"); | ||
2675 | udc->already_stopped = 1; | ||
2676 | return 0; | ||
2677 | } | ||
2678 | |||
2679 | if (mode != USB_MODE_CTRL_MODE_DEVICE) { | ||
2680 | pr_debug("gadget not in device mode, leaving early\n"); | ||
2681 | return 0; | ||
2682 | } | ||
2683 | |||
2684 | /* stop the controller */ | ||
2685 | usbcmd = fsl_readl(&dr_regs->usbcmd) & ~USB_CMD_RUN_STOP; | ||
2686 | fsl_writel(usbcmd, &dr_regs->usbcmd); | ||
2687 | |||
2688 | udc->stopped = 1; | ||
2689 | |||
2690 | pr_info("USB Gadget suspended\n"); | ||
2691 | |||
2692 | return 0; | ||
2693 | } | ||
2694 | |||
2695 | static int fsl_udc_otg_resume(struct device *dev) | ||
2696 | { | ||
2697 | pr_debug("%s(): stopped %d already_stopped %d\n", __func__, | ||
2698 | udc_controller->stopped, udc_controller->already_stopped); | ||
2699 | |||
2700 | /* | ||
2701 | * If the controller was stopped at suspend time, then | ||
2702 | * don't resume it now. | ||
2703 | */ | ||
2704 | if (udc_controller->already_stopped) { | ||
2705 | udc_controller->already_stopped = 0; | ||
2706 | pr_debug("gadget was already stopped, leaving early\n"); | ||
2707 | return 0; | ||
2708 | } | ||
2709 | |||
2710 | pr_info("USB Gadget resume\n"); | ||
2711 | |||
2712 | return fsl_udc_resume(NULL); | ||
2713 | } | ||
2714 | |||
2601 | /*------------------------------------------------------------------------- | 2715 | /*------------------------------------------------------------------------- |
2602 | Register entry point for the peripheral controller driver | 2716 | Register entry point for the peripheral controller driver |
2603 | --------------------------------------------------------------------------*/ | 2717 | --------------------------------------------------------------------------*/ |
@@ -2610,6 +2724,9 @@ static struct platform_driver udc_driver = { | |||
2610 | .driver = { | 2724 | .driver = { |
2611 | .name = (char *)driver_name, | 2725 | .name = (char *)driver_name, |
2612 | .owner = THIS_MODULE, | 2726 | .owner = THIS_MODULE, |
2727 | /* udc suspend/resume called from OTG driver */ | ||
2728 | .suspend = fsl_udc_otg_suspend, | ||
2729 | .resume = fsl_udc_otg_resume, | ||
2613 | }, | 2730 | }, |
2614 | }; | 2731 | }; |
2615 | 2732 | ||
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index 5647cc21b84c..1d51be83fda8 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h | |||
@@ -476,6 +476,7 @@ struct fsl_udc { | |||
476 | unsigned vbus_active:1; | 476 | unsigned vbus_active:1; |
477 | unsigned stopped:1; | 477 | unsigned stopped:1; |
478 | unsigned remote_wakeup:1; | 478 | unsigned remote_wakeup:1; |
479 | unsigned already_stopped:1; | ||
479 | unsigned big_endian_desc:1; | 480 | unsigned big_endian_desc:1; |
480 | 481 | ||
481 | struct ep_queue_head *ep_qh; /* Endpoints Queue-Head */ | 482 | struct ep_queue_head *ep_qh; /* Endpoints Queue-Head */ |
@@ -487,6 +488,7 @@ struct fsl_udc { | |||
487 | dma_addr_t ep_qh_dma; /* dma address of QH */ | 488 | dma_addr_t ep_qh_dma; /* dma address of QH */ |
488 | 489 | ||
489 | u32 max_pipes; /* Device max pipes */ | 490 | u32 max_pipes; /* Device max pipes */ |
491 | u32 bus_reset; /* Device is bus resetting */ | ||
490 | u32 resume_state; /* USB state to resume */ | 492 | u32 resume_state; /* USB state to resume */ |
491 | u32 usb_state; /* USB current state */ | 493 | u32 usb_state; /* USB current state */ |
492 | u32 ep0_state; /* Endpoint zero state */ | 494 | u32 ep0_state; /* Endpoint zero state */ |
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index caf3d4ac42bd..623732a312dd 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -117,6 +117,9 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, | |||
117 | 117 | ||
118 | pdata->regs = hcd->regs; | 118 | pdata->regs = hcd->regs; |
119 | 119 | ||
120 | if (pdata->power_budget) | ||
121 | hcd->power_budget = pdata->power_budget; | ||
122 | |||
120 | /* | 123 | /* |
121 | * do platform specific init: check the clock, grab/config pins, etc. | 124 | * do platform specific init: check the clock, grab/config pins, etc. |
122 | */ | 125 | */ |
@@ -134,6 +137,30 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, | |||
134 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | 137 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); |
135 | if (retval != 0) | 138 | if (retval != 0) |
136 | goto err4; | 139 | goto err4; |
140 | |||
141 | #ifdef CONFIG_USB_OTG | ||
142 | if (pdata->operating_mode == FSL_USB2_DR_OTG) { | ||
143 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
144 | |||
145 | ehci->transceiver = otg_get_transceiver(); | ||
146 | dev_dbg(&pdev->dev, "hcd=0x%p ehci=0x%p, transceiver=0x%p\n", | ||
147 | hcd, ehci, ehci->transceiver); | ||
148 | |||
149 | if (ehci->transceiver) { | ||
150 | retval = otg_set_host(ehci->transceiver, | ||
151 | &ehci_to_hcd(ehci)->self); | ||
152 | if (retval) { | ||
153 | if (ehci->transceiver) | ||
154 | put_device(ehci->transceiver->dev); | ||
155 | goto err4; | ||
156 | } | ||
157 | } else { | ||
158 | dev_err(&pdev->dev, "can't find transceiver\n"); | ||
159 | retval = -ENODEV; | ||
160 | goto err4; | ||
161 | } | ||
162 | } | ||
163 | #endif | ||
137 | return retval; | 164 | return retval; |
138 | 165 | ||
139 | err4: | 166 | err4: |
@@ -164,6 +191,12 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd, | |||
164 | struct platform_device *pdev) | 191 | struct platform_device *pdev) |
165 | { | 192 | { |
166 | struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; | 193 | struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; |
194 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
195 | |||
196 | if (ehci->transceiver) { | ||
197 | otg_set_host(ehci->transceiver, NULL); | ||
198 | put_device(ehci->transceiver->dev); | ||
199 | } | ||
167 | 200 | ||
168 | usb_remove_hcd(hcd); | 201 | usb_remove_hcd(hcd); |
169 | 202 | ||
@@ -544,6 +577,38 @@ static struct dev_pm_ops ehci_fsl_pm_ops = { | |||
544 | #define EHCI_FSL_PM_OPS NULL | 577 | #define EHCI_FSL_PM_OPS NULL |
545 | #endif /* CONFIG_PM */ | 578 | #endif /* CONFIG_PM */ |
546 | 579 | ||
580 | #ifdef CONFIG_USB_OTG | ||
581 | static int ehci_start_port_reset(struct usb_hcd *hcd, unsigned port) | ||
582 | { | ||
583 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
584 | u32 status; | ||
585 | |||
586 | if (!port) | ||
587 | return -EINVAL; | ||
588 | |||
589 | port--; | ||
590 | |||
591 | /* start port reset before HNP protocol time out */ | ||
592 | status = readl(&ehci->regs->port_status[port]); | ||
593 | if (!(status & PORT_CONNECT)) | ||
594 | return -ENODEV; | ||
595 | |||
596 | /* khubd will finish the reset later */ | ||
597 | if (ehci_is_TDI(ehci)) { | ||
598 | writel(PORT_RESET | | ||
599 | (status & ~(PORT_CSC | PORT_PEC | PORT_OCC)), | ||
600 | &ehci->regs->port_status[port]); | ||
601 | } else { | ||
602 | writel(PORT_RESET, &ehci->regs->port_status[port]); | ||
603 | } | ||
604 | |||
605 | return 0; | ||
606 | } | ||
607 | #else | ||
608 | #define ehci_start_port_reset NULL | ||
609 | #endif /* CONFIG_USB_OTG */ | ||
610 | |||
611 | |||
547 | static const struct hc_driver ehci_fsl_hc_driver = { | 612 | static const struct hc_driver ehci_fsl_hc_driver = { |
548 | .description = hcd_name, | 613 | .description = hcd_name, |
549 | .product_desc = "Freescale On-Chip EHCI Host Controller", | 614 | .product_desc = "Freescale On-Chip EHCI Host Controller", |
@@ -583,6 +648,7 @@ static const struct hc_driver ehci_fsl_hc_driver = { | |||
583 | .hub_control = ehci_hub_control, | 648 | .hub_control = ehci_hub_control, |
584 | .bus_suspend = ehci_bus_suspend, | 649 | .bus_suspend = ehci_bus_suspend, |
585 | .bus_resume = ehci_bus_resume, | 650 | .bus_resume = ehci_bus_resume, |
651 | .start_port_reset = ehci_start_port_reset, | ||
586 | .relinquish_port = ehci_relinquish_port, | 652 | .relinquish_port = ehci_relinquish_port, |
587 | .port_handed_over = ehci_port_handed_over, | 653 | .port_handed_over = ehci_port_handed_over, |
588 | 654 | ||
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 1a21799195af..ea6184bf48d0 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -27,6 +27,7 @@ | |||
27 | */ | 27 | */ |
28 | 28 | ||
29 | /*-------------------------------------------------------------------------*/ | 29 | /*-------------------------------------------------------------------------*/ |
30 | #include <linux/usb/otg.h> | ||
30 | 31 | ||
31 | #define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) | 32 | #define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E) |
32 | 33 | ||
@@ -801,6 +802,13 @@ static int ehci_hub_control ( | |||
801 | goto error; | 802 | goto error; |
802 | if (ehci->no_selective_suspend) | 803 | if (ehci->no_selective_suspend) |
803 | break; | 804 | break; |
805 | #ifdef CONFIG_USB_OTG | ||
806 | if ((hcd->self.otg_port == (wIndex + 1)) | ||
807 | && hcd->self.b_hnp_enable) { | ||
808 | otg_start_hnp(ehci->transceiver); | ||
809 | break; | ||
810 | } | ||
811 | #endif | ||
804 | if (!(temp & PORT_SUSPEND)) | 812 | if (!(temp & PORT_SUSPEND)) |
805 | break; | 813 | break; |
806 | if ((temp & PORT_PE) == 0) | 814 | if ((temp & PORT_PE) == 0) |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 168f1a88c4d0..e9ba8e252489 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -161,6 +161,10 @@ struct ehci_hcd { /* one per controller */ | |||
161 | #ifdef DEBUG | 161 | #ifdef DEBUG |
162 | struct dentry *debug_dir; | 162 | struct dentry *debug_dir; |
163 | #endif | 163 | #endif |
164 | /* | ||
165 | * OTG controllers and transceivers need software interaction | ||
166 | */ | ||
167 | struct otg_transceiver *transceiver; | ||
164 | }; | 168 | }; |
165 | 169 | ||
166 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ | 170 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ |
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index 3773c5dab8f5..fffdf00f87b9 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h | |||
@@ -72,6 +72,7 @@ struct fsl_usb2_platform_data { | |||
72 | void (*exit)(struct platform_device *); | 72 | void (*exit)(struct platform_device *); |
73 | void __iomem *regs; /* ioremap'd register base */ | 73 | void __iomem *regs; /* ioremap'd register base */ |
74 | struct clk *clk; | 74 | struct clk *clk; |
75 | unsigned power_budget; /* hcd->power_budget */ | ||
75 | unsigned big_endian_mmio:1; | 76 | unsigned big_endian_mmio:1; |
76 | unsigned big_endian_desc:1; | 77 | unsigned big_endian_desc:1; |
77 | unsigned es:1; /* need USBMODE:ES */ | 78 | unsigned es:1; /* need USBMODE:ES */ |