ohci-at91.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. /*
  2. * OHCI HCD (Host Controller Driver) for USB.
  3. *
  4. * Copyright (C) 2004 SAN People (Pty) Ltd.
  5. * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
  6. *
  7. * AT91 Bus Glue
  8. *
  9. * Based on fragments of 2.4 driver by Rick Bronson.
  10. * Based on ohci-omap.c
  11. *
  12. * This file is licenced under the GPL.
  13. */
  14. #include <linux/clk.h>
  15. #include <linux/dma-mapping.h>
  16. #include <linux/of_platform.h>
  17. #include <linux/of_gpio.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/platform_data/atmel.h>
  20. #include <linux/io.h>
  21. #include <linux/kernel.h>
  22. #include <linux/module.h>
  23. #include <linux/usb.h>
  24. #include <linux/usb/hcd.h>
  25. #include <asm/gpio.h>
  26. #include "ohci.h"
  27. #define valid_port(index) ((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)
  28. #define at91_for_each_port(index) \
  29. for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++)
  30. /* interface, function and usb clocks; sometimes also an AHB clock */
  31. static struct clk *iclk, *fclk, *uclk, *hclk;
  32. /* interface and function clocks; sometimes also an AHB clock */
  33. #define DRIVER_DESC "OHCI Atmel driver"
  34. static const char hcd_name[] = "ohci-atmel";
  35. static struct hc_driver __read_mostly ohci_at91_hc_driver;
  36. static int clocked;
  37. extern int usb_disabled(void);
  38. /*-------------------------------------------------------------------------*/
  39. static void at91_start_clock(void)
  40. {
  41. if (IS_ENABLED(CONFIG_COMMON_CLK)) {
  42. clk_set_rate(uclk, 48000000);
  43. clk_prepare_enable(uclk);
  44. }
  45. clk_prepare_enable(hclk);
  46. clk_prepare_enable(iclk);
  47. clk_prepare_enable(fclk);
  48. clocked = 1;
  49. }
  50. static void at91_stop_clock(void)
  51. {
  52. clk_disable_unprepare(fclk);
  53. clk_disable_unprepare(iclk);
  54. clk_disable_unprepare(hclk);
  55. if (IS_ENABLED(CONFIG_COMMON_CLK))
  56. clk_disable_unprepare(uclk);
  57. clocked = 0;
  58. }
  59. static void at91_start_hc(struct platform_device *pdev)
  60. {
  61. struct usb_hcd *hcd = platform_get_drvdata(pdev);
  62. struct ohci_regs __iomem *regs = hcd->regs;
  63. dev_dbg(&pdev->dev, "start\n");
  64. /*
  65. * Start the USB clocks.
  66. */
  67. at91_start_clock();
  68. /*
  69. * The USB host controller must remain in reset.
  70. */
  71. writel(0, &regs->control);
  72. }
  73. static void at91_stop_hc(struct platform_device *pdev)
  74. {
  75. struct usb_hcd *hcd = platform_get_drvdata(pdev);
  76. struct ohci_regs __iomem *regs = hcd->regs;
  77. dev_dbg(&pdev->dev, "stop\n");
  78. /*
  79. * Put the USB host controller into reset.
  80. */
  81. writel(0, &regs->control);
  82. /*
  83. * Stop the USB clocks.
  84. */
  85. at91_stop_clock();
  86. }
  87. /*-------------------------------------------------------------------------*/
  88. static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
  89. /* configure so an HC device and id are always provided */
  90. /* always called with process context; sleeping is OK */
  91. /**
  92. * usb_hcd_at91_probe - initialize AT91-based HCDs
  93. * Context: !in_interrupt()
  94. *
  95. * Allocates basic resources for this USB host controller, and
  96. * then invokes the start() method for the HCD associated with it
  97. * through the hotplug entry's driver_data.
  98. */
  99. static int usb_hcd_at91_probe(const struct hc_driver *driver,
  100. struct platform_device *pdev)
  101. {
  102. struct at91_usbh_data *board;
  103. struct ohci_hcd *ohci;
  104. int retval;
  105. struct usb_hcd *hcd = NULL;
  106. struct device *dev = &pdev->dev;
  107. struct resource *res;
  108. int irq;
  109. irq = platform_get_irq(pdev, 0);
  110. if (irq < 0) {
  111. dev_dbg(dev, "hcd probe: missing irq resource\n");
  112. return irq;
  113. }
  114. hcd = usb_create_hcd(driver, dev, "at91");
  115. if (!hcd)
  116. return -ENOMEM;
  117. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  118. hcd->regs = devm_ioremap_resource(dev, res);
  119. if (IS_ERR(hcd->regs)) {
  120. retval = PTR_ERR(hcd->regs);
  121. goto err;
  122. }
  123. hcd->rsrc_start = res->start;
  124. hcd->rsrc_len = resource_size(res);
  125. iclk = devm_clk_get(dev, "ohci_clk");
  126. if (IS_ERR(iclk)) {
  127. dev_err(dev, "failed to get ohci_clk\n");
  128. retval = PTR_ERR(iclk);
  129. goto err;
  130. }
  131. fclk = devm_clk_get(dev, "uhpck");
  132. if (IS_ERR(fclk)) {
  133. dev_err(dev, "failed to get uhpck\n");
  134. retval = PTR_ERR(fclk);
  135. goto err;
  136. }
  137. hclk = devm_clk_get(dev, "hclk");
  138. if (IS_ERR(hclk)) {
  139. dev_err(dev, "failed to get hclk\n");
  140. retval = PTR_ERR(hclk);
  141. goto err;
  142. }
  143. if (IS_ENABLED(CONFIG_COMMON_CLK)) {
  144. uclk = devm_clk_get(dev, "usb_clk");
  145. if (IS_ERR(uclk)) {
  146. dev_err(dev, "failed to get uclk\n");
  147. retval = PTR_ERR(uclk);
  148. goto err;
  149. }
  150. }
  151. board = hcd->self.controller->platform_data;
  152. ohci = hcd_to_ohci(hcd);
  153. ohci->num_ports = board->ports;
  154. at91_start_hc(pdev);
  155. retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
  156. if (retval == 0) {
  157. device_wakeup_enable(hcd->self.controller);
  158. return retval;
  159. }
  160. /* Error handling */
  161. at91_stop_hc(pdev);
  162. err:
  163. usb_put_hcd(hcd);
  164. return retval;
  165. }
  166. /* may be called with controller, bus, and devices active */
  167. /**
  168. * usb_hcd_at91_remove - shutdown processing for AT91-based HCDs
  169. * @dev: USB Host Controller being removed
  170. * Context: !in_interrupt()
  171. *
  172. * Reverses the effect of usb_hcd_at91_probe(), first invoking
  173. * the HCD's stop() method. It is always called from a thread
  174. * context, "rmmod" or something similar.
  175. *
  176. */
  177. static void usb_hcd_at91_remove(struct usb_hcd *hcd,
  178. struct platform_device *pdev)
  179. {
  180. usb_remove_hcd(hcd);
  181. at91_stop_hc(pdev);
  182. usb_put_hcd(hcd);
  183. }
  184. /*-------------------------------------------------------------------------*/
  185. static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
  186. {
  187. if (!valid_port(port))
  188. return;
  189. if (!gpio_is_valid(pdata->vbus_pin[port]))
  190. return;
  191. gpio_set_value(pdata->vbus_pin[port],
  192. pdata->vbus_pin_active_low[port] ^ enable);
  193. }
  194. static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
  195. {
  196. if (!valid_port(port))
  197. return -EINVAL;
  198. if (!gpio_is_valid(pdata->vbus_pin[port]))
  199. return -EINVAL;
  200. return gpio_get_value(pdata->vbus_pin[port]) ^
  201. pdata->vbus_pin_active_low[port];
  202. }
  203. /*
  204. * Update the status data from the hub with the over-current indicator change.
  205. */
  206. static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
  207. {
  208. struct at91_usbh_data *pdata = hcd->self.controller->platform_data;
  209. int length = ohci_hub_status_data(hcd, buf);
  210. int port;
  211. at91_for_each_port(port) {
  212. if (pdata->overcurrent_changed[port]) {
  213. if (!length)
  214. length = 1;
  215. buf[0] |= 1 << (port + 1);
  216. }
  217. }
  218. return length;
  219. }
  220. /*
  221. * Look at the control requests to the root hub and see if we need to override.
  222. */
  223. static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
  224. u16 wIndex, char *buf, u16 wLength)
  225. {
  226. struct at91_usbh_data *pdata = dev_get_platdata(hcd->self.controller);
  227. struct usb_hub_descriptor *desc;
  228. int ret = -EINVAL;
  229. u32 *data = (u32 *)buf;
  230. dev_dbg(hcd->self.controller,
  231. "ohci_at91_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n",
  232. hcd, typeReq, wValue, wIndex, buf, wLength);
  233. wIndex--;
  234. switch (typeReq) {
  235. case SetPortFeature:
  236. if (wValue == USB_PORT_FEAT_POWER) {
  237. dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n");
  238. if (valid_port(wIndex)) {
  239. ohci_at91_usb_set_power(pdata, wIndex, 1);
  240. ret = 0;
  241. }
  242. goto out;
  243. }
  244. break;
  245. case ClearPortFeature:
  246. switch (wValue) {
  247. case USB_PORT_FEAT_C_OVER_CURRENT:
  248. dev_dbg(hcd->self.controller,
  249. "ClearPortFeature: C_OVER_CURRENT\n");
  250. if (valid_port(wIndex)) {
  251. pdata->overcurrent_changed[wIndex] = 0;
  252. pdata->overcurrent_status[wIndex] = 0;
  253. }
  254. goto out;
  255. case USB_PORT_FEAT_OVER_CURRENT:
  256. dev_dbg(hcd->self.controller,
  257. "ClearPortFeature: OVER_CURRENT\n");
  258. if (valid_port(wIndex))
  259. pdata->overcurrent_status[wIndex] = 0;
  260. goto out;
  261. case USB_PORT_FEAT_POWER:
  262. dev_dbg(hcd->self.controller,
  263. "ClearPortFeature: POWER\n");
  264. if (valid_port(wIndex)) {
  265. ohci_at91_usb_set_power(pdata, wIndex, 0);
  266. return 0;
  267. }
  268. }
  269. break;
  270. }
  271. ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);
  272. if (ret)
  273. goto out;
  274. switch (typeReq) {
  275. case GetHubDescriptor:
  276. /* update the hub's descriptor */
  277. desc = (struct usb_hub_descriptor *)buf;
  278. dev_dbg(hcd->self.controller, "wHubCharacteristics 0x%04x\n",
  279. desc->wHubCharacteristics);
  280. /* remove the old configurations for power-switching, and
  281. * over-current protection, and insert our new configuration
  282. */
  283. desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM);
  284. desc->wHubCharacteristics |= cpu_to_le16(0x0001);
  285. if (pdata->overcurrent_supported) {
  286. desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_OCPM);
  287. desc->wHubCharacteristics |= cpu_to_le16(0x0008|0x0001);
  288. }
  289. dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n",
  290. desc->wHubCharacteristics);
  291. return ret;
  292. case GetPortStatus:
  293. /* check port status */
  294. dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex);
  295. if (valid_port(wIndex)) {
  296. if (!ohci_at91_usb_get_power(pdata, wIndex))
  297. *data &= ~cpu_to_le32(RH_PS_PPS);
  298. if (pdata->overcurrent_changed[wIndex])
  299. *data |= cpu_to_le32(RH_PS_OCIC);
  300. if (pdata->overcurrent_status[wIndex])
  301. *data |= cpu_to_le32(RH_PS_POCI);
  302. }
  303. }
  304. out:
  305. return ret;
  306. }
  307. /*-------------------------------------------------------------------------*/
  308. static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
  309. {
  310. struct platform_device *pdev = data;
  311. struct at91_usbh_data *pdata = dev_get_platdata(&pdev->dev);
  312. int val, gpio, port;
  313. /* From the GPIO notifying the over-current situation, find
  314. * out the corresponding port */
  315. at91_for_each_port(port) {
  316. if (gpio_is_valid(pdata->overcurrent_pin[port]) &&
  317. gpio_to_irq(pdata->overcurrent_pin[port]) == irq) {
  318. gpio = pdata->overcurrent_pin[port];
  319. break;
  320. }
  321. }
  322. if (port == AT91_MAX_USBH_PORTS) {
  323. dev_err(& pdev->dev, "overcurrent interrupt from unknown GPIO\n");
  324. return IRQ_HANDLED;
  325. }
  326. val = gpio_get_value(gpio);
  327. /* When notified of an over-current situation, disable power
  328. on the corresponding port, and mark this port in
  329. over-current. */
  330. if (!val) {
  331. ohci_at91_usb_set_power(pdata, port, 0);
  332. pdata->overcurrent_status[port] = 1;
  333. pdata->overcurrent_changed[port] = 1;
  334. }
  335. dev_dbg(& pdev->dev, "overcurrent situation %s\n",
  336. val ? "exited" : "notified");
  337. return IRQ_HANDLED;
  338. }
  339. #ifdef CONFIG_OF
  340. static const struct of_device_id at91_ohci_dt_ids[] = {
  341. { .compatible = "atmel,at91rm9200-ohci" },
  342. { /* sentinel */ }
  343. };
  344. MODULE_DEVICE_TABLE(of, at91_ohci_dt_ids);
  345. static int ohci_at91_of_init(struct platform_device *pdev)
  346. {
  347. struct device_node *np = pdev->dev.of_node;
  348. int i, gpio, ret;
  349. enum of_gpio_flags flags;
  350. struct at91_usbh_data *pdata;
  351. u32 ports;
  352. if (!np)
  353. return 0;
  354. /* Right now device-tree probed devices don't get dma_mask set.
  355. * Since shared usb code relies on it, set it here for now.
  356. * Once we have dma capability bindings this can go away.
  357. */
  358. ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
  359. if (ret)
  360. return ret;
  361. pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
  362. if (!pdata)
  363. return -ENOMEM;
  364. if (!of_property_read_u32(np, "num-ports", &ports))
  365. pdata->ports = ports;
  366. at91_for_each_port(i) {
  367. gpio = of_get_named_gpio_flags(np, "atmel,vbus-gpio", i, &flags);
  368. pdata->vbus_pin[i] = gpio;
  369. if (!gpio_is_valid(gpio))
  370. continue;
  371. pdata->vbus_pin_active_low[i] = flags & OF_GPIO_ACTIVE_LOW;
  372. }
  373. at91_for_each_port(i)
  374. pdata->overcurrent_pin[i] =
  375. of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
  376. pdev->dev.platform_data = pdata;
  377. return 0;
  378. }
  379. #else
  380. static int ohci_at91_of_init(struct platform_device *pdev)
  381. {
  382. return 0;
  383. }
  384. #endif
  385. /*-------------------------------------------------------------------------*/
  386. static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
  387. {
  388. struct at91_usbh_data *pdata;
  389. int i;
  390. int gpio;
  391. int ret;
  392. ret = ohci_at91_of_init(pdev);
  393. if (ret)
  394. return ret;
  395. pdata = dev_get_platdata(&pdev->dev);
  396. if (pdata) {
  397. at91_for_each_port(i) {
  398. /*
  399. * do not configure PIO if not in relation with
  400. * real USB port on board
  401. */
  402. if (i >= pdata->ports) {
  403. pdata->vbus_pin[i] = -EINVAL;
  404. pdata->overcurrent_pin[i] = -EINVAL;
  405. break;
  406. }
  407. if (!gpio_is_valid(pdata->vbus_pin[i]))
  408. continue;
  409. gpio = pdata->vbus_pin[i];
  410. ret = gpio_request(gpio, "ohci_vbus");
  411. if (ret) {
  412. dev_err(&pdev->dev,
  413. "can't request vbus gpio %d\n", gpio);
  414. continue;
  415. }
  416. ret = gpio_direction_output(gpio,
  417. !pdata->vbus_pin_active_low[i]);
  418. if (ret) {
  419. dev_err(&pdev->dev,
  420. "can't put vbus gpio %d as output %d\n",
  421. gpio, !pdata->vbus_pin_active_low[i]);
  422. gpio_free(gpio);
  423. continue;
  424. }
  425. ohci_at91_usb_set_power(pdata, i, 1);
  426. }
  427. at91_for_each_port(i) {
  428. if (!gpio_is_valid(pdata->overcurrent_pin[i]))
  429. continue;
  430. gpio = pdata->overcurrent_pin[i];
  431. ret = gpio_request(gpio, "ohci_overcurrent");
  432. if (ret) {
  433. dev_err(&pdev->dev,
  434. "can't request overcurrent gpio %d\n",
  435. gpio);
  436. continue;
  437. }
  438. ret = gpio_direction_input(gpio);
  439. if (ret) {
  440. dev_err(&pdev->dev,
  441. "can't configure overcurrent gpio %d as input\n",
  442. gpio);
  443. gpio_free(gpio);
  444. continue;
  445. }
  446. ret = request_irq(gpio_to_irq(gpio),
  447. ohci_hcd_at91_overcurrent_irq,
  448. IRQF_SHARED, "ohci_overcurrent", pdev);
  449. if (ret) {
  450. gpio_free(gpio);
  451. dev_err(&pdev->dev,
  452. "can't get gpio IRQ for overcurrent\n");
  453. }
  454. }
  455. }
  456. device_init_wakeup(&pdev->dev, 1);
  457. return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
  458. }
  459. static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
  460. {
  461. struct at91_usbh_data *pdata = dev_get_platdata(&pdev->dev);
  462. int i;
  463. if (pdata) {
  464. at91_for_each_port(i) {
  465. if (!gpio_is_valid(pdata->vbus_pin[i]))
  466. continue;
  467. ohci_at91_usb_set_power(pdata, i, 0);
  468. gpio_free(pdata->vbus_pin[i]);
  469. }
  470. at91_for_each_port(i) {
  471. if (!gpio_is_valid(pdata->overcurrent_pin[i]))
  472. continue;
  473. free_irq(gpio_to_irq(pdata->overcurrent_pin[i]), pdev);
  474. gpio_free(pdata->overcurrent_pin[i]);
  475. }
  476. }
  477. device_init_wakeup(&pdev->dev, 0);
  478. usb_hcd_at91_remove(platform_get_drvdata(pdev), pdev);
  479. return 0;
  480. }
  481. #ifdef CONFIG_PM
  482. static int
  483. ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
  484. {
  485. struct usb_hcd *hcd = platform_get_drvdata(pdev);
  486. struct ohci_hcd *ohci = hcd_to_ohci(hcd);
  487. bool do_wakeup = device_may_wakeup(&pdev->dev);
  488. int ret;
  489. if (do_wakeup)
  490. enable_irq_wake(hcd->irq);
  491. ret = ohci_suspend(hcd, do_wakeup);
  492. if (ret) {
  493. disable_irq_wake(hcd->irq);
  494. return ret;
  495. }
  496. /*
  497. * The integrated transceivers seem unable to notice disconnect,
  498. * reconnect, or wakeup without the 48 MHz clock active. so for
  499. * correctness, always discard connection state (using reset).
  500. *
  501. * REVISIT: some boards will be able to turn VBUS off...
  502. */
  503. if (at91_suspend_entering_slow_clock()) {
  504. ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
  505. ohci->hc_control &= OHCI_CTRL_RWC;
  506. ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
  507. ohci->rh_state = OHCI_RH_HALTED;
  508. /* flush the writes */
  509. (void) ohci_readl (ohci, &ohci->regs->control);
  510. at91_stop_clock();
  511. }
  512. return ret;
  513. }
  514. static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
  515. {
  516. struct usb_hcd *hcd = platform_get_drvdata(pdev);
  517. if (device_may_wakeup(&pdev->dev))
  518. disable_irq_wake(hcd->irq);
  519. if (!clocked)
  520. at91_start_clock();
  521. ohci_resume(hcd, false);
  522. return 0;
  523. }
  524. #else
  525. #define ohci_hcd_at91_drv_suspend NULL
  526. #define ohci_hcd_at91_drv_resume NULL
  527. #endif
  528. static struct platform_driver ohci_hcd_at91_driver = {
  529. .probe = ohci_hcd_at91_drv_probe,
  530. .remove = ohci_hcd_at91_drv_remove,
  531. .shutdown = usb_hcd_platform_shutdown,
  532. .suspend = ohci_hcd_at91_drv_suspend,
  533. .resume = ohci_hcd_at91_drv_resume,
  534. .driver = {
  535. .name = "at91_ohci",
  536. .of_match_table = of_match_ptr(at91_ohci_dt_ids),
  537. },
  538. };
  539. static int __init ohci_at91_init(void)
  540. {
  541. if (usb_disabled())
  542. return -ENODEV;
  543. pr_info("%s: " DRIVER_DESC "\n", hcd_name);
  544. ohci_init_driver(&ohci_at91_hc_driver, NULL);
  545. /*
  546. * The Atmel HW has some unusual quirks, which require Atmel-specific
  547. * workarounds. We override certain hc_driver functions here to
  548. * achieve that. We explicitly do not enhance ohci_driver_overrides to
  549. * allow this more easily, since this is an unusual case, and we don't
  550. * want to encourage others to override these functions by making it
  551. * too easy.
  552. */
  553. ohci_at91_hc_driver.hub_status_data = ohci_at91_hub_status_data;
  554. ohci_at91_hc_driver.hub_control = ohci_at91_hub_control;
  555. return platform_driver_register(&ohci_hcd_at91_driver);
  556. }
  557. module_init(ohci_at91_init);
  558. static void __exit ohci_at91_cleanup(void)
  559. {
  560. platform_driver_unregister(&ohci_hcd_at91_driver);
  561. }
  562. module_exit(ohci_at91_cleanup);
  563. MODULE_DESCRIPTION(DRIVER_DESC);
  564. MODULE_LICENSE("GPL");
  565. MODULE_ALIAS("platform:at91_ohci");