diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2013-10-01 08:05:07 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2013-10-01 08:05:05 -0700 |
| commit | 9c6475f3bbc709dba3e2fc25354472a2cdfcdebc (patch) | |
| tree | 51355a1d0103f604cefc66d80b314090c68c84dc | |
| parent | a883420fb5a99527eabf05202c8fb9870629543c (diff) | |
| parent | bfed0ed2670d2bafef2bf0e1fde7fc1755821e7f (diff) | |
Merge "usb: xhci-msm-hsic: Add wakeup gpio support for out of band remote wakeup"
| -rw-r--r-- | Documentation/devicetree/bindings/usb/msm-xhci-hsic.txt | 15 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-msm-hsic.c | 50 |
2 files changed, 42 insertions, 23 deletions
diff --git a/Documentation/devicetree/bindings/usb/msm-xhci-hsic.txt b/Documentation/devicetree/bindings/usb/msm-xhci-hsic.txt index 4d1cb35118f..1cac58eb4f1 100644 --- a/Documentation/devicetree/bindings/usb/msm-xhci-hsic.txt +++ b/Documentation/devicetree/bindings/usb/msm-xhci-hsic.txt @@ -17,13 +17,22 @@ Required properties : values (no, min, max) where each value represents either a voltage in microvolts or a value corresponding to voltage corner. +Optional properties : +- interrupt-names : Optional interrupt resource entry is: + "wakeup_irq" : Interrupt generated by out of band remote wakeup gpio. + Example MSM HSIC XHCI controller device node : xhci_hsic_host: qcom,xhci-msm-hsic@0xf9c00000 { compatible = "qcom,xhci-msm-hsic"; reg = <0xf9c00000 0xfc000>; - interrupts = <0 32 0>, - <0 29 0>; - interrupt-names = "core_irq", "pwr_event_irq"; + interrupt-parent = <&xhci_hsic_host>; + interrupts = <0 1 2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xffffffff>; + interrupt-map = <0 &intc 0 32 0 + 1 &intc 0 29 0 + 2 &msmgpio 107 0x8>; + interrupt-names = "core_irq", "pwr_event_irq", "wakeup_irq"; hsic-vdd-dig-supply = <&pma8084_s2_corner>; hsic-gdsc-supply = <&gdsc_usb_hsic>; hsic,strobe-gpio = <&msmgpio 134 0x00>; diff --git a/drivers/usb/host/xhci-msm-hsic.c b/drivers/usb/host/xhci-msm-hsic.c index d15d0ed4ce3..445c9184654 100644 --- a/drivers/usb/host/xhci-msm-hsic.c +++ b/drivers/usb/host/xhci-msm-hsic.c @@ -405,6 +405,7 @@ static void mxhci_hsic_reset(struct mxhci_hsic_hcd *mxhci) static void mxhci_hsic_plat_quirks(struct device *dev, struct xhci_hcd *xhci) { struct xhci_plat_data *pdata = dev->platform_data; + struct mxhci_hsic_hcd *mxhci = hcd_to_hsic(xhci_to_hcd(xhci)); /* * As of now platform drivers don't provide MSI support so we ensure @@ -413,6 +414,10 @@ static void mxhci_hsic_plat_quirks(struct device *dev, struct xhci_hcd *xhci) */ xhci->quirks |= XHCI_BROKEN_MSI; + /* Single port controller using out of band remote wakeup */ + if (mxhci->wakeup_irq) + xhci->quirks |= XHCI_NO_SELECTIVE_SUSPEND; + if (!pdata) return; if (pdata->vendor == SYNOPSIS_DWC3_VENDOR && @@ -544,9 +549,11 @@ static int mxhci_hsic_suspend(struct mxhci_hsic_hcd *mxhci) enable_irq(hcd->irq); - mxhci->wakeup_irq_enabled = 1; - enable_irq_wake(mxhci->wakeup_irq); - enable_irq(mxhci->wakeup_irq); + if (mxhci->wakeup_irq) { + mxhci->wakeup_irq_enabled = 1; + enable_irq_wake(mxhci->wakeup_irq); + enable_irq(mxhci->wakeup_irq); + } pm_relax(mxhci->dev); @@ -557,6 +564,7 @@ static int mxhci_hsic_suspend(struct mxhci_hsic_hcd *mxhci) static int mxhci_hsic_resume(struct mxhci_hsic_hcd *mxhci) { + struct usb_hcd *hcd = hsic_to_hcd(mxhci); int ret; unsigned long flags; @@ -593,6 +601,9 @@ static int mxhci_hsic_resume(struct mxhci_hsic_hcd *mxhci) clk_prepare_enable(mxhci->hsic_clk); clk_prepare_enable(mxhci->cal_clk); + if (mxhci->wakeup_irq) + usb_hcd_resume_root_hub(hcd); + mxhci->in_lpm = 0; dev_info(mxhci->dev, "HSIC-USB exited from low power mode\n"); @@ -777,6 +788,22 @@ static int mxhci_hsic_probe(struct platform_device *pdev) /* enable pwr event irq for LPM_IN_L2_IRQ */ writel_relaxed(LPM_IN_L2_IRQ_MASK, MSM_HSIC_PWR_EVNT_IRQ_MASK); + mxhci->wakeup_irq = platform_get_irq_byname(pdev, "wakeup_irq"); + if (mxhci->wakeup_irq < 0) { + mxhci->wakeup_irq = 0; + dev_err(&pdev->dev, "failed to init wakeup_irq\n"); + } else { + /* enable wakeup irq only when entering lpm */ + irq_set_status_flags(mxhci->wakeup_irq, IRQ_NOAUTOEN); + ret = devm_request_irq(&pdev->dev, mxhci->wakeup_irq, + mxhci_hsic_wakeup_irq, 0, "mxhci_hsic_wakeup", mxhci); + if (ret) { + dev_err(&pdev->dev, + "request irq failed (wakeup irq)\n"); + goto deinit_vddcx; + } + } + ret = usb_add_hcd(hcd, irq, IRQF_SHARED); if (ret) goto deinit_vddcx; @@ -824,23 +851,6 @@ static int mxhci_hsic_probe(struct platform_device *pdev) goto remove_usb3_hcd; } - mxhci->wakeup_irq = gpio_to_irq(mxhci->strobe); - if (mxhci->wakeup_irq < 0) { - dev_err(&pdev->dev, "gpio_to_irq for strobe gpio failed\n"); - goto remove_usb3_hcd; - } else { - - /* enable wakeup irq while entring lpm */ - irq_set_status_flags(mxhci->wakeup_irq, IRQ_NOAUTOEN); - ret = devm_request_irq(&pdev->dev, mxhci->wakeup_irq, - mxhci_hsic_wakeup_irq, - IRQF_TRIGGER_LOW, "mxhci_hsic_wakeup", mxhci); - if (ret) { - dev_err(&pdev->dev, - "request irq failed (wakeup irq)\n"); - goto remove_usb3_hcd; - } - } init_completion(&mxhci->phy_in_lpm); |
