summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/qxl/qxl_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/qxl/qxl_drv.c')
-rw-r--r--drivers/gpu/drm/qxl/qxl_drv.c160
1 files changed, 90 insertions, 70 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
index ccb090f3ab30..2bbb1168a3ff 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.c
+++ b/drivers/gpu/drm/qxl/qxl_drv.c
@@ -1,4 +1,3 @@
-/* vim: set ts=8 sw=8 tw=78 ai noexpandtab */
/* qxl_drv.c -- QXL driver -*- linux-c -*-
*
* Copyright 2011 Red Hat, Inc.
@@ -28,13 +27,26 @@
* Alon Levy <alevy@redhat.com>
*/
+#include "qxl_drv.h"
+
+#include <linux/aperture.h>
#include <linux/module.h>
-#include <linux/console.h>
+#include <linux/pci.h>
+#include <linux/vgaarb.h>
-#include <drm/drmP.h>
+#include <drm/clients/drm_client_setup.h>
#include <drm/drm.h>
-#include <drm/drm_crtc_helper.h>
-#include "qxl_drv.h"
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_fbdev_ttm.h>
+#include <drm/drm_file.h>
+#include <drm/drm_gem_ttm_helper.h>
+#include <drm/drm_module.h>
+#include <drm/drm_modeset_helper.h>
+#include <drm/drm_prime.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+
#include "qxl_object.h"
static const struct pci_device_id pciidlist[] = {
@@ -70,18 +82,33 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return -EINVAL; /* TODO: ENODEV ? */
}
- qdev = kzalloc(sizeof(struct qxl_device), GFP_KERNEL);
- if (!qdev)
+ qdev = devm_drm_dev_alloc(&pdev->dev, &qxl_driver,
+ struct qxl_device, ddev);
+ if (IS_ERR(qdev)) {
+ pr_err("Unable to init drm dev");
return -ENOMEM;
+ }
ret = pci_enable_device(pdev);
if (ret)
- goto free_dev;
+ return ret;
- ret = qxl_device_init(qdev, &qxl_driver, pdev);
+ ret = aperture_remove_conflicting_pci_devices(pdev, qxl_driver.name);
if (ret)
goto disable_pci;
+ if (pci_is_vga(pdev) && pdev->revision < 5) {
+ ret = vga_get_interruptible(pdev, VGA_RSRC_LEGACY_IO);
+ if (ret) {
+ DRM_ERROR("can't get legacy vga ioports\n");
+ goto disable_pci;
+ }
+ }
+
+ ret = qxl_device_init(qdev, pdev);
+ if (ret)
+ goto put_vga;
+
ret = qxl_modeset_init(qdev);
if (ret)
goto unload;
@@ -93,49 +120,58 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ret)
goto modeset_cleanup;
+ drm_client_setup(&qdev->ddev, NULL);
return 0;
modeset_cleanup:
qxl_modeset_fini(qdev);
unload:
qxl_device_fini(qdev);
+put_vga:
+ if (pci_is_vga(pdev) && pdev->revision < 5)
+ vga_put(pdev, VGA_RSRC_LEGACY_IO);
disable_pci:
pci_disable_device(pdev);
-free_dev:
- kfree(qdev);
+
return ret;
}
+static void qxl_drm_release(struct drm_device *dev)
+{
+ struct qxl_device *qdev = to_qxl(dev);
+
+ /*
+ * TODO: qxl_device_fini() call should be in qxl_pci_remove(),
+ * reordering qxl_modeset_fini() + qxl_device_fini() calls is
+ * non-trivial though.
+ */
+ qxl_modeset_fini(qdev);
+ qxl_device_fini(qdev);
+}
+
static void
qxl_pci_remove(struct pci_dev *pdev)
{
struct drm_device *dev = pci_get_drvdata(pdev);
- struct qxl_device *qdev = dev->dev_private;
drm_dev_unregister(dev);
+ drm_atomic_helper_shutdown(dev);
+ if (pci_is_vga(pdev) && pdev->revision < 5)
+ vga_put(pdev, VGA_RSRC_LEGACY_IO);
+}
- qxl_modeset_fini(qdev);
- qxl_device_fini(qdev);
-
- dev->dev_private = NULL;
- kfree(qdev);
- drm_dev_put(dev);
+static void
+qxl_pci_shutdown(struct pci_dev *pdev)
+{
+ drm_atomic_helper_shutdown(pci_get_drvdata(pdev));
}
-static const struct file_operations qxl_fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .unlocked_ioctl = drm_ioctl,
- .poll = drm_poll,
- .read = drm_read,
- .mmap = qxl_mmap,
-};
+DEFINE_DRM_GEM_FOPS(qxl_fops);
static int qxl_drm_freeze(struct drm_device *dev)
{
- struct pci_dev *pdev = dev->pdev;
- struct qxl_device *qdev = dev->dev_private;
+ struct pci_dev *pdev = to_pci_dev(dev->dev);
+ struct qxl_device *qdev = to_qxl(dev);
int ret;
ret = drm_mode_config_helper_suspend(dev);
@@ -157,12 +193,11 @@ static int qxl_drm_freeze(struct drm_device *dev)
static int qxl_drm_resume(struct drm_device *dev, bool thaw)
{
- struct qxl_device *qdev = dev->dev_private;
+ struct qxl_device *qdev = to_qxl(dev);
qdev->ram_header->int_mask = QXL_INTERRUPT_MASK;
if (!thaw) {
qxl_reinit_memslots(qdev);
- qxl_ring_init_hdr(qdev->release_ring);
}
qxl_create_monitors_object(qdev);
@@ -188,6 +223,7 @@ static int qxl_pm_resume(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
+ struct qxl_device *qdev = to_qxl(drm_dev);
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
@@ -195,21 +231,20 @@ static int qxl_pm_resume(struct device *dev)
return -EIO;
}
+ qxl_io_reset(qdev);
return qxl_drm_resume(drm_dev, false);
}
static int qxl_pm_thaw(struct device *dev)
{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct drm_device *drm_dev = pci_get_drvdata(pdev);
+ struct drm_device *drm_dev = dev_get_drvdata(dev);
return qxl_drm_resume(drm_dev, true);
}
static int qxl_pm_freeze(struct device *dev)
{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct drm_device *drm_dev = pci_get_drvdata(pdev);
+ struct drm_device *drm_dev = dev_get_drvdata(dev);
return qxl_drm_freeze(drm_dev);
}
@@ -218,7 +253,7 @@ static int qxl_pm_restore(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
- struct qxl_device *qdev = drm_dev->dev_private;
+ struct qxl_device *qdev = to_qxl(drm_dev);
qxl_io_reset(qdev);
return qxl_drm_resume(drm_dev, false);
@@ -237,58 +272,43 @@ static struct pci_driver qxl_pci_driver = {
.id_table = pciidlist,
.probe = qxl_pci_probe,
.remove = qxl_pci_remove,
+ .shutdown = qxl_pci_shutdown,
.driver.pm = &qxl_pm_ops,
};
+static const struct drm_ioctl_desc qxl_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(QXL_ALLOC, qxl_alloc_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(QXL_MAP, qxl_map_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(QXL_EXECBUFFER, qxl_execbuffer_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(QXL_UPDATE_AREA, qxl_update_area_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(QXL_GETPARAM, qxl_getparam_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(QXL_CLIENTCAP, qxl_clientcap_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF_DRV(QXL_ALLOC_SURF, qxl_alloc_surf_ioctl, DRM_AUTH),
+};
+
static struct drm_driver qxl_driver = {
- .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
- DRIVER_ATOMIC,
+ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_CURSOR_HOTSPOT,
.dumb_create = qxl_mode_dumb_create,
- .dumb_map_offset = qxl_mode_dumb_mmap,
+ .dumb_map_offset = drm_gem_ttm_dumb_map_offset,
#if defined(CONFIG_DEBUG_FS)
.debugfs_init = qxl_debugfs_init,
#endif
- .gem_prime_export = drm_gem_prime_export,
- .gem_prime_import = drm_gem_prime_import,
- .gem_prime_pin = qxl_gem_prime_pin,
- .gem_prime_unpin = qxl_gem_prime_unpin,
- .gem_prime_vmap = qxl_gem_prime_vmap,
- .gem_prime_vunmap = qxl_gem_prime_vunmap,
- .gem_prime_mmap = qxl_gem_prime_mmap,
- .gem_free_object_unlocked = qxl_gem_object_free,
- .gem_open_object = qxl_gem_object_open,
- .gem_close_object = qxl_gem_object_close,
+ .gem_prime_import_sg_table = qxl_gem_prime_import_sg_table,
+ DRM_FBDEV_TTM_DRIVER_OPS,
.fops = &qxl_fops,
.ioctls = qxl_ioctls,
- .irq_handler = qxl_irq_handler,
+ .num_ioctls = ARRAY_SIZE(qxl_ioctls),
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
- .date = DRIVER_DATE,
.major = 0,
.minor = 1,
.patchlevel = 0,
-};
-static int __init qxl_init(void)
-{
- if (vgacon_text_force() && qxl_modeset == -1)
- return -EINVAL;
-
- if (qxl_modeset == 0)
- return -EINVAL;
- qxl_driver.num_ioctls = qxl_max_ioctls;
- return pci_register_driver(&qxl_pci_driver);
-}
-
-static void __exit qxl_exit(void)
-{
- pci_unregister_driver(&qxl_pci_driver);
-}
+ .release = qxl_drm_release,
+};
-module_init(qxl_init);
-module_exit(qxl_exit);
+drm_module_pci_driver_if_modeset(qxl_pci_driver, qxl_modeset);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);