Skip to content

Commit 0ec8671

Browse files
committed
accel/ivpu: Fix S3 system suspend when not idle
Wait for VPU to be idle in ivpu_pm_suspend_cb() before powering off the device, so jobs are not lost and TDRs are not triggered after resume. Fixes: 852be13 ("accel/ivpu: Add PM support") Signed-off-by: Stanislaw Gruszka <[email protected]> Reviewed-by: Jeffrey Hugo <[email protected]> Signed-off-by: Jacek Lawrynowicz <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 774e7cb commit 0ec8671

File tree

1 file changed

+11
-15
lines changed

1 file changed

+11
-15
lines changed

drivers/accel/ivpu/ivpu_pm.c

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -140,32 +140,28 @@ int ivpu_pm_suspend_cb(struct device *dev)
140140
{
141141
struct drm_device *drm = dev_get_drvdata(dev);
142142
struct ivpu_device *vdev = to_ivpu_device(drm);
143-
int ret;
143+
unsigned long timeout;
144144

145145
ivpu_dbg(vdev, PM, "Suspend..\n");
146146

147-
ret = ivpu_suspend(vdev);
148-
if (ret && vdev->pm->suspend_reschedule_counter) {
149-
ivpu_dbg(vdev, PM, "Failed to enter idle, rescheduling suspend, retries left %d\n",
150-
vdev->pm->suspend_reschedule_counter);
151-
pm_schedule_suspend(dev, vdev->timeout.reschedule_suspend);
152-
vdev->pm->suspend_reschedule_counter--;
153-
return -EBUSY;
154-
} else if (!vdev->pm->suspend_reschedule_counter) {
155-
ivpu_warn(vdev, "Failed to enter idle, force suspend\n");
156-
ivpu_pm_prepare_cold_boot(vdev);
157-
} else {
158-
ivpu_pm_prepare_warm_boot(vdev);
147+
timeout = jiffies + msecs_to_jiffies(vdev->timeout.tdr);
148+
while (!ivpu_hw_is_idle(vdev)) {
149+
cond_resched();
150+
if (time_after_eq(jiffies, timeout)) {
151+
ivpu_err(vdev, "Failed to enter idle on system suspend\n");
152+
return -EBUSY;
153+
}
159154
}
160155

161-
vdev->pm->suspend_reschedule_counter = PM_RESCHEDULE_LIMIT;
156+
ivpu_suspend(vdev);
157+
ivpu_pm_prepare_warm_boot(vdev);
162158

163159
pci_save_state(to_pci_dev(dev));
164160
pci_set_power_state(to_pci_dev(dev), PCI_D3hot);
165161

166162
ivpu_dbg(vdev, PM, "Suspend done.\n");
167163

168-
return ret;
164+
return 0;
169165
}
170166

171167
int ivpu_pm_resume_cb(struct device *dev)

0 commit comments

Comments
 (0)