ohci-sh.c revision b5dd18d8747010e3f3eb1cc76a49f94291938559
1/* 2 * OHCI HCD (Host Controller Driver) for USB. 3 * 4 * Copyright (C) 2008 Renesas Solutions Corp. 5 * 6 * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; version 2 of the License. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 * 21 */ 22 23#include <linux/platform_device.h> 24 25static int ohci_sh_start(struct usb_hcd *hcd) 26{ 27 struct ohci_hcd *ohci = hcd_to_ohci(hcd); 28 29 ohci_hcd_init(ohci); 30 ohci_init(ohci); 31 ohci_run(ohci); 32 hcd->state = HC_STATE_RUNNING; 33 return 0; 34} 35 36static const struct hc_driver ohci_sh_hc_driver = { 37 .description = hcd_name, 38 .product_desc = "SuperH OHCI", 39 .hcd_priv_size = sizeof(struct ohci_hcd), 40 41 /* 42 * generic hardware linkage 43 */ 44 .irq = ohci_irq, 45 .flags = HCD_USB11 | HCD_MEMORY, 46 47 /* 48 * basic lifecycle operations 49 */ 50 .start = ohci_sh_start, 51 .stop = ohci_stop, 52 .shutdown = ohci_shutdown, 53 54 /* 55 * managing i/o requests and associated device resources 56 */ 57 .urb_enqueue = ohci_urb_enqueue, 58 .urb_dequeue = ohci_urb_dequeue, 59 .endpoint_disable = ohci_endpoint_disable, 60 61 /* 62 * scheduling support 63 */ 64 .get_frame_number = ohci_get_frame, 65 66 /* 67 * root hub support 68 */ 69 .hub_status_data = ohci_hub_status_data, 70 .hub_control = ohci_hub_control, 71#ifdef CONFIG_PM 72 .bus_suspend = ohci_bus_suspend, 73 .bus_resume = ohci_bus_resume, 74#endif 75 .start_port_reset = ohci_start_port_reset, 76}; 77 78/*-------------------------------------------------------------------------*/ 79 80static int ohci_hcd_sh_probe(struct platform_device *pdev) 81{ 82 struct resource *res = NULL; 83 struct usb_hcd *hcd = NULL; 84 int irq = -1; 85 int ret; 86 87 if (usb_disabled()) 88 return -ENODEV; 89 90 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 91 if (!res) { 92 err("platform_get_resource error."); 93 return -ENODEV; 94 } 95 96 irq = platform_get_irq(pdev, 0); 97 if (irq < 0) { 98 err("platform_get_irq error."); 99 return -ENODEV; 100 } 101 102 /* initialize hcd */ 103 hcd = usb_create_hcd(&ohci_sh_hc_driver, &pdev->dev, (char *)hcd_name); 104 if (!hcd) { 105 err("Failed to create hcd"); 106 return -ENOMEM; 107 } 108 109 hcd->regs = (void __iomem *)res->start; 110 hcd->rsrc_start = res->start; 111 hcd->rsrc_len = resource_size(res); 112 ret = usb_add_hcd(hcd, irq, IRQF_SHARED); 113 if (ret != 0) { 114 err("Failed to add hcd"); 115 usb_put_hcd(hcd); 116 return ret; 117 } 118 119 return ret; 120} 121 122static int ohci_hcd_sh_remove(struct platform_device *pdev) 123{ 124 struct usb_hcd *hcd = platform_get_drvdata(pdev); 125 126 usb_remove_hcd(hcd); 127 usb_put_hcd(hcd); 128 129 return 0; 130} 131 132static struct platform_driver ohci_hcd_sh_driver = { 133 .probe = ohci_hcd_sh_probe, 134 .remove = ohci_hcd_sh_remove, 135 .shutdown = usb_hcd_platform_shutdown, 136 .driver = { 137 .name = "sh_ohci", 138 .owner = THIS_MODULE, 139 }, 140}; 141 142MODULE_ALIAS("platform:sh_ohci"); 143