sys/dev/drm/i915/i915_drv.c
/**
 * i915_reset - reset chip after a hang
 * @dev: drm device to reset
 *
 * Reset the chip.  Useful if a hang is detected. Returns zero on successful
 * reset or otherwise an error code.
 *
 * Procedure is fairly simple:
 *   - reset the chip using the reset reg
 *   - re-init context state
 *   - re-init hardware status page
 *   - re-init ring buffer
 *   - re-init interrupt state
 *   - re-init display
 */
reset chip after a hang
@dev: drm device to reset

Reset the chip.  Useful if a hang is detected. Returns zero on successful
reset or otherwise an error code.


reset chip after a hang @dev : drm device to reset Reset the chip . Useful if a hang is detected . Returns zero on successful reset or otherwise an error code .
int i915_reset(struct drm_i915_private *dev_priv)
{
	struct drm_device *dev = dev_priv->dev;
	struct i915_gpu_error *error = &dev_priv->gpu_error;
	unsigned reset_counter;
	int ret;
	intel_reset_gt_powersave(dev_priv);
	mutex_lock(&dev->struct_mutex);
	atomic_andnot(I915_WEDGED, &error->reset_counter);
	reset_counter = atomic_inc_return(&error->reset_counter);
	if (WARN_ON(__i915_reset_in_progress(reset_counter))) {
		ret = -EIO;
		goto error;
	}
	i915_gem_reset(dev);
	ret = intel_gpu_reset(dev_priv, ALL_ENGINES);
	if (error->stop_rings != 0) {
		DRM_INFO("Simulated gpu hang, resetting stop_rings\n");
		error->stop_rings = 0;
		if (ret == -ENODEV) {
			DRM_INFO("Reset not implemented, but ignoring "
				 "error for simulated gpu hangs\n");
			ret = 0;
		}
	}
	if (i915_stop_ring_allow_warn(dev_priv))
		pr_notice("drm/i915: Resetting chip after gpu hang\n");
	if (ret) {
		if (ret != -ENODEV)
			DRM_ERROR("Failed to reset chip: %i\n", ret);
		else
			DRM_DEBUG_DRIVER("GPU reset disabled\n");
		goto error;
	}
	intel_overlay_reset(dev_priv);
	ret = i915_gem_init_hw(dev);
	if (ret) {
		DRM_ERROR("Failed hw init on reset %d\n", ret);
		goto error;
	}
	mutex_unlock(&dev->struct_mutex);
	if (INTEL_INFO(dev)->gen > 5)
		intel_enable_gt_powersave(dev_priv);
	return 0;
error:
	atomic_or(I915_WEDGED, &error->reset_counter);
	mutex_unlock(&dev->struct_mutex);
	return ret;
}
int i915_reset ( struct drm_i915_private * dev_priv ) { struct drm_device * dev = dev_priv -> dev ; struct i915_gpu_error * error = & dev_priv -> gpu_error ; unsigned reset_counter ; int ret ; intel_reset_gt_powersave ( dev_priv ) ; mutex_lock ( & dev -> struct_mutex ) ; atomic_andnot ( I915_WEDGED , & error -> reset_counter ) ; reset_counter = atomic_inc_return ( & error -> reset_counter ) ; if ( WARN_ON ( __i915_reset_in_progress ( reset_counter ) ) ) { ret = - EIO ; goto error ; } i915_gem_reset ( dev ) ; ret = intel_gpu_reset ( dev_priv , ALL_ENGINES ) ; if ( error -> stop_rings != 0 ) { DRM_INFO ( " \n " ) ; error -> stop_rings = 0 ; if ( ret == - ENODEV ) { DRM_INFO ( " " " \n " ) ; ret = 0 ; } } if ( i915_stop_ring_allow_warn ( dev_priv ) ) pr_notice ( " \n " ) ; if ( ret ) { if ( ret != - ENODEV ) DRM_ERROR ( " \n " , ret ) ; else DRM_DEBUG_DRIVER ( " \n " ) ; goto error ; } intel_overlay_reset ( dev_priv ) ; ret = i915_gem_init_hw ( dev ) ; if ( ret ) { DRM_ERROR ( " \n " , ret ) ; goto error ; } mutex_unlock ( & dev -> struct_mutex ) ; if ( INTEL_INFO ( dev ) -> gen > 5 ) intel_enable_gt_powersave ( dev_priv ) ; return 0 ; error : atomic_or ( I915_WEDGED , & error -> reset_counter ) ; mutex_unlock ( & dev -> struct_mutex ) ; return ret ; }
i915_reset - reset chip after a hang
 @dev: drm device to reset
i915_reset - reset chip after a hang @dev : drm device to reset
/* Clear any previous failed attempts at recovery. Time to try again. */ /* Clear the reset-in-progress flag and increment the reset epoch. */ /* Also reset the gpu hangman. */ /* Ok, now get things going again... */ /*
	 * Everything depends on having the GTT running, so we need to start
	 * there.  Fortunately we don't need to do this unless we reset the
	 * chip at a PCI level.
	 *
	 * Next we need to restore the context, but we don't use those
	 * yet either...
	 *
	 * Ring buffer needs to be re-initialized in the KMS case, or if X
	 * was running at the time of the reset (i.e. we weren't VT
	 * switched away).
	 */ /*
	 * rps/rc6 re-init is necessary to restore state lost after the
	 * reset and the re-install of gt irqs. Skip for ironlake per
	 * previous concerns that it doesn't respond well to some forms
	 * of re-init after reset.
	 */