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>
18 #include <linux/dma-mapping.h>
22 static void xhci_plat_quirks(struct device
*dev
, struct xhci_hcd
*xhci
)
25 * As of now platform drivers don't provide MSI support so we ensure
26 * here that the generic code does not try to make a pci_dev from our
27 * dev struct in order to setup MSI
29 xhci
->quirks
|= XHCI_PLAT
;
32 /* called during probe() after chip reset completes */
33 static int xhci_plat_setup(struct usb_hcd
*hcd
)
35 return xhci_gen_setup(hcd
, xhci_plat_quirks
);
38 static const struct hc_driver xhci_plat_xhci_driver
= {
39 .description
= "xhci-hcd",
40 .product_desc
= "xHCI Host Controller",
41 .hcd_priv_size
= sizeof(struct xhci_hcd
*),
44 * generic hardware linkage
47 .flags
= HCD_MEMORY
| HCD_USB3
| HCD_SHARED
,
50 * basic lifecycle operations
52 .reset
= xhci_plat_setup
,
55 .shutdown
= xhci_shutdown
,
58 * managing i/o requests and associated device resources
60 .urb_enqueue
= xhci_urb_enqueue
,
61 .urb_dequeue
= xhci_urb_dequeue
,
62 .alloc_dev
= xhci_alloc_dev
,
63 .free_dev
= xhci_free_dev
,
64 .alloc_streams
= xhci_alloc_streams
,
65 .free_streams
= xhci_free_streams
,
66 .add_endpoint
= xhci_add_endpoint
,
67 .drop_endpoint
= xhci_drop_endpoint
,
68 .endpoint_reset
= xhci_endpoint_reset
,
69 .check_bandwidth
= xhci_check_bandwidth
,
70 .reset_bandwidth
= xhci_reset_bandwidth
,
71 .address_device
= xhci_address_device
,
72 .enable_device
= xhci_enable_device
,
73 .update_hub_device
= xhci_update_hub_device
,
74 .reset_device
= xhci_discover_or_reset_device
,
79 .get_frame_number
= xhci_get_frame
,
81 /* Root hub support */
82 .hub_control
= xhci_hub_control
,
83 .hub_status_data
= xhci_hub_status_data
,
84 .bus_suspend
= xhci_bus_suspend
,
85 .bus_resume
= xhci_bus_resume
,
88 static int xhci_plat_probe(struct platform_device
*pdev
)
90 const struct hc_driver
*driver
;
91 struct xhci_hcd
*xhci
;
100 driver
= &xhci_plat_xhci_driver
;
102 irq
= platform_get_irq(pdev
, 0);
106 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
110 /* Initialize dma_mask and coherent_dma_mask to 32-bits */
111 ret
= dma_set_coherent_mask(&pdev
->dev
, DMA_BIT_MASK(32));
114 if (!pdev
->dev
.dma_mask
)
115 pdev
->dev
.dma_mask
= &pdev
->dev
.coherent_dma_mask
;
117 dma_set_mask(&pdev
->dev
, DMA_BIT_MASK(32));
119 hcd
= usb_create_hcd(driver
, &pdev
->dev
, dev_name(&pdev
->dev
));
123 hcd
->rsrc_start
= res
->start
;
124 hcd
->rsrc_len
= resource_size(res
);
126 if (!request_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
,
127 driver
->description
)) {
128 dev_dbg(&pdev
->dev
, "controller already in use\n");
133 hcd
->regs
= ioremap_nocache(hcd
->rsrc_start
, hcd
->rsrc_len
);
135 dev_dbg(&pdev
->dev
, "error mapping memory\n");
137 goto release_mem_region
;
140 ret
= usb_add_hcd(hcd
, irq
, IRQF_SHARED
);
142 goto unmap_registers
;
143 device_wakeup_enable(hcd
->self
.controller
);
145 /* USB 2.0 roothub is stored in the platform_device now. */
146 hcd
= platform_get_drvdata(pdev
);
147 xhci
= hcd_to_xhci(hcd
);
148 xhci
->shared_hcd
= usb_create_shared_hcd(driver
, &pdev
->dev
,
149 dev_name(&pdev
->dev
), hcd
);
150 if (!xhci
->shared_hcd
) {
152 goto dealloc_usb2_hcd
;
156 * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset)
157 * is called by usb_add_hcd().
159 *((struct xhci_hcd
**) xhci
->shared_hcd
->hcd_priv
) = xhci
;
161 ret
= usb_add_hcd(xhci
->shared_hcd
, irq
, IRQF_SHARED
);
168 usb_put_hcd(xhci
->shared_hcd
);
177 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
185 static int xhci_plat_remove(struct platform_device
*dev
)
187 struct usb_hcd
*hcd
= platform_get_drvdata(dev
);
188 struct xhci_hcd
*xhci
= hcd_to_xhci(hcd
);
190 usb_remove_hcd(xhci
->shared_hcd
);
191 usb_put_hcd(xhci
->shared_hcd
);
195 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
203 static int xhci_plat_suspend(struct device
*dev
)
205 struct usb_hcd
*hcd
= dev_get_drvdata(dev
);
206 struct xhci_hcd
*xhci
= hcd_to_xhci(hcd
);
208 return xhci_suspend(xhci
);
211 static int xhci_plat_resume(struct device
*dev
)
213 struct usb_hcd
*hcd
= dev_get_drvdata(dev
);
214 struct xhci_hcd
*xhci
= hcd_to_xhci(hcd
);
216 return xhci_resume(xhci
, 0);
219 static const struct dev_pm_ops xhci_plat_pm_ops
= {
220 SET_SYSTEM_SLEEP_PM_OPS(xhci_plat_suspend
, xhci_plat_resume
)
222 #define DEV_PM_OPS (&xhci_plat_pm_ops)
224 #define DEV_PM_OPS NULL
225 #endif /* CONFIG_PM */
228 static const struct of_device_id usb_xhci_of_match
[] = {
229 { .compatible
= "xhci-platform" },
232 MODULE_DEVICE_TABLE(of
, usb_xhci_of_match
);
235 static struct platform_driver usb_xhci_driver
= {
236 .probe
= xhci_plat_probe
,
237 .remove
= xhci_plat_remove
,
241 .of_match_table
= of_match_ptr(usb_xhci_of_match
),
244 MODULE_ALIAS("platform:xhci-hcd");
246 int xhci_register_plat(void)
248 return platform_driver_register(&usb_xhci_driver
);
251 void xhci_unregister_plat(void)
253 platform_driver_unregister(&usb_xhci_driver
);