Loading Documentation/devicetree/bindings/usb/msm-xhci-hsic.txt +12 −3 Original line number Diff line number Diff line Loading @@ -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>; Loading drivers/usb/host/xhci-msm-hsic.c +30 −20 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 && Loading Loading @@ -544,9 +549,11 @@ static int mxhci_hsic_suspend(struct mxhci_hsic_hcd *mxhci) enable_irq(hcd->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); Loading @@ -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; Loading Loading @@ -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"); Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading
Documentation/devicetree/bindings/usb/msm-xhci-hsic.txt +12 −3 Original line number Diff line number Diff line Loading @@ -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>; Loading
drivers/usb/host/xhci-msm-hsic.c +30 −20 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 && Loading Loading @@ -544,9 +549,11 @@ static int mxhci_hsic_suspend(struct mxhci_hsic_hcd *mxhci) enable_irq(hcd->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); Loading @@ -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; Loading Loading @@ -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"); Loading Loading @@ -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; Loading Loading @@ -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); Loading