diff options
| author | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
| commit | 1ac731c529cd4d6adbce134754b51ff7d822b145 (patch) | |
| tree | 143ab3f35ca5f3b69f583c84e6964b17139c2ec1 /drivers/accel/ivpu/ivpu_pm.c | |
| parent | 07b4c950f27bef0362dc6ad7ee713aab61d58149 (diff) | |
| parent | 54116d442e001e1b6bd482122043b1870998a1f3 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.6 merge window.
Diffstat (limited to 'drivers/accel/ivpu/ivpu_pm.c')
| -rw-r--r-- | drivers/accel/ivpu/ivpu_pm.c | 53 | 
1 files changed, 25 insertions, 28 deletions
diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 553bcbd787b3..aa4d56dc52b3 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -98,12 +98,18 @@ retry:  static void ivpu_pm_recovery_work(struct work_struct *work)  {  	struct ivpu_pm_info *pm = container_of(work, struct ivpu_pm_info, recovery_work); -	struct ivpu_device *vdev =  pm->vdev; +	struct ivpu_device *vdev = pm->vdev;  	char *evt[2] = {"IVPU_PM_EVENT=IVPU_RECOVER", NULL};  	int ret; -	ret = pci_reset_function(to_pci_dev(vdev->drm.dev)); -	if (ret) +retry: +	ret = pci_try_reset_function(to_pci_dev(vdev->drm.dev)); +	if (ret == -EAGAIN && !drm_dev_is_unplugged(&vdev->drm)) { +		cond_resched(); +		goto retry; +	} + +	if (ret && ret != -EAGAIN)  		ivpu_err(vdev, "Failed to reset VPU: %d\n", ret);  	kobject_uevent_env(&vdev->drm.dev->kobj, KOBJ_CHANGE, evt); @@ -134,32 +140,28 @@ int ivpu_pm_suspend_cb(struct device *dev)  {  	struct drm_device *drm = dev_get_drvdata(dev);  	struct ivpu_device *vdev = to_ivpu_device(drm); -	int ret; +	unsigned long timeout;  	ivpu_dbg(vdev, PM, "Suspend..\n"); -	ret = ivpu_suspend(vdev); -	if (ret && vdev->pm->suspend_reschedule_counter) { -		ivpu_dbg(vdev, PM, "Failed to enter idle, rescheduling suspend, retries left %d\n", -			 vdev->pm->suspend_reschedule_counter); -		pm_schedule_suspend(dev, vdev->timeout.reschedule_suspend); -		vdev->pm->suspend_reschedule_counter--; -		return -EBUSY; -	} else if (!vdev->pm->suspend_reschedule_counter) { -		ivpu_warn(vdev, "Failed to enter idle, force suspend\n"); -		ivpu_pm_prepare_cold_boot(vdev); -	} else { -		ivpu_pm_prepare_warm_boot(vdev); +	timeout = jiffies + msecs_to_jiffies(vdev->timeout.tdr); +	while (!ivpu_hw_is_idle(vdev)) { +		cond_resched(); +		if (time_after_eq(jiffies, timeout)) { +			ivpu_err(vdev, "Failed to enter idle on system suspend\n"); +			return -EBUSY; +		}  	} -	vdev->pm->suspend_reschedule_counter = PM_RESCHEDULE_LIMIT; +	ivpu_suspend(vdev); +	ivpu_pm_prepare_warm_boot(vdev);  	pci_save_state(to_pci_dev(dev));  	pci_set_power_state(to_pci_dev(dev), PCI_D3hot);  	ivpu_dbg(vdev, PM, "Suspend done.\n"); -	return ret; +	return 0;  }  int ivpu_pm_resume_cb(struct device *dev) @@ -237,8 +239,6 @@ int ivpu_rpm_get(struct ivpu_device *vdev)  {  	int ret; -	ivpu_dbg(vdev, RPM, "rpm_get count %d\n", atomic_read(&vdev->drm.dev->power.usage_count)); -  	ret = pm_runtime_resume_and_get(vdev->drm.dev);  	if (!drm_WARN_ON(&vdev->drm, ret < 0))  		vdev->pm->suspend_reschedule_counter = PM_RESCHEDULE_LIMIT; @@ -248,8 +248,6 @@ int ivpu_rpm_get(struct ivpu_device *vdev)  void ivpu_rpm_put(struct ivpu_device *vdev)  { -	ivpu_dbg(vdev, RPM, "rpm_put count %d\n", atomic_read(&vdev->drm.dev->power.usage_count)); -  	pm_runtime_mark_last_busy(vdev->drm.dev);  	pm_runtime_put_autosuspend(vdev->drm.dev);  } @@ -306,6 +304,11 @@ int ivpu_pm_init(struct ivpu_device *vdev)  	return 0;  } +void ivpu_pm_cancel_recovery(struct ivpu_device *vdev) +{ +	cancel_work_sync(&vdev->pm->recovery_work); +} +  void ivpu_pm_enable(struct ivpu_device *vdev)  {  	struct device *dev = vdev->drm.dev; @@ -314,16 +317,10 @@ void ivpu_pm_enable(struct ivpu_device *vdev)  	pm_runtime_allow(dev);  	pm_runtime_mark_last_busy(dev);  	pm_runtime_put_autosuspend(dev); - -	ivpu_dbg(vdev, RPM, "Enable RPM count %d\n", atomic_read(&dev->power.usage_count));  }  void ivpu_pm_disable(struct ivpu_device *vdev)  { -	struct device *dev = vdev->drm.dev; - -	ivpu_dbg(vdev, RPM, "Disable RPM count %d\n", atomic_read(&dev->power.usage_count)); -  	pm_runtime_get_noresume(vdev->drm.dev);  	pm_runtime_forbid(vdev->drm.dev);  }  |