File Index
Files and directories
Sign in
FILE

vbox_drv.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/vboxvideo/vbox_drv.c C
  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");
~/ Read-only file preview.