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

vbox_drv.c (4288B)


      1// SPDX-License-Identifier: MIT
      2/*
      3 * Copyright (C) 2013-2017 Oracle Corporation
      4 * This file is based on ast_drv.c
      5 * Copyright 2012 Red Hat Inc.
      6 * Authors: Dave Airlie <airlied@redhat.com>
      7 *          Michael Thayer <michael.thayer@oracle.com,
      8 *          Hans de Goede <hdegoede@redhat.com>
      9 */
     10#include <linux/module.h>
     11#include <linux/pci.h>
     12#include <linux/vt_kern.h>
     13
     14#include <drm/drm_aperture.h>
     15#include <drm/drm_crtc_helper.h>
     16#include <drm/drm_drv.h>
     17#include <drm/drm_fb_helper.h>
     18#include <drm/drm_file.h>
     19#include <drm/drm_ioctl.h>
     20#include <drm/drm_managed.h>
     21#include <drm/drm_module.h>
     22
     23#include "vbox_drv.h"
     24
     25static int vbox_modeset = -1;
     26
     27MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
     28module_param_named(modeset, vbox_modeset, int, 0400);
     29
     30static const struct drm_driver driver;
     31
     32static const struct pci_device_id pciidlist[] = {
     33	{ PCI_DEVICE(0x80ee, 0xbeef) },
     34	{ }
     35};
     36MODULE_DEVICE_TABLE(pci, pciidlist);
     37
     38static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
     39{
     40	struct vbox_private *vbox;
     41	int ret = 0;
     42
     43	if (!vbox_check_supported(VBE_DISPI_ID_HGSMI))
     44		return -ENODEV;
     45
     46	ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver);
     47	if (ret)
     48		return ret;
     49
     50	vbox = devm_drm_dev_alloc(&pdev->dev, &driver,
     51				  struct vbox_private, ddev);
     52	if (IS_ERR(vbox))
     53		return PTR_ERR(vbox);
     54
     55	pci_set_drvdata(pdev, vbox);
     56	mutex_init(&vbox->hw_mutex);
     57
     58	ret = pcim_enable_device(pdev);
     59	if (ret)
     60		return ret;
     61
     62	ret = vbox_hw_init(vbox);
     63	if (ret)
     64		return ret;
     65
     66	ret = vbox_mm_init(vbox);
     67	if (ret)
     68		goto err_hw_fini;
     69
     70	ret = vbox_mode_init(vbox);
     71	if (ret)
     72		goto err_hw_fini;
     73
     74	ret = vbox_irq_init(vbox);
     75	if (ret)
     76		goto err_mode_fini;
     77
     78	ret = drm_dev_register(&vbox->ddev, 0);
     79	if (ret)
     80		goto err_irq_fini;
     81
     82	drm_fbdev_generic_setup(&vbox->ddev, 32);
     83
     84	return 0;
     85
     86err_irq_fini:
     87	vbox_irq_fini(vbox);
     88err_mode_fini:
     89	vbox_mode_fini(vbox);
     90err_hw_fini:
     91	vbox_hw_fini(vbox);
     92	return ret;
     93}
     94
     95static void vbox_pci_remove(struct pci_dev *pdev)
     96{
     97	struct vbox_private *vbox = pci_get_drvdata(pdev);
     98
     99	drm_dev_unregister(&vbox->ddev);
    100	vbox_irq_fini(vbox);
    101	vbox_mode_fini(vbox);
    102	vbox_hw_fini(vbox);
    103}
    104
    105#ifdef CONFIG_PM_SLEEP
    106static int vbox_pm_suspend(struct device *dev)
    107{
    108	struct vbox_private *vbox = dev_get_drvdata(dev);
    109	struct pci_dev *pdev = to_pci_dev(dev);
    110	int error;
    111
    112	error = drm_mode_config_helper_suspend(&vbox->ddev);
    113	if (error)
    114		return error;
    115
    116	pci_save_state(pdev);
    117	pci_disable_device(pdev);
    118	pci_set_power_state(pdev, PCI_D3hot);
    119
    120	return 0;
    121}
    122
    123static int vbox_pm_resume(struct device *dev)
    124{
    125	struct vbox_private *vbox = dev_get_drvdata(dev);
    126	struct pci_dev *pdev = to_pci_dev(dev);
    127
    128	if (pci_enable_device(pdev))
    129		return -EIO;
    130
    131	return drm_mode_config_helper_resume(&vbox->ddev);
    132}
    133
    134static int vbox_pm_freeze(struct device *dev)
    135{
    136	struct vbox_private *vbox = dev_get_drvdata(dev);
    137
    138	return drm_mode_config_helper_suspend(&vbox->ddev);
    139}
    140
    141static int vbox_pm_thaw(struct device *dev)
    142{
    143	struct vbox_private *vbox = dev_get_drvdata(dev);
    144
    145	return drm_mode_config_helper_resume(&vbox->ddev);
    146}
    147
    148static int vbox_pm_poweroff(struct device *dev)
    149{
    150	struct vbox_private *vbox = dev_get_drvdata(dev);
    151
    152	return drm_mode_config_helper_suspend(&vbox->ddev);
    153}
    154
    155static const struct dev_pm_ops vbox_pm_ops = {
    156	.suspend = vbox_pm_suspend,
    157	.resume = vbox_pm_resume,
    158	.freeze = vbox_pm_freeze,
    159	.thaw = vbox_pm_thaw,
    160	.poweroff = vbox_pm_poweroff,
    161	.restore = vbox_pm_resume,
    162};
    163#endif
    164
    165static struct pci_driver vbox_pci_driver = {
    166	.name = DRIVER_NAME,
    167	.id_table = pciidlist,
    168	.probe = vbox_pci_probe,
    169	.remove = vbox_pci_remove,
    170#ifdef CONFIG_PM_SLEEP
    171	.driver.pm = &vbox_pm_ops,
    172#endif
    173};
    174
    175DEFINE_DRM_GEM_FOPS(vbox_fops);
    176
    177static const struct drm_driver driver = {
    178	.driver_features =
    179	    DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
    180
    181	.lastclose = drm_fb_helper_lastclose,
    182
    183	.fops = &vbox_fops,
    184	.name = DRIVER_NAME,
    185	.desc = DRIVER_DESC,
    186	.date = DRIVER_DATE,
    187	.major = DRIVER_MAJOR,
    188	.minor = DRIVER_MINOR,
    189	.patchlevel = DRIVER_PATCHLEVEL,
    190
    191	DRM_GEM_VRAM_DRIVER,
    192};
    193
    194drm_module_pci_driver_if_modeset(vbox_pci_driver, vbox_modeset);
    195
    196MODULE_AUTHOR("Oracle Corporation");
    197MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
    198MODULE_DESCRIPTION(DRIVER_DESC);
    199MODULE_LICENSE("GPL and additional rights");