• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * OHCI HCD (Host Controller Driver) for USB.
3  *
4  * Copyright (C) 2008 Renesas Solutions Corp.
5  *
6  * Author : Yoshihiro Shimoda <shimoda.yoshihiro@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 
ohci_sh_start(struct usb_hcd * hcd)25 static 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 
36 static 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 
80 #define resource_len(r) (((r)->end - (r)->start) + 1)
ohci_hcd_sh_probe(struct platform_device * pdev)81 static int ohci_hcd_sh_probe(struct platform_device *pdev)
82 {
83 	struct resource *res = NULL;
84 	struct usb_hcd *hcd = NULL;
85 	int irq = -1;
86 	int ret;
87 
88 	if (usb_disabled())
89 		return -ENODEV;
90 
91 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
92 	if (!res) {
93 		err("platform_get_resource error.");
94 		return -ENODEV;
95 	}
96 
97 	irq = platform_get_irq(pdev, 0);
98 	if (irq < 0) {
99 		err("platform_get_irq error.");
100 		return -ENODEV;
101 	}
102 
103 	/* initialize hcd */
104 	hcd = usb_create_hcd(&ohci_sh_hc_driver, &pdev->dev, (char *)hcd_name);
105 	if (!hcd) {
106 		err("Failed to create hcd");
107 		return -ENOMEM;
108 	}
109 
110 	hcd->regs = (void __iomem *)res->start;
111 	hcd->rsrc_start = res->start;
112 	hcd->rsrc_len = resource_len(res);
113 	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
114 	if (ret != 0) {
115 		err("Failed to add hcd");
116 		usb_put_hcd(hcd);
117 		return ret;
118 	}
119 
120 	return ret;
121 }
122 
ohci_hcd_sh_remove(struct platform_device * pdev)123 static int ohci_hcd_sh_remove(struct platform_device *pdev)
124 {
125 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
126 
127 	usb_remove_hcd(hcd);
128 	usb_put_hcd(hcd);
129 
130 	return 0;
131 }
132 
133 static struct platform_driver ohci_hcd_sh_driver = {
134 	.probe		= ohci_hcd_sh_probe,
135 	.remove		= ohci_hcd_sh_remove,
136 	.shutdown	= usb_hcd_platform_shutdown,
137 	.driver		= {
138 		.name	= "sh_ohci",
139 		.owner	= THIS_MODULE,
140 	},
141 };
142 
143 MODULE_ALIAS("platform:sh_ohci");
144