Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5bcf719b authored by Dave Airlie's avatar Dave Airlie
Browse files

drm/switcheroo: track state of switch in drivers.



We need to track the state of the switch in drivers, so that after s/r
we don't resume the card we've explicitly switched off before. Also
don't allow a userspace open to occur if we've switched the gpu off.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 8d608aa6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -236,6 +236,8 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
		return -EBUSY;	/* No exclusive opens */
	if (!drm_cpu_valid())
		return -EINVAL;
	if (dev->switch_power_state != DRM_SWITCH_POWER_ON)
		return -EINVAL;

	DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor_id);

+4 −0
Original line number Diff line number Diff line
@@ -1151,12 +1151,16 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_
	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
	if (state == VGA_SWITCHEROO_ON) {
		printk(KERN_INFO "i915: switched on\n");
		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
		/* i915 resume handler doesn't set to D0 */
		pci_set_power_state(dev->pdev, PCI_D0);
		i915_resume(dev);
		dev->switch_power_state = DRM_SWITCH_POWER_ON;
	} else {
		printk(KERN_ERR "i915: switched off\n");
		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
		i915_suspend(dev, pmm);
		dev->switch_power_state = DRM_SWITCH_POWER_OFF;
	}
}

+11 −1
Original line number Diff line number Diff line
@@ -271,6 +271,8 @@ static int i915_drm_freeze(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;

	drm_kms_helper_poll_disable(dev);

	pci_save_state(dev->pdev);

	/* If KMS is active, we do the leavevt stuff here */
@@ -307,7 +309,9 @@ int i915_suspend(struct drm_device *dev, pm_message_t state)
	if (state.event == PM_EVENT_PRETHAW)
		return 0;

	drm_kms_helper_poll_disable(dev);

	if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
		return 0;

	error = i915_drm_freeze(dev);
	if (error)
@@ -361,6 +365,9 @@ int i915_resume(struct drm_device *dev)
{
	int ret;

	if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
		return 0;

	if (pci_enable_device(dev->pdev))
		return -EIO;

@@ -569,6 +576,9 @@ static int i915_pm_suspend(struct device *dev)
		return -ENODEV;
	}

	if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
		return 0;

	error = i915_drm_freeze(drm_dev);
	if (error)
		return error;
+6 −0
Original line number Diff line number Diff line
@@ -171,6 +171,9 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
	if (pm_state.event == PM_EVENT_PRETHAW)
		return 0;

	if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
		return 0;

	NV_INFO(dev, "Disabling fbcon acceleration...\n");
	nouveau_fbcon_save_disable_accel(dev);

@@ -254,6 +257,9 @@ nouveau_pci_resume(struct pci_dev *pdev)
	struct drm_crtc *crtc;
	int ret, i;

	if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
		return 0;

	nouveau_fbcon_save_disable_accel(dev);

	NV_INFO(dev, "We're back, enabling device...\n");
+2 −0
Original line number Diff line number Diff line
@@ -753,6 +753,8 @@ struct drm_nouveau_private {

	struct nouveau_fbdev *nfbdev;
	struct apertures_struct *apertures;

	bool powered_down;
};

static inline struct drm_nouveau_private *
Loading