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 return 0; 33} 34 35static const struct hc_driver ohci_sh_hc_driver = { 36 .description = hcd_name, 37 .product_desc = "SuperH OHCI", 38 .hcd_priv_size = sizeof(struct ohci_hcd), 39 40 /* 41 * generic hardware linkage 42 */ 43 .irq = ohci_irq, 44 .flags = HCD_USB11 | HCD_MEMORY, 45 46 /* 47 * basic lifecycle operations 48 */ 49 .start = ohci_sh_start, 50 .stop = ohci_stop, 51 .shutdown = ohci_shutdown, 52 53 /* 54 * managing i/o requests and associated device resources 55 */ 56 .urb_enqueue = ohci_urb_enqueue, 57 .urb_dequeue = ohci_urb_dequeue, 58 .endpoint_disable = ohci_endpoint_disable, 59 60 /* 61 * scheduling support 62 */ 63 .get_frame_number = ohci_get_frame, 64 65 /* 66 * root hub support 67 */ 68 .hub_status_data = ohci_hub_status_data, 69 .hub_control = ohci_hub_control, 70#ifdef CONFIG_PM 71 .bus_suspend = ohci_bus_suspend, 72 .bus_resume = ohci_bus_resume, 73#endif 74 .start_port_reset = ohci_start_port_reset, 75}; 76 77/*-------------------------------------------------------------------------*/ 78 79static int ohci_hcd_sh_probe(struct platform_device *pdev) 80{ 81 struct resource *res = NULL; 82 struct usb_hcd *hcd = NULL; 83 int irq = -1; 84 int ret; 85 86 if (usb_disabled()) 87 return -ENODEV; 88 89 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 90 if (!res) { 91 err("platform_get_resource error."); 92 return -ENODEV; 93 } 94 95 irq = platform_get_irq(pdev, 0); 96 if (irq < 0) { 97 err("platform_get_irq error."); 98 return -ENODEV; 99 } 100 101 /* initialize hcd */ 102 hcd = usb_create_hcd(&ohci_sh_hc_driver, &pdev->dev, (char *)hcd_name); 103 if (!hcd) { 104 err("Failed to create hcd"); 105 return -ENOMEM; 106 } 107 108 hcd->regs = (void __iomem *)res->start; 109 hcd->rsrc_start = res->start; 110 hcd->rsrc_len = resource_size(res); 111 ret = usb_add_hcd(hcd, irq, IRQF_SHARED); 112 if (ret != 0) { 113 err("Failed to add hcd"); 114 usb_put_hcd(hcd); 115 return ret; 116 } 117 118 return ret; 119} 120 121static int ohci_hcd_sh_remove(struct platform_device *pdev) 122{ 123 struct usb_hcd *hcd = platform_get_drvdata(pdev); 124 125 usb_remove_hcd(hcd); 126 usb_put_hcd(hcd); 127 128 return 0; 129} 130 131static struct platform_driver ohci_hcd_sh_driver = { 132 .probe = ohci_hcd_sh_probe, 133 .remove = ohci_hcd_sh_remove, 134 .shutdown = usb_hcd_platform_shutdown, 135 .driver = { 136 .name = "sh_ohci", 137 .owner = THIS_MODULE, 138 }, 139}; 140 141MODULE_ALIAS("platform:sh_ohci"); 142