cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

i915_switcheroo.c (1959B)


      1// SPDX-License-Identifier: MIT
      2/*
      3 * Copyright © 2019 Intel Corporation
      4 */
      5
      6#include <linux/vga_switcheroo.h>
      7
      8#include "i915_driver.h"
      9#include "i915_drv.h"
     10#include "i915_switcheroo.h"
     11
     12static void i915_switcheroo_set_state(struct pci_dev *pdev,
     13				      enum vga_switcheroo_state state)
     14{
     15	struct drm_i915_private *i915 = pdev_to_i915(pdev);
     16	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
     17
     18	if (!i915) {
     19		dev_err(&pdev->dev, "DRM not initialized, aborting switch.\n");
     20		return;
     21	}
     22
     23	if (state == VGA_SWITCHEROO_ON) {
     24		drm_info(&i915->drm, "switched on\n");
     25		i915->drm.switch_power_state = DRM_SWITCH_POWER_CHANGING;
     26		/* i915 resume handler doesn't set to D0 */
     27		pci_set_power_state(pdev, PCI_D0);
     28		i915_driver_resume_switcheroo(i915);
     29		i915->drm.switch_power_state = DRM_SWITCH_POWER_ON;
     30	} else {
     31		drm_info(&i915->drm, "switched off\n");
     32		i915->drm.switch_power_state = DRM_SWITCH_POWER_CHANGING;
     33		i915_driver_suspend_switcheroo(i915, pmm);
     34		i915->drm.switch_power_state = DRM_SWITCH_POWER_OFF;
     35	}
     36}
     37
     38static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
     39{
     40	struct drm_i915_private *i915 = pdev_to_i915(pdev);
     41
     42	/*
     43	 * FIXME: open_count is protected by drm_global_mutex but that would lead to
     44	 * locking inversion with the driver load path. And the access here is
     45	 * completely racy anyway. So don't bother with locking for now.
     46	 */
     47	return i915 && atomic_read(&i915->drm.open_count) == 0;
     48}
     49
     50static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
     51	.set_gpu_state = i915_switcheroo_set_state,
     52	.reprobe = NULL,
     53	.can_switch = i915_switcheroo_can_switch,
     54};
     55
     56int i915_switcheroo_register(struct drm_i915_private *i915)
     57{
     58	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
     59
     60	return vga_switcheroo_register_client(pdev, &i915_switcheroo_ops, false);
     61}
     62
     63void i915_switcheroo_unregister(struct drm_i915_private *i915)
     64{
     65	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
     66
     67	vga_switcheroo_unregister_client(pdev);
     68}