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>
20 static void xhci_plat_quirks(struct device
*dev
, struct xhci_hcd
*xhci
)
23 * As of now platform drivers don't provide MSI support so we ensure
24 * here that the generic code does not try to make a pci_dev from our
25 * dev struct in order to setup MSI
27 xhci
->quirks
|= XHCI_BROKEN_MSI
;
30 /* called during probe() after chip reset completes */
31 static int xhci_plat_setup(struct usb_hcd
*hcd
)
33 return xhci_gen_setup(hcd
, xhci_plat_quirks
);
36 static const struct hc_driver xhci_plat_xhci_driver
= {
37 .description
= "xhci-hcd",
38 .product_desc
= "xHCI Host Controller",
39 .hcd_priv_size
= sizeof(struct xhci_hcd
*),
42 * generic hardware linkage
45 .flags
= HCD_MEMORY
| HCD_USB3
| HCD_SHARED
,
48 * basic lifecycle operations
50 .reset
= xhci_plat_setup
,
53 .shutdown
= xhci_shutdown
,
56 * managing i/o requests and associated device resources
58 .urb_enqueue
= xhci_urb_enqueue
,
59 .urb_dequeue
= xhci_urb_dequeue
,
60 .alloc_dev
= xhci_alloc_dev
,
61 .free_dev
= xhci_free_dev
,
62 .alloc_streams
= xhci_alloc_streams
,
63 .free_streams
= xhci_free_streams
,
64 .add_endpoint
= xhci_add_endpoint
,
65 .drop_endpoint
= xhci_drop_endpoint
,
66 .endpoint_reset
= xhci_endpoint_reset
,
67 .check_bandwidth
= xhci_check_bandwidth
,
68 .reset_bandwidth
= xhci_reset_bandwidth
,
69 .address_device
= xhci_address_device
,
70 .update_hub_device
= xhci_update_hub_device
,
71 .reset_device
= xhci_discover_or_reset_device
,
76 .get_frame_number
= xhci_get_frame
,
78 /* Root hub support */
79 .hub_control
= xhci_hub_control
,
80 .hub_status_data
= xhci_hub_status_data
,
81 .bus_suspend
= xhci_bus_suspend
,
82 .bus_resume
= xhci_bus_resume
,
85 static int xhci_plat_probe(struct platform_device
*pdev
)
87 const struct hc_driver
*driver
;
88 struct xhci_hcd
*xhci
;
97 driver
= &xhci_plat_xhci_driver
;
99 irq
= platform_get_irq(pdev
, 0);
103 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
107 hcd
= usb_create_hcd(driver
, &pdev
->dev
, dev_name(&pdev
->dev
));
111 hcd
->rsrc_start
= res
->start
;
112 hcd
->rsrc_len
= resource_size(res
);
114 if (!request_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
,
115 driver
->description
)) {
116 dev_dbg(&pdev
->dev
, "controller already in use\n");
121 hcd
->regs
= ioremap_nocache(hcd
->rsrc_start
, hcd
->rsrc_len
);
123 dev_dbg(&pdev
->dev
, "error mapping memory\n");
125 goto release_mem_region
;
128 ret
= usb_add_hcd(hcd
, irq
, IRQF_SHARED
);
130 goto unmap_registers
;
132 /* USB 2.0 roothub is stored in the platform_device now. */
133 hcd
= dev_get_drvdata(&pdev
->dev
);
134 xhci
= hcd_to_xhci(hcd
);
135 xhci
->shared_hcd
= usb_create_shared_hcd(driver
, &pdev
->dev
,
136 dev_name(&pdev
->dev
), hcd
);
137 if (!xhci
->shared_hcd
) {
139 goto dealloc_usb2_hcd
;
143 * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset)
144 * is called by usb_add_hcd().
146 *((struct xhci_hcd
**) xhci
->shared_hcd
->hcd_priv
) = xhci
;
148 ret
= usb_add_hcd(xhci
->shared_hcd
, irq
, IRQF_SHARED
);
155 usb_put_hcd(xhci
->shared_hcd
);
164 release_mem_region(hcd
->rsrc_start
, hcd
->rsrc_len
);
172 static int xhci_plat_remove(struct platform_device
*dev
)
174 struct usb_hcd
*hcd
= platform_get_drvdata(dev
);
175 struct xhci_hcd
*xhci
= hcd_to_xhci(hcd
);
177 usb_remove_hcd(xhci
->shared_hcd
);
178 usb_put_hcd(xhci
->shared_hcd
);
188 static struct platform_driver usb_xhci_driver
= {
189 .probe
= xhci_plat_probe
,
190 .remove
= xhci_plat_remove
,
195 MODULE_ALIAS("platform:xhci-hcd");
197 int xhci_register_plat(void)
199 return platform_driver_register(&usb_xhci_driver
);
202 void xhci_unregister_plat(void)
204 platform_driver_unregister(&usb_xhci_driver
);