17e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack/* 27e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix 37e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> 47e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * 57e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * This program is free software; you can redistribute it and/or modify it 67e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * under the terms of the GNU General Public License as published by the 77e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * Free Software Foundation; either version 2 of the License, or (at your 87e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * option) any later version. 97e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * 107e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * This program is distributed in the hope that it will be useful, but 117e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 127e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 137e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * for more details. 147e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * 157e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * You should have received a copy of the GNU General Public License 167e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * along with this program; if not, write to the Free Software Foundation, 177e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 187e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack */ 197e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 20dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern#include <linux/kernel.h> 21dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern#include <linux/module.h> 22dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern#include <linux/io.h> 237e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack#include <linux/platform_device.h> 247e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack#include <linux/clk.h> 257e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack#include <linux/delay.h> 267e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack#include <linux/usb/otg.h> 27a464dc4d4044c936d4558725fa2229fb4a1aa932Arnaud Patard#include <linux/usb/ulpi.h> 285a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 29dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern#include <linux/usb.h> 30dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern#include <linux/usb/hcd.h> 3182906b13a6f4f42edec92f0a3e480e1bdd9b3f91Arnd Bergmann#include <linux/platform_data/usb-ehci-mxc.h> 32dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern#include "ehci.h" 33dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern 34dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern#define DRIVER_DESC "Freescale On-Chip EHCI Host driver" 35dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern 36dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Sternstatic const char hcd_name[] = "ehci-mxc"; 37dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern 387e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack#define ULPI_VIEWPORT_OFFSET 0x170 397e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 407e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mackstruct ehci_mxc_priv { 41c943740ccd7ccfc7e92c80d194d0a8a80ab7b55cSascha Hauer struct clk *usbclk, *ahbclk, *phyclk; 427e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack}; 437e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 44dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Sternstatic struct hc_driver __read_mostly ehci_mxc_hc_driver; 457e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 4662d08a1151d2755dc580a8311a6684275e4aeb94Andi Kleenstatic const struct ehci_driver_overrides ehci_mxc_overrides __initconst = { 47dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern .extra_priv_size = sizeof(struct ehci_mxc_priv), 487e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack}; 497e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 507e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mackstatic int ehci_mxc_drv_probe(struct platform_device *pdev) 517e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack{ 52d4f09e28d7bc5c1adde8229b1e89401f23fb44f9Jingoo Han struct mxc_usbh_platform_data *pdata = dev_get_platdata(&pdev->dev); 537e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack struct usb_hcd *hcd; 547e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack struct resource *res; 55724c85251f78f1332e0a28f80cead0cee5b7c906Uwe Kleine-König int irq, ret; 567e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack struct ehci_mxc_priv *priv; 577e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack struct device *dev = &pdev->dev; 580247a7bcd4273fa10c4aba9b3f567c659bab2d2bFabio Estevam struct ehci_hcd *ehci; 597e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 607e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack if (!pdata) { 617e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack dev_err(dev, "No platform data given, bailing out.\n"); 627e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack return -EINVAL; 637e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack } 647e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 657e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack irq = platform_get_irq(pdev, 0); 667e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 677e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack hcd = usb_create_hcd(&ehci_mxc_hc_driver, dev, dev_name(dev)); 687e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack if (!hcd) 697e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack return -ENOMEM; 707e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 717e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 727e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack if (!res) { 737e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack dev_err(dev, "Found HC with no register addr. Check setup!\n"); 747e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack ret = -ENODEV; 75af09c060895b9c9137c02943c71302ac0fc9555aJulia Lawall goto err_alloc; 767e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack } 777e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 787e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack hcd->rsrc_start = res->start; 797e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack hcd->rsrc_len = resource_size(res); 807e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 81148e11349b0c9c7199fd3096254bd3ea16d59a05Thierry Reding hcd->regs = devm_ioremap_resource(&pdev->dev, res); 82148e11349b0c9c7199fd3096254bd3ea16d59a05Thierry Reding if (IS_ERR(hcd->regs)) { 83148e11349b0c9c7199fd3096254bd3ea16d59a05Thierry Reding ret = PTR_ERR(hcd->regs); 84af09c060895b9c9137c02943c71302ac0fc9555aJulia Lawall goto err_alloc; 857e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack } 867e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 87dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern hcd->has_tt = 1; 88dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern ehci = hcd_to_ehci(hcd); 89dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern priv = (struct ehci_mxc_priv *) ehci->priv; 90dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern 917e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack /* enable clocks */ 92af09c060895b9c9137c02943c71302ac0fc9555aJulia Lawall priv->usbclk = devm_clk_get(&pdev->dev, "ipg"); 937e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack if (IS_ERR(priv->usbclk)) { 947e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack ret = PTR_ERR(priv->usbclk); 95af09c060895b9c9137c02943c71302ac0fc9555aJulia Lawall goto err_alloc; 967e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack } 97198ad2cecde16ce309a65f2fddd5f6d3442f8250Sascha Hauer clk_prepare_enable(priv->usbclk); 987e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 99af09c060895b9c9137c02943c71302ac0fc9555aJulia Lawall priv->ahbclk = devm_clk_get(&pdev->dev, "ahb"); 100c943740ccd7ccfc7e92c80d194d0a8a80ab7b55cSascha Hauer if (IS_ERR(priv->ahbclk)) { 101c943740ccd7ccfc7e92c80d194d0a8a80ab7b55cSascha Hauer ret = PTR_ERR(priv->ahbclk); 102c943740ccd7ccfc7e92c80d194d0a8a80ab7b55cSascha Hauer goto err_clk_ahb; 1037e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack } 104c943740ccd7ccfc7e92c80d194d0a8a80ab7b55cSascha Hauer clk_prepare_enable(priv->ahbclk); 1057e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 1063bb8029a2445e289efade6133b01545143336f70Eric Bénard /* "dr" device has its own clock on i.MX51 */ 107af09c060895b9c9137c02943c71302ac0fc9555aJulia Lawall priv->phyclk = devm_clk_get(&pdev->dev, "phy"); 108c943740ccd7ccfc7e92c80d194d0a8a80ab7b55cSascha Hauer if (IS_ERR(priv->phyclk)) 109c943740ccd7ccfc7e92c80d194d0a8a80ab7b55cSascha Hauer priv->phyclk = NULL; 110c943740ccd7ccfc7e92c80d194d0a8a80ab7b55cSascha Hauer if (priv->phyclk) 111c943740ccd7ccfc7e92c80d194d0a8a80ab7b55cSascha Hauer clk_prepare_enable(priv->phyclk); 112711669e5b80b6f2d88f61ed8a9681f83d8cbd201Arnaud Patard 113711669e5b80b6f2d88f61ed8a9681f83d8cbd201Arnaud Patard 114711669e5b80b6f2d88f61ed8a9681f83d8cbd201Arnaud Patard /* call platform specific init function */ 115711669e5b80b6f2d88f61ed8a9681f83d8cbd201Arnaud Patard if (pdata->init) { 116711669e5b80b6f2d88f61ed8a9681f83d8cbd201Arnaud Patard ret = pdata->init(pdev); 117711669e5b80b6f2d88f61ed8a9681f83d8cbd201Arnaud Patard if (ret) { 118711669e5b80b6f2d88f61ed8a9681f83d8cbd201Arnaud Patard dev_err(dev, "platform init failed\n"); 119711669e5b80b6f2d88f61ed8a9681f83d8cbd201Arnaud Patard goto err_init; 120711669e5b80b6f2d88f61ed8a9681f83d8cbd201Arnaud Patard } 121711669e5b80b6f2d88f61ed8a9681f83d8cbd201Arnaud Patard /* platforms need some time to settle changed IO settings */ 122711669e5b80b6f2d88f61ed8a9681f83d8cbd201Arnaud Patard mdelay(10); 123711669e5b80b6f2d88f61ed8a9681f83d8cbd201Arnaud Patard } 124711669e5b80b6f2d88f61ed8a9681f83d8cbd201Arnaud Patard 1250247a7bcd4273fa10c4aba9b3f567c659bab2d2bFabio Estevam /* EHCI registers start at offset 0x100 */ 1260247a7bcd4273fa10c4aba9b3f567c659bab2d2bFabio Estevam ehci->caps = hcd->regs + 0x100; 1270247a7bcd4273fa10c4aba9b3f567c659bab2d2bFabio Estevam ehci->regs = hcd->regs + 0x100 + 128c430131a02d677aa708f56342c1565edfdacb3c0Jan Andersson HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); 1290247a7bcd4273fa10c4aba9b3f567c659bab2d2bFabio Estevam 1300247a7bcd4273fa10c4aba9b3f567c659bab2d2bFabio Estevam /* set up the PORTSCx register */ 1310247a7bcd4273fa10c4aba9b3f567c659bab2d2bFabio Estevam ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]); 1320247a7bcd4273fa10c4aba9b3f567c659bab2d2bFabio Estevam 1330247a7bcd4273fa10c4aba9b3f567c659bab2d2bFabio Estevam /* is this really needed? */ 1340247a7bcd4273fa10c4aba9b3f567c659bab2d2bFabio Estevam msleep(10); 1350247a7bcd4273fa10c4aba9b3f567c659bab2d2bFabio Estevam 1367e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack /* Initialize the transceiver */ 1377e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack if (pdata->otg) { 1387e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET; 139b96d3b08365f5a9603f50f3aadca6012f7eaffa1Heikki Krogerus ret = usb_phy_init(pdata->otg); 1404c9715de52b9b6256bf1e9510917111a47b0c176Wolfram Sang if (ret) { 1414c9715de52b9b6256bf1e9510917111a47b0c176Wolfram Sang dev_err(dev, "unable to init transceiver, probably missing\n"); 1424c9715de52b9b6256bf1e9510917111a47b0c176Wolfram Sang ret = -ENODEV; 1434c9715de52b9b6256bf1e9510917111a47b0c176Wolfram Sang goto err_add; 1444c9715de52b9b6256bf1e9510917111a47b0c176Wolfram Sang } 1456e13c6505cdff9766d5268ffb8c972c1a2f996e6Heikki Krogerus ret = otg_set_vbus(pdata->otg->otg, 1); 1464c9715de52b9b6256bf1e9510917111a47b0c176Wolfram Sang if (ret) { 1477e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack dev_err(dev, "unable to enable vbus on transceiver\n"); 1484c9715de52b9b6256bf1e9510917111a47b0c176Wolfram Sang goto err_add; 1494c9715de52b9b6256bf1e9510917111a47b0c176Wolfram Sang } 1507e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack } 1517e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 152dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern platform_set_drvdata(pdev, hcd); 1537e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 154b5dd18d8747010e3f3eb1cc76a49f94291938559Yong Zhang ret = usb_add_hcd(hcd, irq, IRQF_SHARED); 1557e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack if (ret) 1567e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack goto err_add; 1577e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 1583c9740a117d40a74412775b5d3fe2b88a7635a0ePeter Chen device_wakeup_enable(hcd->self.controller); 1597e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack return 0; 1607e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 1617e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mackerr_add: 1627e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack if (pdata && pdata->exit) 1637e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack pdata->exit(pdev); 1647e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mackerr_init: 165af09c060895b9c9137c02943c71302ac0fc9555aJulia Lawall if (priv->phyclk) 166c943740ccd7ccfc7e92c80d194d0a8a80ab7b55cSascha Hauer clk_disable_unprepare(priv->phyclk); 167c943740ccd7ccfc7e92c80d194d0a8a80ab7b55cSascha Hauer 168c943740ccd7ccfc7e92c80d194d0a8a80ab7b55cSascha Hauer clk_disable_unprepare(priv->ahbclk); 1697e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mackerr_clk_ahb: 170198ad2cecde16ce309a65f2fddd5f6d3442f8250Sascha Hauer clk_disable_unprepare(priv->usbclk); 1717e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mackerr_alloc: 1727e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack usb_put_hcd(hcd); 1737e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack return ret; 1747e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack} 1757e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 17639d35681d5380b403855202dcd75575a8d5b0ec1Dmitry Torokhovstatic int ehci_mxc_drv_remove(struct platform_device *pdev) 1777e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack{ 178d4f09e28d7bc5c1adde8229b1e89401f23fb44f9Jingoo Han struct mxc_usbh_platform_data *pdata = dev_get_platdata(&pdev->dev); 179dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern struct usb_hcd *hcd = platform_get_drvdata(pdev); 180dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern struct ehci_hcd *ehci = hcd_to_ehci(hcd); 181dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern struct ehci_mxc_priv *priv = (struct ehci_mxc_priv *) ehci->priv; 182dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern 183dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern usb_remove_hcd(hcd); 1847e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 1857e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack if (pdata && pdata->exit) 1867e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack pdata->exit(pdev); 1877e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 188f375fc520d4df0cd9fcb570f33c103c6c0311f9eDaniel Mack if (pdata && pdata->otg) 189b96d3b08365f5a9603f50f3aadca6012f7eaffa1Heikki Krogerus usb_phy_shutdown(pdata->otg); 1907e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 191198ad2cecde16ce309a65f2fddd5f6d3442f8250Sascha Hauer clk_disable_unprepare(priv->usbclk); 192c943740ccd7ccfc7e92c80d194d0a8a80ab7b55cSascha Hauer clk_disable_unprepare(priv->ahbclk); 193c943740ccd7ccfc7e92c80d194d0a8a80ab7b55cSascha Hauer 194af09c060895b9c9137c02943c71302ac0fc9555aJulia Lawall if (priv->phyclk) 195c943740ccd7ccfc7e92c80d194d0a8a80ab7b55cSascha Hauer clk_disable_unprepare(priv->phyclk); 1967e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 197dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern usb_put_hcd(hcd); 1987e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack return 0; 1997e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack} 2007e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 2017e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel MackMODULE_ALIAS("platform:mxc-ehci"); 2027e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack 2037e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mackstatic struct platform_driver ehci_mxc_driver = { 2047e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack .probe = ehci_mxc_drv_probe, 205dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern .remove = ehci_mxc_drv_remove, 206aaf6b52d50f85ed792c9c8987f5169f3dce2adeaRoger Quadros .shutdown = usb_hcd_platform_shutdown, 2077e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack .driver = { 2087e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack .name = "mxc-ehci", 2097e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack }, 2107e8d5cd93fac4d3720d8f780b350c9421e8997d4Daniel Mack}; 211dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern 212dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Sternstatic int __init ehci_mxc_init(void) 213dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern{ 214dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern if (usb_disabled()) 215dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern return -ENODEV; 216dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern 217dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern pr_info("%s: " DRIVER_DESC "\n", hcd_name); 218dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern 219dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern ehci_init_driver(&ehci_mxc_hc_driver, &ehci_mxc_overrides); 220dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern return platform_driver_register(&ehci_mxc_driver); 221dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern} 222dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Sternmodule_init(ehci_mxc_init); 223dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern 224dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Sternstatic void __exit ehci_mxc_cleanup(void) 225dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern{ 226dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern platform_driver_unregister(&ehci_mxc_driver); 227dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern} 228dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Sternmodule_exit(ehci_mxc_cleanup); 229dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan Stern 230dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan SternMODULE_DESCRIPTION(DRIVER_DESC); 231dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan SternMODULE_AUTHOR("Sascha Hauer"); 232dba63b2f733ebfd89bbb15e8fe8ca10fd3871a7fAlan SternMODULE_LICENSE("GPL"); 233