Commit 0ab9cfeb authored by Imre Deak's avatar Imre Deak Committed by Daniel Vetter

drm/i915: propagate the error code from runtime PM callbacks

Atm, none of the RPM callbacks can fail, but the next patch adding
RPM support for VLV changes this, so prepare for it.

In case one of these callbacks return error RPM will get permanently
disabled until the error is explicitly cleared. In the future we could
add support for re-enabling it, for example after resetting the HW, but
for now - hopefully - we can live with the simpler solution.

v2:
- propagate the error from the resume callbacks too (Paulo)
v3:
- fix rebase fail typo around IS_GEN6() check in intel_runtime_suspend()
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 9e72b46c
...@@ -916,21 +916,27 @@ static int i915_pm_poweroff(struct device *dev) ...@@ -916,21 +916,27 @@ static int i915_pm_poweroff(struct device *dev)
return i915_drm_freeze(drm_dev); return i915_drm_freeze(drm_dev);
} }
static void hsw_runtime_suspend(struct drm_i915_private *dev_priv) static int hsw_runtime_suspend(struct drm_i915_private *dev_priv)
{ {
hsw_enable_pc8(dev_priv); hsw_enable_pc8(dev_priv);
return 0;
} }
static void snb_runtime_resume(struct drm_i915_private *dev_priv) static int snb_runtime_resume(struct drm_i915_private *dev_priv)
{ {
struct drm_device *dev = dev_priv->dev; struct drm_device *dev = dev_priv->dev;
intel_init_pch_refclk(dev); intel_init_pch_refclk(dev);
return 0;
} }
static void hsw_runtime_resume(struct drm_i915_private *dev_priv) static int hsw_runtime_resume(struct drm_i915_private *dev_priv)
{ {
hsw_disable_pc8(dev_priv); hsw_disable_pc8(dev_priv);
return 0;
} }
int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool force_on) int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool force_on)
...@@ -975,6 +981,7 @@ static int intel_runtime_suspend(struct device *device) ...@@ -975,6 +981,7 @@ static int intel_runtime_suspend(struct device *device)
struct pci_dev *pdev = to_pci_dev(device); struct pci_dev *pdev = to_pci_dev(device);
struct drm_device *dev = pci_get_drvdata(pdev); struct drm_device *dev = pci_get_drvdata(pdev);
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
if (WARN_ON_ONCE(!(dev_priv->rps.enabled && intel_enable_rc6(dev)))) if (WARN_ON_ONCE(!(dev_priv->rps.enabled && intel_enable_rc6(dev))))
return -ENODEV; return -ENODEV;
...@@ -992,12 +999,21 @@ static int intel_runtime_suspend(struct device *device) ...@@ -992,12 +999,21 @@ static int intel_runtime_suspend(struct device *device)
cancel_work_sync(&dev_priv->rps.work); cancel_work_sync(&dev_priv->rps.work);
intel_runtime_pm_disable_interrupts(dev); intel_runtime_pm_disable_interrupts(dev);
if (IS_GEN6(dev)) if (IS_GEN6(dev)) {
; ret = 0;
else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
hsw_runtime_suspend(dev_priv); ret = hsw_runtime_suspend(dev_priv);
else } else {
ret = -ENODEV;
WARN_ON(1); WARN_ON(1);
}
if (ret) {
DRM_ERROR("Runtime suspend failed, disabling it (%d)\n", ret);
intel_runtime_pm_restore_interrupts(dev);
return ret;
}
i915_gem_release_all_mmaps(dev_priv); i915_gem_release_all_mmaps(dev_priv);
...@@ -1022,6 +1038,7 @@ static int intel_runtime_resume(struct device *device) ...@@ -1022,6 +1038,7 @@ static int intel_runtime_resume(struct device *device)
struct pci_dev *pdev = to_pci_dev(device); struct pci_dev *pdev = to_pci_dev(device);
struct drm_device *dev = pci_get_drvdata(pdev); struct drm_device *dev = pci_get_drvdata(pdev);
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
int ret;
WARN_ON(!HAS_RUNTIME_PM(dev)); WARN_ON(!HAS_RUNTIME_PM(dev));
...@@ -1030,21 +1047,31 @@ static int intel_runtime_resume(struct device *device) ...@@ -1030,21 +1047,31 @@ static int intel_runtime_resume(struct device *device)
intel_opregion_notify_adapter(dev, PCI_D0); intel_opregion_notify_adapter(dev, PCI_D0);
dev_priv->pm.suspended = false; dev_priv->pm.suspended = false;
if (IS_GEN6(dev)) if (IS_GEN6(dev)) {
snb_runtime_resume(dev_priv); ret = snb_runtime_resume(dev_priv);
else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
hsw_runtime_resume(dev_priv); ret = hsw_runtime_resume(dev_priv);
else } else {
WARN_ON(1); WARN_ON(1);
ret = -ENODEV;
}
/*
* No point of rolling back things in case of an error, as the best
* we can do is to hope that things will still work (and disable RPM).
*/
i915_gem_init_swizzling(dev); i915_gem_init_swizzling(dev);
gen6_update_ring_freq(dev); gen6_update_ring_freq(dev);
intel_runtime_pm_restore_interrupts(dev); intel_runtime_pm_restore_interrupts(dev);
intel_reset_gt_powersave(dev); intel_reset_gt_powersave(dev);
if (ret)
DRM_ERROR("Runtime resume failed, disabling it (%d)\n", ret);
else
DRM_DEBUG_KMS("Device resumed\n"); DRM_DEBUG_KMS("Device resumed\n");
return 0;
return ret;
} }
static const struct dev_pm_ops i915_pm_ops = { static const struct dev_pm_ops i915_pm_ops = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment