Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.0-rc5 151 lines 3.3 kB view raw
1/* 2 * OHCI HCD (Host Controller Driver) for USB. 3 * 4 * Bus Glue for Atheros AR71XX/AR724X built-in OHCI controller. 5 * 6 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> 7 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 8 * 9 * Parts of this file are based on Atheros' 2.6.15 BSP 10 * Copyright (C) 2007 Atheros Communications, Inc. 11 * 12 * This program is free software; you can redistribute it and/or modify it 13 * under the terms of the GNU General Public License version 2 as published 14 * by the Free Software Foundation. 15 */ 16 17#include <linux/platform_device.h> 18 19static int __devinit ohci_ath79_start(struct usb_hcd *hcd) 20{ 21 struct ohci_hcd *ohci = hcd_to_ohci(hcd); 22 int ret; 23 24 ret = ohci_init(ohci); 25 if (ret < 0) 26 return ret; 27 28 ret = ohci_run(ohci); 29 if (ret < 0) 30 goto err; 31 32 return 0; 33 34err: 35 ohci_stop(hcd); 36 return ret; 37} 38 39static const struct hc_driver ohci_ath79_hc_driver = { 40 .description = hcd_name, 41 .product_desc = "Atheros built-in OHCI controller", 42 .hcd_priv_size = sizeof(struct ohci_hcd), 43 44 .irq = ohci_irq, 45 .flags = HCD_USB11 | HCD_MEMORY, 46 47 .start = ohci_ath79_start, 48 .stop = ohci_stop, 49 .shutdown = ohci_shutdown, 50 51 .urb_enqueue = ohci_urb_enqueue, 52 .urb_dequeue = ohci_urb_dequeue, 53 .endpoint_disable = ohci_endpoint_disable, 54 55 /* 56 * scheduling support 57 */ 58 .get_frame_number = ohci_get_frame, 59 60 /* 61 * root hub support 62 */ 63 .hub_status_data = ohci_hub_status_data, 64 .hub_control = ohci_hub_control, 65 .start_port_reset = ohci_start_port_reset, 66}; 67 68static int ohci_ath79_probe(struct platform_device *pdev) 69{ 70 struct usb_hcd *hcd; 71 struct resource *res; 72 int irq; 73 int ret; 74 75 if (usb_disabled()) 76 return -ENODEV; 77 78 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 79 if (!res) { 80 dev_dbg(&pdev->dev, "no IRQ specified\n"); 81 return -ENODEV; 82 } 83 irq = res->start; 84 85 hcd = usb_create_hcd(&ohci_ath79_hc_driver, &pdev->dev, 86 dev_name(&pdev->dev)); 87 if (!hcd) 88 return -ENOMEM; 89 90 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 91 if (!res) { 92 dev_dbg(&pdev->dev, "no base address specified\n"); 93 ret = -ENODEV; 94 goto err_put_hcd; 95 } 96 hcd->rsrc_start = res->start; 97 hcd->rsrc_len = res->end - res->start + 1; 98 99 if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { 100 dev_dbg(&pdev->dev, "controller already in use\n"); 101 ret = -EBUSY; 102 goto err_put_hcd; 103 } 104 105 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); 106 if (!hcd->regs) { 107 dev_dbg(&pdev->dev, "error mapping memory\n"); 108 ret = -EFAULT; 109 goto err_release_region; 110 } 111 112 ohci_hcd_init(hcd_to_ohci(hcd)); 113 114 ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); 115 if (ret) 116 goto err_stop_hcd; 117 118 return 0; 119 120err_stop_hcd: 121 iounmap(hcd->regs); 122err_release_region: 123 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 124err_put_hcd: 125 usb_put_hcd(hcd); 126 return ret; 127} 128 129static int ohci_ath79_remove(struct platform_device *pdev) 130{ 131 struct usb_hcd *hcd = platform_get_drvdata(pdev); 132 133 usb_remove_hcd(hcd); 134 iounmap(hcd->regs); 135 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 136 usb_put_hcd(hcd); 137 138 return 0; 139} 140 141static struct platform_driver ohci_hcd_ath79_driver = { 142 .probe = ohci_ath79_probe, 143 .remove = ohci_ath79_remove, 144 .shutdown = usb_hcd_platform_shutdown, 145 .driver = { 146 .name = "ath79-ohci", 147 .owner = THIS_MODULE, 148 }, 149}; 150 151MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ath79-ohci");