aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-msm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-msm.c')
-rw-r--r--drivers/usb/host/ehci-msm.c290
1 files changed, 290 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
new file mode 100644
index 000000000000..9ed855986599
--- /dev/null
+++ b/drivers/usb/host/ehci-msm.c
@@ -0,0 +1,290 @@
1/* ehci-msm.c - HSUSB Host Controller Driver Implementation
2 *
3 * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
4 *
5 * Partly derived from ehci-fsl.c and ehci-hcd.c
6 * Copyright (c) 2000-2004 by David Brownell
7 * Copyright (c) 2005 MontaVista Software
8 *
9 * All source code in this file is licensed under the following license except
10 * where indicated.
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 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * See the GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, you can find it at http://www.fsf.org
23 */
24
25#include <linux/platform_device.h>
26#include <linux/clk.h>
27#include <linux/err.h>
28
29#include <linux/usb/otg.h>
30#include <linux/usb/msm_hsusb_hw.h>
31
32#define MSM_USB_BASE (hcd->regs)
33
34static struct otg_transceiver *otg;
35
36/*
37 * ehci_run defined in drivers/usb/host/ehci-hcd.c reset the controller and
38 * the configuration settings in ehci_msm_reset vanish after controller is
39 * reset. Resetting the controler in ehci_run seems to be un-necessary
40 * provided HCD reset the controller before calling ehci_run. Most of the HCD
41 * do but some are not. So this function is same as ehci_run but we don't
42 * reset the controller here.
43 */
44static int ehci_msm_run(struct usb_hcd *hcd)
45{
46 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
47 u32 temp;
48 u32 hcc_params;
49
50 hcd->uses_new_polling = 1;
51
52 ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);
53 ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next);
54
55 /*
56 * hcc_params controls whether ehci->regs->segment must (!!!)
57 * be used; it constrains QH/ITD/SITD and QTD locations.
58 * pci_pool consistent memory always uses segment zero.
59 * streaming mappings for I/O buffers, like pci_map_single(),
60 * can return segments above 4GB, if the device allows.
61 *
62 * NOTE: the dma mask is visible through dma_supported(), so
63 * drivers can pass this info along ... like NETIF_F_HIGHDMA,
64 * Scsi_Host.highmem_io, and so forth. It's readonly to all
65 * host side drivers though.
66 */
67 hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
68 if (HCC_64BIT_ADDR(hcc_params))
69 ehci_writel(ehci, 0, &ehci->regs->segment);
70
71 /*
72 * Philips, Intel, and maybe others need CMD_RUN before the
73 * root hub will detect new devices (why?); NEC doesn't
74 */
75 ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
76 ehci->command |= CMD_RUN;
77 ehci_writel(ehci, ehci->command, &ehci->regs->command);
78 dbg_cmd(ehci, "init", ehci->command);
79
80 /*
81 * Start, enabling full USB 2.0 functionality ... usb 1.1 devices
82 * are explicitly handed to companion controller(s), so no TT is
83 * involved with the root hub. (Except where one is integrated,
84 * and there's no companion controller unless maybe for USB OTG.)
85 *
86 * Turning on the CF flag will transfer ownership of all ports
87 * from the companions to the EHCI controller. If any of the
88 * companions are in the middle of a port reset at the time, it
89 * could cause trouble. Write-locking ehci_cf_port_reset_rwsem
90 * guarantees that no resets are in progress. After we set CF,
91 * a short delay lets the hardware catch up; new resets shouldn't
92 * be started before the port switching actions could complete.
93 */
94 down_write(&ehci_cf_port_reset_rwsem);
95 hcd->state = HC_STATE_RUNNING;
96 ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
97 ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
98 usleep_range(5000, 5500);
99 up_write(&ehci_cf_port_reset_rwsem);
100 ehci->last_periodic_enable = ktime_get_real();
101
102 temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
103 ehci_info(ehci,
104 "USB %x.%x started, EHCI %x.%02x%s\n",
105 ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
106 temp >> 8, temp & 0xff,
107 ignore_oc ? ", overcurrent ignored" : "");
108
109 ehci_writel(ehci, INTR_MASK,
110 &ehci->regs->intr_enable); /* Turn On Interrupts */
111
112 /* GRR this is run-once init(), being done every time the HC starts.
113 * So long as they're part of class devices, we can't do it init()
114 * since the class device isn't created that early.
115 */
116 create_debug_files(ehci);
117 create_companion_file(ehci);
118
119 return 0;
120}
121
122static int ehci_msm_reset(struct usb_hcd *hcd)
123{
124 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
125 int retval;
126
127 ehci->caps = USB_CAPLENGTH;
128 ehci->regs = USB_CAPLENGTH +
129 HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
130
131 /* cache the data to minimize the chip reads*/
132 ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
133
134 hcd->has_tt = 1;
135 ehci->sbrn = HCD_USB2;
136
137 /* data structure init */
138 retval = ehci_init(hcd);
139 if (retval)
140 return retval;
141
142 retval = ehci_reset(ehci);
143 if (retval)
144 return retval;
145
146 /* bursts of unspecified length. */
147 writel(0, USB_AHBBURST);
148 /* Use the AHB transactor */
149 writel(0, USB_AHBMODE);
150 /* Disable streaming mode and select host mode */
151 writel(0x13, USB_USBMODE);
152
153 ehci_port_power(ehci, 1);
154 return 0;
155}
156
157static struct hc_driver msm_hc_driver = {
158 .description = hcd_name,
159 .product_desc = "Qualcomm On-Chip EHCI Host Controller",
160 .hcd_priv_size = sizeof(struct ehci_hcd),
161
162 /*
163 * generic hardware linkage
164 */
165 .irq = ehci_irq,
166 .flags = HCD_USB2 | HCD_MEMORY,
167
168 .reset = ehci_msm_reset,
169 .start = ehci_msm_run,
170
171 .stop = ehci_stop,
172 .shutdown = ehci_shutdown,
173
174 /*
175 * managing i/o requests and associated device resources
176 */
177 .urb_enqueue = ehci_urb_enqueue,
178 .urb_dequeue = ehci_urb_dequeue,
179 .endpoint_disable = ehci_endpoint_disable,
180 .endpoint_reset = ehci_endpoint_reset,
181 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
182
183 /*
184 * scheduling support
185 */
186 .get_frame_number = ehci_get_frame,
187
188 /*
189 * root hub support
190 */
191 .hub_status_data = ehci_hub_status_data,
192 .hub_control = ehci_hub_control,
193 .relinquish_port = ehci_relinquish_port,
194 .port_handed_over = ehci_port_handed_over,
195
196 /*
197 * PM support
198 */
199 .bus_suspend = ehci_bus_suspend,
200 .bus_resume = ehci_bus_resume,
201};
202
203static int ehci_msm_probe(struct platform_device *pdev)
204{
205 struct usb_hcd *hcd;
206 struct resource *res;
207 int ret;
208
209 dev_dbg(&pdev->dev, "ehci_msm proble\n");
210
211 hcd = usb_create_hcd(&msm_hc_driver, &pdev->dev, dev_name(&pdev->dev));
212 if (!hcd) {
213 dev_err(&pdev->dev, "Unable to create HCD\n");
214 return -ENOMEM;
215 }
216
217 hcd->irq = platform_get_irq(pdev, 0);
218 if (hcd->irq < 0) {
219 dev_err(&pdev->dev, "Unable to get IRQ resource\n");
220 ret = hcd->irq;
221 goto put_hcd;
222 }
223
224 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
225 if (!res) {
226 dev_err(&pdev->dev, "Unable to get memory resource\n");
227 ret = -ENODEV;
228 goto put_hcd;
229 }
230
231 hcd->rsrc_start = res->start;
232 hcd->rsrc_len = resource_size(res);
233 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
234 if (!hcd->regs) {
235 dev_err(&pdev->dev, "ioremap failed\n");
236 ret = -ENOMEM;
237 goto put_hcd;
238 }
239
240 /*
241 * OTG driver takes care of PHY initialization, clock management,
242 * powering up VBUS and mapping of registers address space.
243 */
244 otg = otg_get_transceiver();
245 if (!otg) {
246 dev_err(&pdev->dev, "unable to find transceiver\n");
247 ret = -ENODEV;
248 goto unmap;
249 }
250
251 ret = otg_set_host(otg, &hcd->self);
252 if (ret < 0) {
253 dev_err(&pdev->dev, "unable to register with transceiver\n");
254 goto put_transceiver;
255 }
256
257 device_init_wakeup(&pdev->dev, 1);
258 return 0;
259
260put_transceiver:
261 otg_put_transceiver(otg);
262unmap:
263 iounmap(hcd->regs);
264put_hcd:
265 usb_put_hcd(hcd);
266
267 return ret;
268}
269
270static int __devexit ehci_msm_remove(struct platform_device *pdev)
271{
272 struct usb_hcd *hcd = platform_get_drvdata(pdev);
273
274 device_init_wakeup(&pdev->dev, 0);
275
276 otg_set_host(otg, NULL);
277 otg_put_transceiver(otg);
278
279 usb_put_hcd(hcd);
280
281 return 0;
282}
283
284static struct platform_driver ehci_msm_driver = {
285 .probe = ehci_msm_probe,
286 .remove = __devexit_p(ehci_msm_remove),
287 .driver = {
288 .name = "msm_hsusb_host",
289 },
290};