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.7-rc3 147 lines 3.1 kB view raw
1/* 2 * Bus Glue for Loongson LS1X built-in EHCI controller. 3 * 4 * Copyright (c) 2012 Zhang, Keguang <keguang.zhang@gmail.com> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 as published 8 * by the Free Software Foundation. 9 */ 10 11 12#include <linux/platform_device.h> 13 14static int ehci_ls1x_reset(struct usb_hcd *hcd) 15{ 16 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 17 int ret; 18 19 ehci->caps = hcd->regs; 20 21 ret = ehci_setup(hcd); 22 if (ret) 23 return ret; 24 25 ehci_port_power(ehci, 0); 26 27 return 0; 28} 29 30static const struct hc_driver ehci_ls1x_hc_driver = { 31 .description = hcd_name, 32 .product_desc = "LOONGSON1 EHCI", 33 .hcd_priv_size = sizeof(struct ehci_hcd), 34 35 /* 36 * generic hardware linkage 37 */ 38 .irq = ehci_irq, 39 .flags = HCD_MEMORY | HCD_USB2, 40 41 /* 42 * basic lifecycle operations 43 */ 44 .reset = ehci_ls1x_reset, 45 .start = ehci_run, 46 .stop = ehci_stop, 47 .shutdown = ehci_shutdown, 48 49 /* 50 * managing i/o requests and associated device resources 51 */ 52 .urb_enqueue = ehci_urb_enqueue, 53 .urb_dequeue = ehci_urb_dequeue, 54 .endpoint_disable = ehci_endpoint_disable, 55 .endpoint_reset = ehci_endpoint_reset, 56 57 /* 58 * scheduling support 59 */ 60 .get_frame_number = ehci_get_frame, 61 62 /* 63 * root hub support 64 */ 65 .hub_status_data = ehci_hub_status_data, 66 .hub_control = ehci_hub_control, 67 .relinquish_port = ehci_relinquish_port, 68 .port_handed_over = ehci_port_handed_over, 69 70 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, 71}; 72 73static int ehci_hcd_ls1x_probe(struct platform_device *pdev) 74{ 75 struct usb_hcd *hcd; 76 struct resource *res; 77 int irq; 78 int ret; 79 80 pr_debug("initializing loongson1 ehci USB Controller\n"); 81 82 if (usb_disabled()) 83 return -ENODEV; 84 85 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 86 if (!res) { 87 dev_err(&pdev->dev, 88 "Found HC with no IRQ. Check %s setup!\n", 89 dev_name(&pdev->dev)); 90 return -ENODEV; 91 } 92 irq = res->start; 93 94 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 95 if (!res) { 96 dev_err(&pdev->dev, 97 "Found HC with no register addr. Check %s setup!\n", 98 dev_name(&pdev->dev)); 99 return -ENODEV; 100 } 101 102 hcd = usb_create_hcd(&ehci_ls1x_hc_driver, &pdev->dev, 103 dev_name(&pdev->dev)); 104 if (!hcd) 105 return -ENOMEM; 106 hcd->rsrc_start = res->start; 107 hcd->rsrc_len = resource_size(res); 108 109 hcd->regs = devm_request_and_ioremap(&pdev->dev, res); 110 if (hcd->regs == NULL) { 111 dev_dbg(&pdev->dev, "error mapping memory\n"); 112 ret = -EFAULT; 113 goto err_put_hcd; 114 } 115 116 ret = usb_add_hcd(hcd, irq, IRQF_SHARED); 117 if (ret) 118 goto err_put_hcd; 119 120 return ret; 121 122err_put_hcd: 123 usb_put_hcd(hcd); 124 return ret; 125} 126 127static int ehci_hcd_ls1x_remove(struct platform_device *pdev) 128{ 129 struct usb_hcd *hcd = platform_get_drvdata(pdev); 130 131 usb_remove_hcd(hcd); 132 usb_put_hcd(hcd); 133 134 return 0; 135} 136 137static struct platform_driver ehci_ls1x_driver = { 138 .probe = ehci_hcd_ls1x_probe, 139 .remove = ehci_hcd_ls1x_remove, 140 .shutdown = usb_hcd_platform_shutdown, 141 .driver = { 142 .name = "ls1x-ehci", 143 .owner = THIS_MODULE, 144 }, 145}; 146 147MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ls1x-ehci");