mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
usb: dwc3-msm: Mandate pwr_evt_irq only for cores allowing SSPHY suspend
Currently the driver requires pwr_evt_irq to be compulsorily passed from DT unless the core is dual port. Now consider a core that does not allow SSPHY autosuspend during operational mode, instead allowing it only as a part of dwc3_msm_ssphy_autosuspend. As soon as autosuspend is enabled, there is a chance that pwr_evt_irq is fired with IN_P3 bit set. Although the driver will be marking mdwc->in_p3 in the pwr_evt_handler, it will fail to see IN_P3 bit to be set(because it has been cleared in handler) during the 5ms wait time in the ssphy_autosuspend function and prepare_suspend will again set mdwc->in_p3 to 0. This leads to failure of runtime/system suspend. Fix this by not passing pwr_evt_irq from DT for the cores which disable SSPHY autosuspend. Change-Id: I85ca7e45337fe35c570d163766e7638e11537201 Signed-off-by: Ajay Agarwal <ajaya@codeaurora.org>
This commit is contained in:
parent
bb168a0f46
commit
2b5d53c9ff
1 changed files with 45 additions and 43 deletions
|
|
@ -4530,36 +4530,6 @@ static int dwc3_msm_probe(struct platform_device *pdev)
|
|||
mdwc->lpm_to_suspend_delay = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < USB_MAX_IRQ; i++) {
|
||||
mdwc->wakeup_irq[i].irq = platform_get_irq_byname(pdev,
|
||||
usb_irq_info[i].name);
|
||||
/* pwr_evnt_irq is only mandatory irq for single port core */
|
||||
if (mdwc->wakeup_irq[i].irq < 0) {
|
||||
if (!mdwc->dual_port && usb_irq_info[i].required) {
|
||||
dev_err(&pdev->dev, "get_irq for %s failed\n\n",
|
||||
usb_irq_info[i].name);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
mdwc->wakeup_irq[i].irq = 0;
|
||||
} else {
|
||||
irq_set_status_flags(mdwc->wakeup_irq[i].irq,
|
||||
IRQ_NOAUTOEN);
|
||||
|
||||
ret = devm_request_threaded_irq(&pdev->dev,
|
||||
mdwc->wakeup_irq[i].irq,
|
||||
msm_dwc3_pwr_irq,
|
||||
msm_dwc3_pwr_irq_thread,
|
||||
usb_irq_info[i].irq_type,
|
||||
usb_irq_info[i].name, mdwc);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "irq req %s failed: %d\n\n",
|
||||
usb_irq_info[i].name, ret);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core_base");
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "missing memory base resource\n");
|
||||
|
|
@ -4606,19 +4576,6 @@ static int dwc3_msm_probe(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
dwc3_init_dbm(mdwc);
|
||||
|
||||
/* Add power event if the dbm indicates coming out of L1 by interrupt */
|
||||
if (!mdwc->dbm_is_1p4) {
|
||||
/* Dual port core does not need pwr_evnt_irq */
|
||||
if (!mdwc->dual_port && !mdwc->wakeup_irq[PWR_EVNT_IRQ].irq) {
|
||||
dev_err(&pdev->dev,
|
||||
"need pwr_event_irq exiting L1\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (of_property_read_u32(node, "qcom,dwc-usb3-msm-tx-fifo-size",
|
||||
&mdwc->tx_fifo_size))
|
||||
dev_err(&pdev->dev,
|
||||
|
|
@ -4745,6 +4702,51 @@ static int dwc3_msm_probe(struct platform_device *pdev)
|
|||
goto put_dwc3;
|
||||
}
|
||||
|
||||
for (i = 0; i < USB_MAX_IRQ; i++) {
|
||||
mdwc->wakeup_irq[i].irq = platform_get_irq_byname(pdev,
|
||||
usb_irq_info[i].name);
|
||||
/* pwr_evnt_irq is mandatory for cores allowing SSPHY suspend */
|
||||
if (mdwc->wakeup_irq[i].irq < 0) {
|
||||
if (!dwc->dis_u3_susphy_quirk &&
|
||||
usb_irq_info[i].required) {
|
||||
dev_err(&pdev->dev, "get_irq for %s failed\n\n",
|
||||
usb_irq_info[i].name);
|
||||
ret = -EINVAL;
|
||||
goto put_dwc3;
|
||||
}
|
||||
mdwc->wakeup_irq[i].irq = 0;
|
||||
} else {
|
||||
irq_set_status_flags(mdwc->wakeup_irq[i].irq,
|
||||
IRQ_NOAUTOEN);
|
||||
|
||||
ret = devm_request_threaded_irq(&pdev->dev,
|
||||
mdwc->wakeup_irq[i].irq,
|
||||
msm_dwc3_pwr_irq,
|
||||
msm_dwc3_pwr_irq_thread,
|
||||
usb_irq_info[i].irq_type,
|
||||
usb_irq_info[i].name, mdwc);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "irq req %s failed: %d\n\n",
|
||||
usb_irq_info[i].name, ret);
|
||||
goto put_dwc3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dwc3_init_dbm(mdwc);
|
||||
|
||||
/* Add power event if the dbm indicates coming out of L1 by interrupt */
|
||||
if (!mdwc->dbm_is_1p4) {
|
||||
/* pwr_evnt_irq is mandatory for cores allowing SSPHY suspend */
|
||||
if (!dwc->dis_u3_susphy_quirk &&
|
||||
!mdwc->wakeup_irq[PWR_EVNT_IRQ].irq) {
|
||||
dev_err(&pdev->dev,
|
||||
"need pwr_event_irq exiting L1\n");
|
||||
ret = -EINVAL;
|
||||
goto put_dwc3;
|
||||
}
|
||||
}
|
||||
|
||||
if (of_property_read_bool(node, "qcom,ignore-wakeup-src-in-hostmode")) {
|
||||
dwc->ignore_wakeup_src_in_hostmode = true;
|
||||
dev_dbg(mdwc->dev, "%s: Allow system suspend irrespective of runtime suspend\n",
|
||||
|
|
|
|||
Loading…
Reference in a new issue