blob: 7a153485d612c8f43d553601b3ff2c0e8c213d0d [file] [log] [blame]
Vijayavardhan Vennapusa39025fe2011-10-15 05:55:10 +05301/* ehci-msm-hsic.c - HSUSB Host Controller Driver Implementation
2 *
3 * Copyright (c) 2011, 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#include <linux/wakelock.h>
29#include <linux/pm_runtime.h>
30#include <linux/regulator/consumer.h>
31
32#include <linux/usb/msm_hsusb_hw.h>
33
34#include <mach/clk.h>
35#include <mach/msm_iomap.h>
36
37#define MSM_USB_BASE (hcd->regs)
38
39struct msm_hsic_hcd {
40 struct ehci_hcd ehci;
41 struct device *dev;
42 struct clk *ahb_clk;
43 struct clk *sys_clk;
44 struct clk *fs_xcvr_clk;
45 struct clk *hsic_clk;
46 struct clk *cal_clk;
47 struct regulator *hsic_vddcx;
48 bool async_int;
49 atomic_t in_lpm;
50 struct wake_lock wlock;
51};
52
53static inline struct msm_hsic_hcd *hcd_to_hsic(struct usb_hcd *hcd)
54{
55 return (struct msm_hsic_hcd *) (hcd->hcd_priv);
56}
57
58static inline struct usb_hcd *hsic_to_hcd(struct msm_hsic_hcd *mehci)
59{
60 return container_of((void *) mehci, struct usb_hcd, hcd_priv);
61}
62
63#define ULPI_IO_TIMEOUT_USEC (10 * 1000)
64
65#define USB_PHY_VDD_DIG_VOL_MIN 1000000 /* uV */
66#define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */
67#define USB_PHY_VDD_DIG_LOAD 49360 /* uA */
68
69static int msm_hsic_init_vddcx(struct msm_hsic_hcd *mehci, int init)
70{
71 int ret = 0;
72
73 if (!init)
74 goto disable_reg;
75
76 mehci->hsic_vddcx = regulator_get(mehci->dev, "HSIC_VDDCX");
77 if (IS_ERR(mehci->hsic_vddcx)) {
78 dev_err(mehci->dev, "unable to get hsic vddcx\n");
79 return PTR_ERR(mehci->hsic_vddcx);
80 }
81
82 ret = regulator_set_voltage(mehci->hsic_vddcx,
83 USB_PHY_VDD_DIG_VOL_MIN,
84 USB_PHY_VDD_DIG_VOL_MAX);
85 if (ret) {
86 dev_err(mehci->dev, "unable to set the voltage"
87 "for hsic vddcx\n");
88 goto reg_set_voltage_err;
89 }
90
91 ret = regulator_set_optimum_mode(mehci->hsic_vddcx,
92 USB_PHY_VDD_DIG_LOAD);
93 if (ret < 0) {
94 pr_err("%s: Unable to set optimum mode of the regulator:"
95 "VDDCX\n", __func__);
96 goto reg_optimum_mode_err;
97 }
98
99 ret = regulator_enable(mehci->hsic_vddcx);
100 if (ret) {
101 dev_err(mehci->dev, "unable to enable hsic vddcx\n");
102 goto reg_enable_err;
103 }
104
105 return 0;
106
107disable_reg:
108 regulator_disable(mehci->hsic_vddcx);
109reg_enable_err:
110 regulator_set_optimum_mode(mehci->hsic_vddcx, 0);
111reg_optimum_mode_err:
112 regulator_set_voltage(mehci->hsic_vddcx, 0,
113 USB_PHY_VDD_DIG_VOL_MIN);
114reg_set_voltage_err:
115 regulator_put(mehci->hsic_vddcx);
116
117 return ret;
118
119}
120
121static int ulpi_write(struct msm_hsic_hcd *mehci, u32 val, u32 reg)
122{
123 struct usb_hcd *hcd = hsic_to_hcd(mehci);
124 int cnt = 0;
125
126 /* initiate write operation */
127 writel_relaxed(ULPI_RUN | ULPI_WRITE |
128 ULPI_ADDR(reg) | ULPI_DATA(val),
129 USB_ULPI_VIEWPORT);
130
131 /* wait for completion */
132 while (cnt < ULPI_IO_TIMEOUT_USEC) {
133 if (!(readl_relaxed(USB_ULPI_VIEWPORT) & ULPI_RUN))
134 break;
135 udelay(1);
136 cnt++;
137 }
138
139 if (cnt >= ULPI_IO_TIMEOUT_USEC) {
140 dev_err(mehci->dev, "ulpi_write: timeout\n");
141 return -ETIMEDOUT;
142 }
143
144 return 0;
145}
146
147static int msm_hsic_phy_clk_reset(struct msm_hsic_hcd *mehci)
148{
149 int ret;
150
151 clk_enable(mehci->fs_xcvr_clk);
152
153 ret = clk_reset(mehci->sys_clk, CLK_RESET_ASSERT);
154 if (ret) {
155 clk_disable(mehci->fs_xcvr_clk);
156 dev_err(mehci->dev, "usb phy clk assert failed\n");
157 return ret;
158 }
159 usleep_range(10000, 12000);
160 clk_disable(mehci->fs_xcvr_clk);
161
162 ret = clk_reset(mehci->sys_clk, CLK_RESET_DEASSERT);
163 if (ret)
164 dev_err(mehci->dev, "usb phy clk deassert failed\n");
165
166 return ret;
167}
168
169static int msm_hsic_phy_reset(struct msm_hsic_hcd *mehci)
170{
171 struct usb_hcd *hcd = hsic_to_hcd(mehci);
172 u32 val;
173 int ret;
174
175 ret = msm_hsic_phy_clk_reset(mehci);
176 if (ret)
177 return ret;
178
179 val = readl_relaxed(USB_PORTSC) & ~PORTSC_PTS_MASK;
180 writel_relaxed(val | PORTSC_PTS_ULPI, USB_PORTSC);
181
182 /* Ensure that RESET operation is completed before turning off clock */
183 mb();
184 dev_dbg(mehci->dev, "phy_reset: success\n");
185
186 return 0;
187}
188
189#define LINK_RESET_TIMEOUT_USEC (250 * 1000)
190static int msm_hsic_reset(struct msm_hsic_hcd *mehci)
191{
192 struct usb_hcd *hcd = hsic_to_hcd(mehci);
193 int cnt = 0;
194 int ret;
195
196 ret = msm_hsic_phy_reset(mehci);
197 if (ret) {
198 dev_err(mehci->dev, "phy_reset failed\n");
199 return ret;
200 }
201
202 writel_relaxed(USBCMD_RESET, USB_USBCMD);
203 while (cnt < LINK_RESET_TIMEOUT_USEC) {
204 if (!(readl_relaxed(USB_USBCMD) & USBCMD_RESET))
205 break;
206 udelay(1);
207 cnt++;
208 }
209 if (cnt >= LINK_RESET_TIMEOUT_USEC)
210 return -ETIMEDOUT;
211
212 /* select ULPI phy */
213 writel_relaxed(0x80000000, USB_PORTSC);
214
215 /* TODO: Need to confirm if HSIC PHY also requires delay after RESET */
216 msleep(100);
217
218 /* HSIC PHY Initialization */
219 /*set periodic calibration interval to ~2.048sec in HSIC_IO_CAL_REG */
220 ulpi_write(mehci, 0xFF, 0x33);
221 /*enable periodic IO calibration,HSIC host mode in HSIC_CFG register*/
222 ulpi_write(mehci, 0xA9, 0x30);
223
224 return 0;
225}
226
227#define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000)
228#define PHY_RESUME_TIMEOUT_USEC (100 * 1000)
229
230#ifdef CONFIG_PM_SLEEP
231static int msm_hsic_suspend(struct msm_hsic_hcd *mehci)
232{
233 struct usb_hcd *hcd = hsic_to_hcd(mehci);
234 int cnt = 0;
235 u32 val;
236
237 if (atomic_read(&mehci->in_lpm)) {
238 dev_dbg(mehci->dev, "%s called in lpm\n", __func__);
239 return 0;
240 }
241
242 disable_irq(hcd->irq);
243 /*
244 * PHY may take some time or even fail to enter into low power
245 * mode (LPM). Hence poll for 500 msec and reset the PHY and link
246 * in failure case.
247 */
248 val = readl_relaxed(USB_PORTSC) | PORTSC_PHCD;
249 writel_relaxed(val, USB_PORTSC);
250 while (cnt < PHY_SUSPEND_TIMEOUT_USEC) {
251 if (readl_relaxed(USB_PORTSC) & PORTSC_PHCD)
252 break;
253 udelay(1);
254 cnt++;
255 }
256
257 if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) {
258 dev_err(mehci->dev, "Unable to suspend PHY\n");
259 msm_hsic_reset(mehci);
260 enable_irq(hcd->irq);
261 return -ETIMEDOUT;
262 }
263
264 /*
265 * PHY has capability to generate interrupt asynchronously in low
266 * power mode (LPM). This interrupt is level triggered. So USB IRQ
267 * line must be disabled till async interrupt enable bit is cleared
268 * in USBCMD register. Assert STP (ULPI interface STOP signal) to
269 * block data communication from PHY.
270 */
271 writel_relaxed(readl_relaxed(USB_USBCMD) | ASYNC_INTR_CTRL |
272 ULPI_STP_CTRL, USB_USBCMD);
273
274 /*
275 * Ensure that hardware is put in low power mode before
276 * clocks are turned OFF and VDD is allowed to minimize.
277 */
278 mb();
279
280 clk_disable(mehci->sys_clk);
281 clk_disable(mehci->hsic_clk);
282 clk_disable(mehci->cal_clk);
283 clk_disable(mehci->ahb_clk);
284
285 atomic_set(&mehci->in_lpm, 1);
286 enable_irq(hcd->irq);
287 wake_unlock(&mehci->wlock);
288
289 dev_info(mehci->dev, "HSIC-USB in low power mode\n");
290
291 return 0;
292}
293
294static int msm_hsic_resume(struct msm_hsic_hcd *mehci)
295{
296 struct usb_hcd *hcd = hsic_to_hcd(mehci);
297 int cnt = 0;
298 unsigned temp;
299
300 if (!atomic_read(&mehci->in_lpm)) {
301 dev_dbg(mehci->dev, "%s called in !in_lpm\n", __func__);
302 return 0;
303 }
304
305 wake_lock(&mehci->wlock);
306
307 clk_enable(mehci->sys_clk);
308 clk_enable(mehci->hsic_clk);
309 clk_enable(mehci->cal_clk);
310 clk_enable(mehci->ahb_clk);
311
312 temp = readl_relaxed(USB_USBCMD);
313 temp &= ~ASYNC_INTR_CTRL;
314 temp &= ~ULPI_STP_CTRL;
315 writel_relaxed(temp, USB_USBCMD);
316
317 if (!(readl_relaxed(USB_PORTSC) & PORTSC_PHCD))
318 goto skip_phy_resume;
319
320 temp = readl_relaxed(USB_PORTSC) & ~PORTSC_PHCD;
321 writel_relaxed(temp, USB_PORTSC);
322 while (cnt < PHY_RESUME_TIMEOUT_USEC) {
323 if (!(readl_relaxed(USB_PORTSC) & PORTSC_PHCD) &&
324 (readl_relaxed(USB_ULPI_VIEWPORT) & ULPI_SYNC_STATE))
325 break;
326 udelay(1);
327 cnt++;
328 }
329
330 if (cnt >= PHY_RESUME_TIMEOUT_USEC) {
331 /*
332 * This is a fatal error. Reset the link and
333 * PHY to make hsic working.
334 */
335 dev_err(mehci->dev, "Unable to resume USB. Reset the hsic\n");
336 msm_hsic_reset(mehci);
337 }
338
339skip_phy_resume:
340
341 atomic_set(&mehci->in_lpm, 0);
342
343 if (mehci->async_int) {
344 mehci->async_int = false;
345 pm_runtime_put_noidle(mehci->dev);
346 enable_irq(hcd->irq);
347 }
348
349 dev_info(mehci->dev, "HSIC-USB exited from low power mode\n");
350
351 return 0;
352}
353#endif
354
355static irqreturn_t msm_hsic_irq(struct usb_hcd *hcd)
356{
357 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
358
359 if (atomic_read(&mehci->in_lpm)) {
360 disable_irq_nosync(hcd->irq);
361 mehci->async_int = true;
362 pm_runtime_get(mehci->dev);
363 return IRQ_HANDLED;
364 }
365
366 return ehci_irq(hcd);
367}
368
369static int ehci_hsic_reset(struct usb_hcd *hcd)
370{
371 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
372 int retval;
373
374 ehci->caps = USB_CAPLENGTH;
375 ehci->regs = USB_CAPLENGTH +
376 HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
377 dbg_hcs_params(ehci, "reset");
378 dbg_hcc_params(ehci, "reset");
379
380 /* cache the data to minimize the chip reads*/
381 ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
382
383 hcd->has_tt = 1;
384 ehci->sbrn = HCD_USB2;
385
386 retval = ehci_halt(ehci);
387 if (retval)
388 return retval;
389
390 /* data structure init */
391 retval = ehci_init(hcd);
392 if (retval)
393 return retval;
394
395 retval = ehci_reset(ehci);
396 if (retval)
397 return retval;
398
399 /* bursts of unspecified length. */
400 writel_relaxed(0, USB_AHBBURST);
401 /* Use the AHB transactor */
402 writel_relaxed(0, USB_AHBMODE);
403 /* Disable streaming mode and select host mode */
404 writel_relaxed(0x13, USB_USBMODE);
405
406 ehci_port_power(ehci, 1);
407 return 0;
408}
409
410static struct hc_driver msm_hsic_driver = {
411 .description = hcd_name,
412 .product_desc = "Qualcomm EHCI Host Controller using HSIC",
413 .hcd_priv_size = sizeof(struct msm_hsic_hcd),
414
415 /*
416 * generic hardware linkage
417 */
418 .irq = msm_hsic_irq,
419 .flags = HCD_USB2 | HCD_MEMORY,
420
421 .reset = ehci_hsic_reset,
422 .start = ehci_run,
423
424 .stop = ehci_stop,
425 .shutdown = ehci_shutdown,
426
427 /*
428 * managing i/o requests and associated device resources
429 */
430 .urb_enqueue = ehci_urb_enqueue,
431 .urb_dequeue = ehci_urb_dequeue,
432 .endpoint_disable = ehci_endpoint_disable,
433 .endpoint_reset = ehci_endpoint_reset,
434 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
435
436 /*
437 * scheduling support
438 */
439 .get_frame_number = ehci_get_frame,
440
441 /*
442 * root hub support
443 */
444 .hub_status_data = ehci_hub_status_data,
445 .hub_control = ehci_hub_control,
446 .relinquish_port = ehci_relinquish_port,
447 .port_handed_over = ehci_port_handed_over,
448
449 /*
450 * PM support
451 */
452 .bus_suspend = ehci_bus_suspend,
453 .bus_resume = ehci_bus_resume,
454};
455
456static int msm_hsic_init_clocks(struct msm_hsic_hcd *mehci, u32 init)
457{
458 int ret = 0;
459
460 if (!init)
461 goto put_clocks;
462
463 /*sys_clk is required for LINK protocol engine,it should be at 60MHz */
464 mehci->sys_clk = clk_get(mehci->dev, "usb_hsic_system_clk");
465 if (IS_ERR(mehci->sys_clk)) {
466 dev_err(mehci->dev, "failed to get hsic_sys_clk\n");
467 ret = PTR_ERR(mehci->sys_clk);
468 return ret;
469 }
470 clk_set_rate(mehci->sys_clk, 60000000);
471
472 /* 60MHz fs_xcvr_clk is for LINK to be used during PHY RESET */
473 mehci->fs_xcvr_clk = clk_get(mehci->dev, "usb_hsic_xcvr_fs_clk");
474 if (IS_ERR(mehci->fs_xcvr_clk)) {
475 dev_err(mehci->dev, "failed to get fs_xcvr_clk\n");
476 ret = PTR_ERR(mehci->fs_xcvr_clk);
477 goto put_sys_clk;
478 }
479 clk_set_rate(mehci->fs_xcvr_clk, 60000000);
480
481 /* 480MHz hsic_clk is required for HSIC PHY operation */
482 mehci->hsic_clk = clk_get(mehci->dev, "usb_hsic_hsic_clk");
483 if (IS_ERR(mehci->hsic_clk)) {
484 dev_err(mehci->dev, "failed to get hsic_clk\n");
485 ret = PTR_ERR(mehci->hsic_clk);
486 goto put_fs_xcvr_clk;
487 }
488 clk_set_rate(mehci->hsic_clk, 480000000);
489
490 /* 10MHz cal_clk is required for calibration of I/O pads */
491 mehci->cal_clk = clk_get(mehci->dev, "usb_hsic_hsio_cal_clk");
492 if (IS_ERR(mehci->cal_clk)) {
493 dev_err(mehci->dev, "failed to get hsic_cal_clk\n");
494 ret = PTR_ERR(mehci->cal_clk);
495 goto put_hsic_clk;
496 }
497 clk_set_rate(mehci->cal_clk, 10000000);
498
499 /* ahb_clk is required for data transfers */
500 mehci->ahb_clk = clk_get(mehci->dev, "usb_hsic_p_clk");
501 if (IS_ERR(mehci->ahb_clk)) {
502 dev_err(mehci->dev, "failed to get hsic_ahb_clk\n");
503 ret = PTR_ERR(mehci->ahb_clk);
504 goto put_cal_clk;
505 }
506
507 clk_enable(mehci->sys_clk);
508 clk_enable(mehci->hsic_clk);
509 clk_enable(mehci->cal_clk);
510 clk_enable(mehci->ahb_clk);
511
512 return 0;
513
514put_clocks:
515 clk_disable(mehci->sys_clk);
516 clk_disable(mehci->hsic_clk);
517 clk_disable(mehci->cal_clk);
518 clk_disable(mehci->ahb_clk);
519 clk_put(mehci->ahb_clk);
520put_cal_clk:
521 clk_put(mehci->cal_clk);
522put_hsic_clk:
523 clk_put(mehci->hsic_clk);
524put_fs_xcvr_clk:
525 clk_put(mehci->fs_xcvr_clk);
526put_sys_clk:
527 clk_put(mehci->sys_clk);
528
529 return ret;
530}
531static int __devinit ehci_hsic_msm_probe(struct platform_device *pdev)
532{
533 struct usb_hcd *hcd;
534 struct resource *res;
535 struct msm_hsic_hcd *mehci;
536 int ret;
537
538 dev_dbg(&pdev->dev, "ehci_msm-hsic probe\n");
539
540 hcd = usb_create_hcd(&msm_hsic_driver, &pdev->dev,
541 dev_name(&pdev->dev));
542 if (!hcd) {
543 dev_err(&pdev->dev, "Unable to create HCD\n");
544 return -ENOMEM;
545 }
546
547 hcd->irq = platform_get_irq(pdev, 0);
548 if (hcd->irq < 0) {
549 dev_err(&pdev->dev, "Unable to get IRQ resource\n");
550 ret = hcd->irq;
551 goto put_hcd;
552 }
553
554 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
555 if (!res) {
556 dev_err(&pdev->dev, "Unable to get memory resource\n");
557 ret = -ENODEV;
558 goto put_hcd;
559 }
560
561 hcd->rsrc_start = res->start;
562 hcd->rsrc_len = resource_size(res);
563 hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
564 if (!hcd->regs) {
565 dev_err(&pdev->dev, "ioremap failed\n");
566 ret = -ENOMEM;
567 goto put_hcd;
568 }
569
570 mehci = hcd_to_hsic(hcd);
571 mehci->dev = &pdev->dev;
572
573 ret = msm_hsic_init_clocks(mehci, 1);
574 if (ret) {
575 dev_err(&pdev->dev, "unable to initialize clocks\n");
576 ret = -ENODEV;
577 goto unmap;
578 }
579
580 ret = msm_hsic_init_vddcx(mehci, 1);
581 if (ret) {
582 dev_err(&pdev->dev, "unable to initialize VDDCX\n");
583 ret = -ENODEV;
584 goto deinit_clocks;
585 }
586
587 ret = msm_hsic_reset(mehci);
588 if (ret) {
589 dev_err(&pdev->dev, "unable to initialize PHY\n");
590 goto deinit_vddcx;
591 }
592
593 ret = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
594 if (ret) {
595 dev_err(&pdev->dev, "unable to register HCD\n");
596 goto deinit_vddcx;
597 }
598
599 device_init_wakeup(&pdev->dev, 1);
600 wake_lock_init(&mehci->wlock, WAKE_LOCK_SUSPEND, dev_name(&pdev->dev));
601 wake_lock(&mehci->wlock);
602 /*
603 * This pdev->dev is assigned parent of root-hub by USB core,
604 * hence, runtime framework automatically calls this driver's
605 * runtime APIs based on root-hub's state.
606 */
607 pm_runtime_set_active(&pdev->dev);
608 pm_runtime_enable(&pdev->dev);
609
610 return 0;
611
612deinit_vddcx:
613 msm_hsic_init_vddcx(mehci, 0);
614deinit_clocks:
615 msm_hsic_init_clocks(mehci, 0);
616unmap:
617 iounmap(hcd->regs);
618put_hcd:
619 usb_put_hcd(hcd);
620
621 return ret;
622}
623
624static int __devexit ehci_hsic_msm_remove(struct platform_device *pdev)
625{
626 struct usb_hcd *hcd = platform_get_drvdata(pdev);
627 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
628
629 device_init_wakeup(&pdev->dev, 0);
630 pm_runtime_disable(&pdev->dev);
631 pm_runtime_set_suspended(&pdev->dev);
632
633 usb_remove_hcd(hcd);
634 msm_hsic_init_vddcx(mehci, 0);
635
636 msm_hsic_init_clocks(mehci, 0);
637 wake_lock_destroy(&mehci->wlock);
638 iounmap(hcd->regs);
639 usb_put_hcd(hcd);
640
641 return 0;
642}
643
644#ifdef CONFIG_PM_SLEEP
645static int msm_hsic_pm_suspend(struct device *dev)
646{
647 struct usb_hcd *hcd = dev_get_drvdata(dev);
648 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
649
650 dev_dbg(dev, "ehci-msm-hsic PM suspend\n");
651
652 if (device_may_wakeup(dev))
653 enable_irq_wake(hcd->irq);
654
655 return msm_hsic_suspend(mehci);
656
657}
658
659static int msm_hsic_pm_resume(struct device *dev)
660{
661 int ret;
662 struct usb_hcd *hcd = dev_get_drvdata(dev);
663 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
664
665 dev_dbg(dev, "ehci-msm-hsic PM resume\n");
666
667 if (device_may_wakeup(dev))
668 disable_irq_wake(hcd->irq);
669
670 ret = msm_hsic_resume(mehci);
671 if (ret)
672 return ret;
673
674 /* Bring the device to full powered state upon system resume */
675 pm_runtime_disable(dev);
676 pm_runtime_set_active(dev);
677 pm_runtime_enable(dev);
678
679 return 0;
680}
681#endif
682
683#ifdef CONFIG_PM_RUNTIME
684static int msm_hsic_runtime_idle(struct device *dev)
685{
686 dev_dbg(dev, "EHCI runtime idle\n");
687
688 return 0;
689}
690
691static int msm_hsic_runtime_suspend(struct device *dev)
692{
693 struct usb_hcd *hcd = dev_get_drvdata(dev);
694 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
695
696 dev_dbg(dev, "EHCI runtime suspend\n");
697 return msm_hsic_suspend(mehci);
698}
699
700static int msm_hsic_runtime_resume(struct device *dev)
701{
702 struct usb_hcd *hcd = dev_get_drvdata(dev);
703 struct msm_hsic_hcd *mehci = hcd_to_hsic(hcd);
704
705 dev_dbg(dev, "EHCI runtime resume\n");
706 return msm_hsic_resume(mehci);
707}
708#endif
709
710#ifdef CONFIG_PM
711static const struct dev_pm_ops msm_hsic_dev_pm_ops = {
712 SET_SYSTEM_SLEEP_PM_OPS(msm_hsic_pm_suspend, msm_hsic_pm_resume)
713 SET_RUNTIME_PM_OPS(msm_hsic_runtime_suspend, msm_hsic_runtime_resume,
714 msm_hsic_runtime_idle)
715};
716#endif
717
718static struct platform_driver ehci_msm_hsic_driver = {
719 .probe = ehci_hsic_msm_probe,
720 .remove = __devexit_p(ehci_hsic_msm_remove),
721 .driver = {
722 .name = "msm_hsic_host",
723#ifdef CONFIG_PM
724 .pm = &msm_hsic_dev_pm_ops,
725#endif
726 },
727};