Merge tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[linux-drm-fsl-dcu.git] / drivers / usb / host / ehci-tegra.c
index 99ae5ea3f8d1d39ea2fd51ce82dbf6ccd3f3fa83..68548236ec4228ceb224d69845daba6345bf9971 100644 (file)
@@ -147,18 +147,7 @@ static int tegra_ehci_hub_control(
 
        spin_lock_irqsave(&ehci->lock, flags);
 
-       /*
-        * In ehci_hub_control() for USB_PORT_FEAT_ENABLE clears the other bits
-        * that are write on clear, by writing back the register read value, so
-        * USB_PORT_FEAT_ENABLE is handled by masking the set on clear bits
-        */
-       if (typeReq == ClearPortFeature && wValue == USB_PORT_FEAT_ENABLE) {
-               temp = ehci_readl(ehci, status_reg) & ~PORT_RWC_BITS;
-               ehci_writel(ehci, temp & ~PORT_PE, status_reg);
-               goto done;
-       }
-
-       else if (typeReq == GetPortStatus) {
+       if (typeReq == GetPortStatus) {
                temp = ehci_readl(ehci, status_reg);
                if (tegra->port_resuming && !(temp & PORT_SUSPEND)) {
                        /* Resume completed, re-enable disconnect detection */
@@ -174,7 +163,7 @@ static int tegra_ehci_hub_control(
                        goto done;
                }
 
-               temp &= ~PORT_WKCONN_E;
+               temp &= ~(PORT_RWC_BITS | PORT_WKCONN_E);
                temp |= PORT_WKDISC_E | PORT_WKOC_E;
                ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
 
@@ -319,26 +308,23 @@ static int tegra_ehci_setup(struct usb_hcd *hcd)
        return retval;
 }
 
-struct temp_buffer {
+struct dma_aligned_buffer {
        void *kmalloc_ptr;
        void *old_xfer_buffer;
        u8 data[0];
 };
 
-static void free_temp_buffer(struct urb *urb)
+static void free_dma_aligned_buffer(struct urb *urb)
 {
-       enum dma_data_direction dir;
-       struct temp_buffer *temp;
+       struct dma_aligned_buffer *temp;
 
        if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
                return;
 
-       dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-
-       temp = container_of(urb->transfer_buffer, struct temp_buffer,
-                           data);
+       temp = container_of(urb->transfer_buffer,
+               struct dma_aligned_buffer, data);
 
-       if (dir == DMA_FROM_DEVICE)
+       if (usb_urb_dir_in(urb))
                memcpy(temp->old_xfer_buffer, temp->data,
                       urb->transfer_buffer_length);
        urb->transfer_buffer = temp->old_xfer_buffer;
@@ -347,10 +333,9 @@ static void free_temp_buffer(struct urb *urb)
        urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
 }
 
-static int alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
+static int alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
 {
-       enum dma_data_direction dir;
-       struct temp_buffer *temp, *kmalloc_ptr;
+       struct dma_aligned_buffer *temp, *kmalloc_ptr;
        size_t kmalloc_size;
 
        if (urb->num_sgs || urb->sg ||
@@ -358,22 +343,19 @@ static int alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
            !((uintptr_t)urb->transfer_buffer & (TEGRA_USB_DMA_ALIGN - 1)))
                return 0;
 
-       dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-
        /* Allocate a buffer with enough padding for alignment */
        kmalloc_size = urb->transfer_buffer_length +
-               sizeof(struct temp_buffer) + TEGRA_USB_DMA_ALIGN - 1;
+               sizeof(struct dma_aligned_buffer) + TEGRA_USB_DMA_ALIGN - 1;
 
        kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
        if (!kmalloc_ptr)
                return -ENOMEM;
 
-       /* Position our struct temp_buffer such that data is aligned */
+       /* Position our struct dma_aligned_buffer such that data is aligned */
        temp = PTR_ALIGN(kmalloc_ptr + 1, TEGRA_USB_DMA_ALIGN) - 1;
-
        temp->kmalloc_ptr = kmalloc_ptr;
        temp->old_xfer_buffer = urb->transfer_buffer;
-       if (dir == DMA_TO_DEVICE)
+       if (usb_urb_dir_out(urb))
                memcpy(temp->data, urb->transfer_buffer,
                       urb->transfer_buffer_length);
        urb->transfer_buffer = temp->data;
@@ -388,13 +370,13 @@ static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
 {
        int ret;
 
-       ret = alloc_temp_buffer(urb, mem_flags);
+       ret = alloc_dma_aligned_buffer(urb, mem_flags);
        if (ret)
                return ret;
 
        ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
        if (ret)
-               free_temp_buffer(urb);
+               free_dma_aligned_buffer(urb);
 
        return ret;
 }
@@ -402,38 +384,39 @@ static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
 static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
 {
        usb_hcd_unmap_urb_for_dma(hcd, urb);
-       free_temp_buffer(urb);
+       free_dma_aligned_buffer(urb);
 }
 
 static const struct hc_driver tegra_ehci_hc_driver = {
        .description            = hcd_name,
        .product_desc           = "Tegra EHCI Host Controller",
        .hcd_priv_size          = sizeof(struct ehci_hcd),
-
        .flags                  = HCD_USB2 | HCD_MEMORY,
 
-       .reset                  = tegra_ehci_setup,
+       /* standard ehci functions */
        .irq                    = ehci_irq,
-
        .start                  = ehci_run,
        .stop                   = ehci_stop,
-       .shutdown               = tegra_ehci_shutdown,
        .urb_enqueue            = ehci_urb_enqueue,
        .urb_dequeue            = ehci_urb_dequeue,
-       .map_urb_for_dma        = tegra_ehci_map_urb_for_dma,
-       .unmap_urb_for_dma      = tegra_ehci_unmap_urb_for_dma,
        .endpoint_disable       = ehci_endpoint_disable,
        .endpoint_reset         = ehci_endpoint_reset,
        .get_frame_number       = ehci_get_frame,
        .hub_status_data        = ehci_hub_status_data,
-       .hub_control            = tegra_ehci_hub_control,
        .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+       .relinquish_port        = ehci_relinquish_port,
+       .port_handed_over       = ehci_port_handed_over,
+
+       /* modified ehci functions for tegra */
+       .reset                  = tegra_ehci_setup,
+       .shutdown               = tegra_ehci_shutdown,
+       .map_urb_for_dma        = tegra_ehci_map_urb_for_dma,
+       .unmap_urb_for_dma      = tegra_ehci_unmap_urb_for_dma,
+       .hub_control            = tegra_ehci_hub_control,
 #ifdef CONFIG_PM
        .bus_suspend            = ehci_bus_suspend,
        .bus_resume             = ehci_bus_resume,
 #endif
-       .relinquish_port        = ehci_relinquish_port,
-       .port_handed_over       = ehci_port_handed_over,
 };
 
 static int setup_vbus_gpio(struct platform_device *pdev,