Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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