1 /* 2 * xhci-plat.c - xHCI host controller driver platform Bus Glue. 3 * 4 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com 5 * Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de> 6 * 7 * A lot of code borrowed from the Linux xHCI driver. 8 * 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. 12 */ 13 14 #include <linux/clk.h> 15 #include <linux/dma-mapping.h> 16 #include <linux/module.h> 17 #include <linux/of.h> 18 #include <linux/platform_device.h> 19 #include <linux/slab.h> 20 21 #include "xhci.h" 22 #include "xhci-mvebu.h" 23 24 static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) 25 { 26 /* 27 * As of now platform drivers don't provide MSI support so we ensure 28 * here that the generic code does not try to make a pci_dev from our 29 * dev struct in order to setup MSI 30 */ 31 xhci->quirks |= XHCI_PLAT; 32 } 33 34 /* called during probe() after chip reset completes */ 35 static int xhci_plat_setup(struct usb_hcd *hcd) 36 { 37 return xhci_gen_setup(hcd, xhci_plat_quirks); 38 } 39 40 static int xhci_plat_start(struct usb_hcd *hcd) 41 { 42 return xhci_run(hcd); 43 } 44 45 static const struct hc_driver xhci_plat_xhci_driver = { 46 .description = "xhci-hcd", 47 .product_desc = "xHCI Host Controller", 48 .hcd_priv_size = sizeof(struct xhci_hcd *), 49 50 /* 51 * generic hardware linkage 52 */ 53 .irq = xhci_irq, 54 .flags = HCD_MEMORY | HCD_USB3 | HCD_SHARED, 55 56 /* 57 * basic lifecycle operations 58 */ 59 .reset = xhci_plat_setup, 60 .start = xhci_plat_start, 61 .stop = xhci_stop, 62 .shutdown = xhci_shutdown, 63 64 /* 65 * managing i/o requests and associated device resources 66 */ 67 .urb_enqueue = xhci_urb_enqueue, 68 .urb_dequeue = xhci_urb_dequeue, 69 .alloc_dev = xhci_alloc_dev, 70 .free_dev = xhci_free_dev, 71 .alloc_streams = xhci_alloc_streams, 72 .free_streams = xhci_free_streams, 73 .add_endpoint = xhci_add_endpoint, 74 .drop_endpoint = xhci_drop_endpoint, 75 .endpoint_reset = xhci_endpoint_reset, 76 .check_bandwidth = xhci_check_bandwidth, 77 .reset_bandwidth = xhci_reset_bandwidth, 78 .address_device = xhci_address_device, 79 .enable_device = xhci_enable_device, 80 .update_hub_device = xhci_update_hub_device, 81 .reset_device = xhci_discover_or_reset_device, 82 83 /* 84 * scheduling support 85 */ 86 .get_frame_number = xhci_get_frame, 87 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, 93 }; 94 95 static int xhci_plat_probe(struct platform_device *pdev) 96 { 97 const struct hc_driver *driver; 98 struct xhci_hcd *xhci; 99 struct resource *res; 100 struct usb_hcd *hcd; 101 struct clk *clk; 102 int ret; 103 int irq; 104 105 if (usb_disabled()) 106 return -ENODEV; 107 108 driver = &xhci_plat_xhci_driver; 109 110 irq = platform_get_irq(pdev, 0); 111 if (irq < 0) 112 return -ENODEV; 113 114 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 115 if (!res) 116 return -ENODEV; 117 118 if (of_device_is_compatible(pdev->dev.of_node, 119 "marvell,armada-375-xhci") || 120 of_device_is_compatible(pdev->dev.of_node, 121 "marvell,armada-380-xhci")) { 122 ret = xhci_mvebu_mbus_init_quirk(pdev); 123 if (ret) 124 return ret; 125 } 126 127 /* Initialize dma_mask and coherent_dma_mask to 32-bits */ 128 ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); 129 if (ret) 130 return ret; 131 if (!pdev->dev.dma_mask) 132 pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; 133 else 134 dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); 135 136 hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); 137 if (!hcd) 138 return -ENOMEM; 139 140 hcd->rsrc_start = res->start; 141 hcd->rsrc_len = resource_size(res); 142 143 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, 144 driver->description)) { 145 dev_dbg(&pdev->dev, "controller already in use\n"); 146 ret = -EBUSY; 147 goto put_hcd; 148 } 149 150 hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); 151 if (!hcd->regs) { 152 dev_dbg(&pdev->dev, "error mapping memory\n"); 153 ret = -EFAULT; 154 goto release_mem_region; 155 } 156 157 /* 158 * Not all platforms have a clk so it is not an error if the 159 * clock does not exists. 160 */ 161 clk = devm_clk_get(&pdev->dev, NULL); 162 if (!IS_ERR(clk)) { 163 ret = clk_prepare_enable(clk); 164 if (ret) 165 goto unmap_registers; 166 } 167 168 ret = usb_add_hcd(hcd, irq, IRQF_SHARED); 169 if (ret) 170 goto disable_clk; 171 172 device_wakeup_enable(hcd->self.controller); 173 174 /* USB 2.0 roothub is stored in the platform_device now. */ 175 hcd = platform_get_drvdata(pdev); 176 xhci = hcd_to_xhci(hcd); 177 xhci->clk = clk; 178 xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev, 179 dev_name(&pdev->dev), hcd); 180 if (!xhci->shared_hcd) { 181 ret = -ENOMEM; 182 goto dealloc_usb2_hcd; 183 } 184 185 /* 186 * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset) 187 * is called by usb_add_hcd(). 188 */ 189 *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; 190 191 if (HCC_MAX_PSA(xhci->hcc_params) >= 4) 192 xhci->shared_hcd->can_do_streams = 1; 193 194 ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); 195 if (ret) 196 goto put_usb3_hcd; 197 198 return 0; 199 200 put_usb3_hcd: 201 usb_put_hcd(xhci->shared_hcd); 202 203 dealloc_usb2_hcd: 204 usb_remove_hcd(hcd); 205 206 disable_clk: 207 if (!IS_ERR(clk)) 208 clk_disable_unprepare(clk); 209 210 unmap_registers: 211 iounmap(hcd->regs); 212 213 release_mem_region: 214 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 215 216 put_hcd: 217 usb_put_hcd(hcd); 218 219 return ret; 220 } 221 222 static int xhci_plat_remove(struct platform_device *dev) 223 { 224 struct usb_hcd *hcd = platform_get_drvdata(dev); 225 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 226 struct clk *clk = xhci->clk; 227 228 usb_remove_hcd(xhci->shared_hcd); 229 usb_put_hcd(xhci->shared_hcd); 230 231 usb_remove_hcd(hcd); 232 if (!IS_ERR(clk)) 233 clk_disable_unprepare(clk); 234 iounmap(hcd->regs); 235 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 236 usb_put_hcd(hcd); 237 kfree(xhci); 238 239 return 0; 240 } 241 242 #ifdef CONFIG_PM_SLEEP 243 static int xhci_plat_suspend(struct device *dev) 244 { 245 struct usb_hcd *hcd = dev_get_drvdata(dev); 246 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 247 248 return xhci_suspend(xhci); 249 } 250 251 static int xhci_plat_resume(struct device *dev) 252 { 253 struct usb_hcd *hcd = dev_get_drvdata(dev); 254 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 255 256 return xhci_resume(xhci, 0); 257 } 258 259 static const struct dev_pm_ops xhci_plat_pm_ops = { 260 SET_SYSTEM_SLEEP_PM_OPS(xhci_plat_suspend, xhci_plat_resume) 261 }; 262 #define DEV_PM_OPS (&xhci_plat_pm_ops) 263 #else 264 #define DEV_PM_OPS NULL 265 #endif /* CONFIG_PM */ 266 267 #ifdef CONFIG_OF 268 static const struct of_device_id usb_xhci_of_match[] = { 269 { .compatible = "generic-xhci" }, 270 { .compatible = "xhci-platform" }, 271 { .compatible = "marvell,armada-375-xhci"}, 272 { .compatible = "marvell,armada-380-xhci"}, 273 { }, 274 }; 275 MODULE_DEVICE_TABLE(of, usb_xhci_of_match); 276 #endif 277 278 static struct platform_driver usb_xhci_driver = { 279 .probe = xhci_plat_probe, 280 .remove = xhci_plat_remove, 281 .driver = { 282 .name = "xhci-hcd", 283 .pm = DEV_PM_OPS, 284 .of_match_table = of_match_ptr(usb_xhci_of_match), 285 }, 286 }; 287 MODULE_ALIAS("platform:xhci-hcd"); 288 289 int xhci_register_plat(void) 290 { 291 return platform_driver_register(&usb_xhci_driver); 292 } 293 294 void xhci_unregister_plat(void) 295 { 296 platform_driver_unregister(&usb_xhci_driver); 297 } 298