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 #include <linux/usb/xhci_pdriver.h> 21 22 #include "xhci.h" 23 #include "xhci-mvebu.h" 24 #include "xhci-rcar.h" 25 26 static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) 27 { 28 /* 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 32 */ 33 xhci->quirks |= XHCI_PLAT; 34 } 35 36 /* called during probe() after chip reset completes */ 37 static int xhci_plat_setup(struct usb_hcd *hcd) 38 { 39 struct device_node *of_node = hcd->self.controller->of_node; 40 int ret; 41 42 if (of_device_is_compatible(of_node, "renesas,xhci-r8a7790") || 43 of_device_is_compatible(of_node, "renesas,xhci-r8a7791")) { 44 ret = xhci_rcar_init_quirk(hcd); 45 if (ret) 46 return ret; 47 } 48 49 return xhci_gen_setup(hcd, xhci_plat_quirks); 50 } 51 52 static int xhci_plat_start(struct usb_hcd *hcd) 53 { 54 struct device_node *of_node = hcd->self.controller->of_node; 55 56 if (of_device_is_compatible(of_node, "renesas,xhci-r8a7790") || 57 of_device_is_compatible(of_node, "renesas,xhci-r8a7791")) 58 xhci_rcar_start(hcd); 59 60 return xhci_run(hcd); 61 } 62 63 static const struct hc_driver xhci_plat_xhci_driver = { 64 .description = "xhci-hcd", 65 .product_desc = "xHCI Host Controller", 66 .hcd_priv_size = sizeof(struct xhci_hcd *), 67 68 /* 69 * generic hardware linkage 70 */ 71 .irq = xhci_irq, 72 .flags = HCD_MEMORY | HCD_USB3 | HCD_SHARED, 73 74 /* 75 * basic lifecycle operations 76 */ 77 .reset = xhci_plat_setup, 78 .start = xhci_plat_start, 79 .stop = xhci_stop, 80 .shutdown = xhci_shutdown, 81 82 /* 83 * managing i/o requests and associated device resources 84 */ 85 .urb_enqueue = xhci_urb_enqueue, 86 .urb_dequeue = xhci_urb_dequeue, 87 .alloc_dev = xhci_alloc_dev, 88 .free_dev = xhci_free_dev, 89 .alloc_streams = xhci_alloc_streams, 90 .free_streams = xhci_free_streams, 91 .add_endpoint = xhci_add_endpoint, 92 .drop_endpoint = xhci_drop_endpoint, 93 .endpoint_reset = xhci_endpoint_reset, 94 .check_bandwidth = xhci_check_bandwidth, 95 .reset_bandwidth = xhci_reset_bandwidth, 96 .address_device = xhci_address_device, 97 .enable_device = xhci_enable_device, 98 .update_hub_device = xhci_update_hub_device, 99 .reset_device = xhci_discover_or_reset_device, 100 101 /* 102 * scheduling support 103 */ 104 .get_frame_number = xhci_get_frame, 105 106 /* Root hub support */ 107 .hub_control = xhci_hub_control, 108 .hub_status_data = xhci_hub_status_data, 109 .bus_suspend = xhci_bus_suspend, 110 .bus_resume = xhci_bus_resume, 111 112 .enable_usb3_lpm_timeout = xhci_enable_usb3_lpm_timeout, 113 .disable_usb3_lpm_timeout = xhci_disable_usb3_lpm_timeout, 114 }; 115 116 static int xhci_plat_probe(struct platform_device *pdev) 117 { 118 struct device_node *node = pdev->dev.of_node; 119 struct usb_xhci_pdata *pdata = dev_get_platdata(&pdev->dev); 120 const struct hc_driver *driver; 121 struct xhci_hcd *xhci; 122 struct resource *res; 123 struct usb_hcd *hcd; 124 struct clk *clk; 125 int ret; 126 int irq; 127 128 if (usb_disabled()) 129 return -ENODEV; 130 131 driver = &xhci_plat_xhci_driver; 132 133 irq = platform_get_irq(pdev, 0); 134 if (irq < 0) 135 return -ENODEV; 136 137 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 138 if (!res) 139 return -ENODEV; 140 141 if (of_device_is_compatible(pdev->dev.of_node, 142 "marvell,armada-375-xhci") || 143 of_device_is_compatible(pdev->dev.of_node, 144 "marvell,armada-380-xhci")) { 145 ret = xhci_mvebu_mbus_init_quirk(pdev); 146 if (ret) 147 return ret; 148 } 149 150 /* Initialize dma_mask and coherent_dma_mask to 32-bits */ 151 ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); 152 if (ret) 153 return ret; 154 if (!pdev->dev.dma_mask) 155 pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; 156 else 157 dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); 158 159 hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); 160 if (!hcd) 161 return -ENOMEM; 162 163 hcd->rsrc_start = res->start; 164 hcd->rsrc_len = resource_size(res); 165 166 hcd->regs = devm_ioremap_resource(&pdev->dev, res); 167 if (IS_ERR(hcd->regs)) { 168 ret = PTR_ERR(hcd->regs); 169 goto put_hcd; 170 } 171 172 /* 173 * Not all platforms have a clk so it is not an error if the 174 * clock does not exists. 175 */ 176 clk = devm_clk_get(&pdev->dev, NULL); 177 if (!IS_ERR(clk)) { 178 ret = clk_prepare_enable(clk); 179 if (ret) 180 goto put_hcd; 181 } 182 183 ret = usb_add_hcd(hcd, irq, IRQF_SHARED); 184 if (ret) 185 goto disable_clk; 186 187 device_wakeup_enable(hcd->self.controller); 188 189 /* USB 2.0 roothub is stored in the platform_device now. */ 190 hcd = platform_get_drvdata(pdev); 191 xhci = hcd_to_xhci(hcd); 192 xhci->clk = clk; 193 xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev, 194 dev_name(&pdev->dev), hcd); 195 if (!xhci->shared_hcd) { 196 ret = -ENOMEM; 197 goto dealloc_usb2_hcd; 198 } 199 200 if ((node && of_property_read_bool(node, "usb3-lpm-capable")) || 201 (pdata && pdata->usb3_lpm_capable)) 202 xhci->quirks |= XHCI_LPM_SUPPORT; 203 /* 204 * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset) 205 * is called by usb_add_hcd(). 206 */ 207 *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; 208 209 if (HCC_MAX_PSA(xhci->hcc_params) >= 4) 210 xhci->shared_hcd->can_do_streams = 1; 211 212 ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); 213 if (ret) 214 goto put_usb3_hcd; 215 216 return 0; 217 218 put_usb3_hcd: 219 usb_put_hcd(xhci->shared_hcd); 220 221 dealloc_usb2_hcd: 222 usb_remove_hcd(hcd); 223 224 disable_clk: 225 if (!IS_ERR(clk)) 226 clk_disable_unprepare(clk); 227 228 put_hcd: 229 usb_put_hcd(hcd); 230 231 return ret; 232 } 233 234 static int xhci_plat_remove(struct platform_device *dev) 235 { 236 struct usb_hcd *hcd = platform_get_drvdata(dev); 237 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 238 struct clk *clk = xhci->clk; 239 240 usb_remove_hcd(xhci->shared_hcd); 241 usb_put_hcd(xhci->shared_hcd); 242 243 usb_remove_hcd(hcd); 244 if (!IS_ERR(clk)) 245 clk_disable_unprepare(clk); 246 usb_put_hcd(hcd); 247 kfree(xhci); 248 249 return 0; 250 } 251 252 #ifdef CONFIG_PM_SLEEP 253 static int xhci_plat_suspend(struct device *dev) 254 { 255 struct usb_hcd *hcd = dev_get_drvdata(dev); 256 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 257 258 return xhci_suspend(xhci); 259 } 260 261 static int xhci_plat_resume(struct device *dev) 262 { 263 struct usb_hcd *hcd = dev_get_drvdata(dev); 264 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 265 266 return xhci_resume(xhci, 0); 267 } 268 269 static const struct dev_pm_ops xhci_plat_pm_ops = { 270 SET_SYSTEM_SLEEP_PM_OPS(xhci_plat_suspend, xhci_plat_resume) 271 }; 272 #define DEV_PM_OPS (&xhci_plat_pm_ops) 273 #else 274 #define DEV_PM_OPS NULL 275 #endif /* CONFIG_PM */ 276 277 #ifdef CONFIG_OF 278 static const struct of_device_id usb_xhci_of_match[] = { 279 { .compatible = "generic-xhci" }, 280 { .compatible = "xhci-platform" }, 281 { .compatible = "marvell,armada-375-xhci"}, 282 { .compatible = "marvell,armada-380-xhci"}, 283 { .compatible = "renesas,xhci-r8a7790"}, 284 { .compatible = "renesas,xhci-r8a7791"}, 285 { }, 286 }; 287 MODULE_DEVICE_TABLE(of, usb_xhci_of_match); 288 #endif 289 290 static struct platform_driver usb_xhci_driver = { 291 .probe = xhci_plat_probe, 292 .remove = xhci_plat_remove, 293 .driver = { 294 .name = "xhci-hcd", 295 .pm = DEV_PM_OPS, 296 .of_match_table = of_match_ptr(usb_xhci_of_match), 297 }, 298 }; 299 MODULE_ALIAS("platform:xhci-hcd"); 300 301 int xhci_register_plat(void) 302 { 303 return platform_driver_register(&usb_xhci_driver); 304 } 305 306 void xhci_unregister_plat(void) 307 { 308 platform_driver_unregister(&usb_xhci_driver); 309 } 310