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 .update_hub_device
= xhci_update_hub_device
,
73 .reset_device
= xhci_discover_or_reset_device
,
78 .get_frame_number
= xhci_get_frame
,
80 /* Root hub support */
81 .hub_control
= xhci_hub_control
,
82 .hub_status_data
= xhci_hub_status_data
,
83 .bus_suspend
= xhci_bus_suspend
,
84 .bus_resume
= xhci_bus_resume
,
87 static int xhci_plat_probe(struct platform_device
*pdev
)
89 const struct hc_driver
*driver
;
90 struct xhci_hcd
*xhci
;
99 driver
= &xhci_plat_xhci_driver
;
101 irq
= platform_get_irq(pdev
, 0);
105 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
109 /* Initialize dma_mask and coherent_dma_mask to 32-bits */
110 ret
= dma_set_coherent_mask(&pdev
->dev
, DMA_BIT_MASK(32));
113 if (!pdev
->dev
.dma_mask
)
114 pdev
->dev
.dma_mask
= &pdev
->dev
.coherent_dma_mask
;
116 dma_set_mask(&pdev
->dev
, DMA_BIT_MASK(32));
118 hcd
= usb_create_hcd(driver
, &pdev
->dev
, dev_name(&pdev
->dev
));
122 hcd
->rsrc_start
= res
->start
;
123 hcd
->rsrc_len
= resource_size(res
);
125 if (!request_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
,
126 driver
->description
)) {
127 dev_dbg(&pdev
->dev
, "controller already in use\n");
132 hcd
->regs
= ioremap_nocache(hcd
->rsrc_start
, hcd
->rsrc_len
);
134 dev_dbg(&pdev
->dev
, "error mapping memory\n");
136 goto release_mem_region
;
139 ret
= usb_add_hcd(hcd
, irq
, IRQF_SHARED
);
141 goto unmap_registers
;
143 /* USB 2.0 roothub is stored in the platform_device now. */
144 hcd
= platform_get_drvdata(pdev
);
145 xhci
= hcd_to_xhci(hcd
);
146 xhci
->shared_hcd
= usb_create_shared_hcd(driver
, &pdev
->dev
,
147 dev_name(&pdev
->dev
), hcd
);
148 if (!xhci
->shared_hcd
) {
150 goto dealloc_usb2_hcd
;
154 * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset)
155 * is called by usb_add_hcd().
157 *((struct xhci_hcd
**) xhci
->shared_hcd
->hcd_priv
) = xhci
;
159 ret
= usb_add_hcd(xhci
->shared_hcd
, irq
, IRQF_SHARED
);
166 usb_put_hcd(xhci
->shared_hcd
);
175 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
183 static int xhci_plat_remove(struct platform_device
*dev
)
185 struct usb_hcd
*hcd
= platform_get_drvdata(dev
);
186 struct xhci_hcd
*xhci
= hcd_to_xhci(hcd
);
188 usb_remove_hcd(xhci
->shared_hcd
);
189 usb_put_hcd(xhci
->shared_hcd
);
193 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
201 static int xhci_plat_suspend(struct device
*dev
)
203 struct usb_hcd
*hcd
= dev_get_drvdata(dev
);
204 struct xhci_hcd
*xhci
= hcd_to_xhci(hcd
);
206 return xhci_suspend(xhci
);
209 static int xhci_plat_resume(struct device
*dev
)
211 struct usb_hcd
*hcd
= dev_get_drvdata(dev
);
212 struct xhci_hcd
*xhci
= hcd_to_xhci(hcd
);
214 return xhci_resume(xhci
, 0);
217 static const struct dev_pm_ops xhci_plat_pm_ops
= {
218 SET_SYSTEM_SLEEP_PM_OPS(xhci_plat_suspend
, xhci_plat_resume
)
220 #define DEV_PM_OPS (&xhci_plat_pm_ops)
222 #define DEV_PM_OPS NULL
223 #endif /* CONFIG_PM */
226 static const struct of_device_id usb_xhci_of_match
[] = {
227 { .compatible
= "xhci-platform" },
230 MODULE_DEVICE_TABLE(of
, usb_xhci_of_match
);
233 static struct platform_driver usb_xhci_driver
= {
234 .probe
= xhci_plat_probe
,
235 .remove
= xhci_plat_remove
,
239 .of_match_table
= of_match_ptr(usb_xhci_of_match
),
242 MODULE_ALIAS("platform:xhci-hcd");
244 int xhci_register_plat(void)
246 return platform_driver_register(&usb_xhci_driver
);
249 void xhci_unregister_plat(void)
251 platform_driver_unregister(&usb_xhci_driver
);