2 * xhci-plat.c - xHCI host controller driver platform Bus Glue.
4 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
5 * Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
7 * A lot of code borrowed from the Linux xHCI driver.
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
14 #include <linux/platform_device.h>
15 #include <linux/module.h>
16 #include <linux/slab.h>
17 #include <linux/dma-mapping.h>
21 #ifdef CONFIG_MTK_XHCI
22 #include <linux/xhci/xhci-mtk.h>
26 static void xhci_plat_quirks(struct device
*dev
, struct xhci_hcd
*xhci
)
29 * As of now platform drivers don't provide MSI support so we ensure
30 * here that the generic code does not try to make a pci_dev from our
31 * dev struct in order to setup MSI
33 xhci
->quirks
|= XHCI_PLAT
;
34 //CC: MTK host controller gives a spurious successful event after a
35 // short transfer. Ignore it.
36 xhci
->quirks
|= XHCI_SPURIOUS_SUCCESS
;
37 xhci
->quirks
|= XHCI_LPM_SUPPORT
;
40 /* called during probe() after chip reset completes */
41 static int xhci_plat_setup(struct usb_hcd
*hcd
)
43 return xhci_gen_setup(hcd
, xhci_plat_quirks
);
46 static const struct hc_driver xhci_plat_xhci_driver
= {
47 .description
= "xhci-hcd",
48 .product_desc
= "xHCI Host Controller",
49 .hcd_priv_size
= sizeof(struct xhci_hcd
*),
52 * generic hardware linkage
55 .flags
= HCD_MEMORY
| HCD_USB3
| HCD_SHARED
,
58 * basic lifecycle operations
60 .reset
= xhci_plat_setup
,
63 .shutdown
= xhci_shutdown
,
66 * managing i/o requests and associated device resources
68 .urb_enqueue
= xhci_urb_enqueue
,
69 .urb_dequeue
= xhci_urb_dequeue
,
70 .alloc_dev
= xhci_alloc_dev
,
71 .free_dev
= xhci_free_dev
,
72 .alloc_streams
= xhci_alloc_streams
,
73 .free_streams
= xhci_free_streams
,
74 .add_endpoint
= xhci_add_endpoint
,
75 .drop_endpoint
= xhci_drop_endpoint
,
76 .endpoint_reset
= xhci_endpoint_reset
,
77 .check_bandwidth
= xhci_check_bandwidth
,
78 .reset_bandwidth
= xhci_reset_bandwidth
,
79 .address_device
= xhci_address_device
,
80 .update_hub_device
= xhci_update_hub_device
,
81 .reset_device
= xhci_discover_or_reset_device
,
86 .get_frame_number
= xhci_get_frame
,
88 /* Root hub support */
89 .hub_control
= xhci_hub_control
,
90 .hub_status_data
= xhci_hub_status_data
,
91 .bus_suspend
= xhci_bus_suspend
,
92 .bus_resume
= xhci_bus_resume
,
95 #if defined(CONFIG_MTK_LM_MODE)
96 #define XHCI_DMA_BIT_MASK DMA_BIT_MASK(64)
98 #define XHCI_DMA_BIT_MASK DMA_BIT_MASK(32)
101 static u64 xhci_dma_mask
= XHCI_DMA_BIT_MASK
;
103 static void xhci_hcd_release (struct device
*dev
)
105 printk(KERN_INFO
"dev = 0x%p\n", dev
);
108 static int xhci_plat_probe(struct platform_device
*pdev
)
110 const struct hc_driver
*driver
;
111 struct xhci_hcd
*xhci
;
112 struct resource
*res
;
120 driver
= &xhci_plat_xhci_driver
;
122 #ifdef CONFIG_MTK_XHCI /* device tree support */
123 irq
= platform_get_irq_byname(pdev
, XHCI_DRIVER_NAME
);
124 printk("%s(%d): %d\n", __func__
, __LINE__
, irq
);
128 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, XHCI_BASE_REGS_ADDR_RES_NAME
);
132 pdev
->dev
.coherent_dma_mask
= XHCI_DMA_BIT_MASK
;
133 pdev
->dev
.dma_mask
= &xhci_dma_mask
;
134 pdev
->dev
.release
= xhci_hcd_release
;
136 irq
= platform_get_irq(pdev
, 0);
140 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
145 hcd
= usb_create_hcd(driver
, &pdev
->dev
, dev_name(&pdev
->dev
));
149 hcd
->rsrc_start
= res
->start
;
150 hcd
->rsrc_len
= resource_size(res
);
152 if (!request_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
,
153 driver
->description
)) {
154 dev_dbg(&pdev
->dev
, "controller already in use\n");
159 hcd
->regs
= ioremap_nocache(hcd
->rsrc_start
, hcd
->rsrc_len
);
161 dev_dbg(&pdev
->dev
, "error mapping memory\n");
163 goto release_mem_region
;
166 printk("%s(%d): logic 0x%p, phys 0x%p\n", __func__
, __LINE__
,
167 (void *)(unsigned long)res
->start
, hcd
->regs
);
169 #ifdef CONFIG_MTK_XHCI
170 ret
= usb_add_hcd(hcd
, irq
, IRQF_SHARED
| IRQF_TRIGGER_LOW
);
172 ret
= usb_add_hcd(hcd
, irq
, IRQF_SHARED
);
176 goto unmap_registers
;
178 /* USB 2.0 roothub is stored in the platform_device now. */
179 hcd
= dev_get_drvdata(&pdev
->dev
);
180 xhci
= hcd_to_xhci(hcd
);
181 xhci
->shared_hcd
= usb_create_shared_hcd(driver
, &pdev
->dev
,
182 dev_name(&pdev
->dev
), hcd
);
183 if (!xhci
->shared_hcd
) {
185 goto dealloc_usb2_hcd
;
189 * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset)
190 * is called by usb_add_hcd().
192 *((struct xhci_hcd
**) xhci
->shared_hcd
->hcd_priv
) = xhci
;
194 #ifdef CONFIG_MTK_XHCI
195 ret
= usb_add_hcd(xhci
->shared_hcd
, irq
, IRQF_SHARED
| IRQF_TRIGGER_LOW
);
197 ret
= usb_add_hcd(xhci
->shared_hcd
, irq
, IRQF_SHARED
);
205 usb_put_hcd(xhci
->shared_hcd
);
214 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
222 static int xhci_plat_remove(struct platform_device
*dev
)
224 struct usb_hcd
*hcd
= platform_get_drvdata(dev
);
225 struct xhci_hcd
*xhci
= hcd_to_xhci(hcd
);
227 xhci
->xhc_state
|= XHCI_STATE_REMOVING
;
229 usb_remove_hcd(xhci
->shared_hcd
);
230 usb_put_hcd(xhci
->shared_hcd
);
234 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
236 #ifdef CONFIG_MTK_XHCI
237 mtk_xhci_reset(xhci
);
244 #ifdef CONFIG_MTK_XHCI
245 static const struct of_device_id mtk_xhci_of_match
[] = {
247 .compatible
= "mediatek,USB3_XHCI",
253 static struct platform_driver usb_xhci_driver
= {
254 .probe
= xhci_plat_probe
,
255 .remove
= xhci_plat_remove
,
258 #ifdef CONFIG_MTK_XHCI
259 .of_match_table
= of_match_ptr(mtk_xhci_of_match
),
263 MODULE_ALIAS("platform:xhci-hcd");
265 int xhci_register_plat(void)
267 return platform_driver_register(&usb_xhci_driver
);
270 void xhci_unregister_plat(void)
272 platform_driver_unregister(&usb_xhci_driver
);