summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/imagination/pvr_device.c17
-rw-r--r--drivers/gpu/drm/imagination/pvr_power.c11
2 files changed, 8 insertions, 20 deletions
diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c
index f58bb66a6327..dbb6f5a8ded1 100644
--- a/drivers/gpu/drm/imagination/pvr_device.c
+++ b/drivers/gpu/drm/imagination/pvr_device.c
@@ -225,29 +225,12 @@ static irqreturn_t pvr_device_irq_thread_handler(int irq, void *data)
}
if (pvr_dev->has_safety_events) {
- int err;
-
- /*
- * Ensure the GPU is powered on since some safety events (such
- * as ECC faults) can happen outside of job submissions, which
- * are otherwise the only time a power reference is held.
- */
- err = pvr_power_get(pvr_dev);
- if (err) {
- drm_err_ratelimited(drm_dev,
- "%s: could not take power reference (%d)\n",
- __func__, err);
- return ret;
- }
-
while (pvr_device_safety_irq_pending(pvr_dev)) {
pvr_device_safety_irq_clear(pvr_dev);
pvr_device_handle_safety_events(pvr_dev);
ret = IRQ_HANDLED;
}
-
- pvr_power_put(pvr_dev);
}
return ret;
diff --git a/drivers/gpu/drm/imagination/pvr_power.c b/drivers/gpu/drm/imagination/pvr_power.c
index ab10b4ac06b0..cee4d16ac851 100644
--- a/drivers/gpu/drm/imagination/pvr_power.c
+++ b/drivers/gpu/drm/imagination/pvr_power.c
@@ -90,7 +90,7 @@ pvr_power_request_pwr_off(struct pvr_device *pvr_dev)
}
static int
-pvr_power_fw_disable(struct pvr_device *pvr_dev, bool hard_reset)
+pvr_power_fw_disable(struct pvr_device *pvr_dev, bool hard_reset, bool rpm_suspend)
{
if (!hard_reset) {
int err;
@@ -106,6 +106,11 @@ pvr_power_fw_disable(struct pvr_device *pvr_dev, bool hard_reset)
return err;
}
+ if (rpm_suspend) {
+ /* Wait for late processing of GPU or firmware IRQs in other cores */
+ synchronize_irq(pvr_dev->irq);
+ }
+
return pvr_fw_stop(pvr_dev);
}
@@ -361,7 +366,7 @@ pvr_power_device_suspend(struct device *dev)
return -EIO;
if (pvr_dev->fw_dev.booted) {
- err = pvr_power_fw_disable(pvr_dev, false);
+ err = pvr_power_fw_disable(pvr_dev, false, true);
if (err)
goto err_drm_dev_exit;
}
@@ -527,7 +532,7 @@ pvr_power_reset(struct pvr_device *pvr_dev, bool hard_reset)
queues_disabled = true;
}
- err = pvr_power_fw_disable(pvr_dev, hard_reset);
+ err = pvr_power_fw_disable(pvr_dev, hard_reset, false);
if (!err) {
if (hard_reset) {
pvr_dev->fw_dev.booted = false;