qxl_drv.c revision b0e898ac555e96e7863a5ee95d70f3625f1db5e2
1a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek/* vim: set ts=8 sw=8 tw=78 ai noexpandtab */ 2ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek/* qxl_drv.c -- QXL driver -*- linux-c -*- 3ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek * 4a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * Copyright 2011 Red Hat, Inc. 5a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * All Rights Reserved. 6a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * 7a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * Permission is hereby granted, free of charge, to any person obtaining a 8a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * copy of this software and associated documentation files (the "Software"), 9a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * to deal in the Software without restriction, including without limitation 10a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * and/or sell copies of the Software, and to permit persons to whom the 12a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * Software is furnished to do so, subject to the following conditions: 13a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * 14a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * The above copyright notice and this permission notice (including the next 15a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * paragraph) shall be included in all copies or substantial portions of the 16a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * Software. 17a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * 18a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * OTHER DEALINGS IN THE SOFTWARE. 25a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * 26a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * Authors: 27a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * Dave Airlie <airlie@redhat.com> 28a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek * Alon Levy <alevy@redhat.com> 29a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek */ 30a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 31a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek#include <linux/module.h> 32a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek#include <linux/console.h> 33a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 34a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek#include "drmP.h" 35a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek#include "drm/drm.h" 36a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek#include "drm_crtc_helper.h" 37a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek#include "qxl_drv.h" 38a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek#include "qxl_object.h" 39a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 40a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekextern int qxl_max_ioctls; 41a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic DEFINE_PCI_DEVICE_TABLE(pciidlist) = { 42a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek { 0x1b36, 0x100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 43a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 0xffff00, 0 }, 44ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek { 0x1b36, 0x100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_OTHER << 8, 45ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek 0xffff00, 0 }, 46a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek { 0, 0, 0 }, 47ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek}; 48ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert BuytenhekMODULE_DEVICE_TABLE(pci, pciidlist); 49ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek 50a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic int qxl_modeset = -1; 51a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekint qxl_num_crtc = 4; 52a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 53a66098daacee2f354dab311b58011e7076aa248cLennert BuytenhekMODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); 54a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekmodule_param_named(modeset, qxl_modeset, int, 0400); 55a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 56a66098daacee2f354dab311b58011e7076aa248cLennert BuytenhekMODULE_PARM_DESC(num_heads, "Number of virtual crtcs to expose (default 4)"); 57a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekmodule_param_named(num_heads, qxl_num_crtc, int, 0400); 58ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek 59ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhekstatic struct drm_driver qxl_driver; 60ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhekstatic struct pci_driver qxl_pci_driver; 61ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek 62a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic int 63a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekqxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 64a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek{ 65a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek if (pdev->revision < 4) { 66a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek DRM_ERROR("qxl too old, doesn't support client_monitors_config," 67a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek " use xf86-video-qxl in user mode"); 68a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek return -EINVAL; /* TODO: ENODEV ? */ 69ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek } 70ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek return drm_get_pci_dev(pdev, ent, &qxl_driver); 71ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek} 72ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek 73ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhekstatic void 74ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhekqxl_pci_remove(struct pci_dev *pdev) 75ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek{ 76ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek struct drm_device *dev = pci_get_drvdata(pdev); 77ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek 78ce9e2e1b8433c8795459a259ee87bc4e424e7c50Lennert Buytenhek drm_put_dev(dev); 79a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek} 80a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 81a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic const struct file_operations qxl_fops = { 82a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .owner = THIS_MODULE, 83a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .open = drm_open, 84a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .release = drm_release, 85a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .unlocked_ioctl = drm_ioctl, 86a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .poll = drm_poll, 87a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .mmap = qxl_mmap, 88a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek}; 89a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 90a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic int qxl_drm_freeze(struct drm_device *dev) 91a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek{ 92a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek struct pci_dev *pdev = dev->pdev; 93a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek struct qxl_device *qdev = dev->dev_private; 94a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek struct drm_crtc *crtc; 95a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 96a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek drm_kms_helper_poll_disable(dev); 97a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 98a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek console_lock(); 99a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek qxl_fbdev_set_suspend(qdev, 1); 100a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek console_unlock(); 101a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 102a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek /* unpin the front buffers */ 103a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 104a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 105a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek if (crtc->enabled) 106a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek (*crtc_funcs->disable)(crtc); 107a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek } 108a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 109a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek qxl_destroy_monitors_object(qdev); 110a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek qxl_surf_evict(qdev); 111a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek qxl_vram_evict(qdev); 112a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 113a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek while (!qxl_check_idle(qdev->command_ring)); 114a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek while (!qxl_check_idle(qdev->release_ring)) 115a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek qxl_queue_garbage_collect(qdev, 1); 116a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 117a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek pci_save_state(pdev); 118a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 119a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek return 0; 120a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek} 121a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 122a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic int qxl_drm_resume(struct drm_device *dev, bool thaw) 123a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek{ 12476266b2ad38c33fb2c1475cfeb35ed070adaba2bLennert Buytenhek struct qxl_device *qdev = dev->dev_private; 125a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 126a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek qdev->ram_header->int_mask = QXL_INTERRUPT_MASK; 127a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek if (!thaw) { 128a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek qxl_reinit_memslots(qdev); 129a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek qxl_ring_init_hdr(qdev->release_ring); 130a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek } 131a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 132a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek qxl_create_monitors_object(qdev); 133a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek drm_helper_resume_force_mode(dev); 134a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 135a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek console_lock(); 136a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek qxl_fbdev_set_suspend(qdev, 0); 137a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek console_unlock(); 138a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 139a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek drm_kms_helper_poll_enable(dev); 140a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek return 0; 141a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek} 142a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 143a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic int qxl_pm_suspend(struct device *dev) 144a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek{ 145a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek struct pci_dev *pdev = to_pci_dev(dev); 146a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek struct drm_device *drm_dev = pci_get_drvdata(pdev); 147618952a7b19b796fce98364fb26551cbe3e16a75Lennert Buytenhek int error; 148618952a7b19b796fce98364fb26551cbe3e16a75Lennert Buytenhek 149618952a7b19b796fce98364fb26551cbe3e16a75Lennert Buytenhek error = qxl_drm_freeze(drm_dev); 150618952a7b19b796fce98364fb26551cbe3e16a75Lennert Buytenhek if (error) 151618952a7b19b796fce98364fb26551cbe3e16a75Lennert Buytenhek return error; 152618952a7b19b796fce98364fb26551cbe3e16a75Lennert Buytenhek 153618952a7b19b796fce98364fb26551cbe3e16a75Lennert Buytenhek pci_disable_device(pdev); 154a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek pci_set_power_state(pdev, PCI_D3hot); 155a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek return 0; 156a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek} 157a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 158a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic int qxl_pm_resume(struct device *dev) 159a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek{ 160a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek struct pci_dev *pdev = to_pci_dev(dev); 161a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek struct drm_device *drm_dev = pci_get_drvdata(pdev); 162a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 163a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek pci_set_power_state(pdev, PCI_D0); 164a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek pci_restore_state(pdev); 165a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek if (pci_enable_device(pdev)) { 166a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek return -EIO; 167a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek } 168a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 169a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek return qxl_drm_resume(drm_dev, false); 170a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek} 171a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 172a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic int qxl_pm_thaw(struct device *dev) 173a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek{ 174a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek struct pci_dev *pdev = to_pci_dev(dev); 175a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek struct drm_device *drm_dev = pci_get_drvdata(pdev); 176a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 177a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek return qxl_drm_resume(drm_dev, true); 178a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek} 179a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 180a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic int qxl_pm_freeze(struct device *dev) 181a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek{ 182a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek struct pci_dev *pdev = to_pci_dev(dev); 183c46563b714b09d44eec4d1fd8a0f53e79ddaa3aaLennert Buytenhek struct drm_device *drm_dev = pci_get_drvdata(pdev); 18468ce38845c23443b15e374fb7362916c1231278eLennert Buytenhek 1850439b1f55646ea944b0d58337f5065b79a1c1be0Lennert Buytenhek return qxl_drm_freeze(drm_dev); 186a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek} 187a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 188a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic int qxl_pm_restore(struct device *dev) 189d89173f25228b8795af2d4b53e985cc44c729332Lennert Buytenhek{ 190a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek struct pci_dev *pdev = to_pci_dev(dev); 191a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek struct drm_device *drm_dev = pci_get_drvdata(pdev); 192a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek struct qxl_device *qdev = drm_dev->dev_private; 193a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 194a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek qxl_io_reset(qdev); 195a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek return qxl_drm_resume(drm_dev, false); 196a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek} 197a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 198a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic const struct dev_pm_ops qxl_pm_ops = { 199a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .suspend = qxl_pm_suspend, 200a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .resume = qxl_pm_resume, 201a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .freeze = qxl_pm_freeze, 202a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .thaw = qxl_pm_thaw, 203a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .poweroff = qxl_pm_freeze, 204a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .restore = qxl_pm_restore, 205a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek}; 206a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic struct pci_driver qxl_pci_driver = { 207a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .name = DRIVER_NAME, 208a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .id_table = pciidlist, 209a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .probe = qxl_pci_probe, 210a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .remove = qxl_pci_remove, 211a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .driver.pm = &qxl_pm_ops, 212a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek}; 213a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 214a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic struct drm_driver qxl_driver = { 215a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .driver_features = DRIVER_GEM | DRIVER_MODESET | 216d89173f25228b8795af2d4b53e985cc44c729332Lennert Buytenhek DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, 217d89173f25228b8795af2d4b53e985cc44c729332Lennert Buytenhek .dev_priv_size = 0, 218a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .load = qxl_driver_load, 219a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .unload = qxl_driver_unload, 220a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 221a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .dumb_create = qxl_mode_dumb_create, 222a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .dumb_map_offset = qxl_mode_dumb_mmap, 223a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .dumb_destroy = drm_gem_dumb_destroy, 224a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek#if defined(CONFIG_DEBUG_FS) 225a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .debugfs_init = qxl_debugfs_init, 226a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .debugfs_cleanup = qxl_debugfs_takedown, 227a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek#endif 228a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .gem_init_object = qxl_gem_object_init, 229a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .gem_free_object = qxl_gem_object_free, 230a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .gem_open_object = qxl_gem_object_open, 231a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .gem_close_object = qxl_gem_object_close, 232a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .fops = &qxl_fops, 233a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .ioctls = qxl_ioctls, 234a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .irq_handler = qxl_irq_handler, 235a94cc97e14c5750ec2b50b2e4ecdfb0f369ed0f4Lennert Buytenhek .name = DRIVER_NAME, 236a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .desc = DRIVER_DESC, 237a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .date = DRIVER_DATE, 238a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .major = 0, 239a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .minor = 1, 240a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek .patchlevel = 0, 241a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek}; 242a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 243a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic int __init qxl_init(void) 244a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek{ 245a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek#ifdef CONFIG_VGA_CONSOLE 246a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek if (vgacon_text_force() && qxl_modeset == -1) 247a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek return -EINVAL; 248a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek#endif 249a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 250a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek if (qxl_modeset == 0) 251a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek return -EINVAL; 252a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek qxl_driver.num_ioctls = qxl_max_ioctls; 253a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek return drm_pci_init(&qxl_driver, &qxl_pci_driver); 254a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek} 255a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 256a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekstatic void __exit qxl_exit(void) 257a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek{ 258a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek drm_pci_exit(&qxl_driver, &qxl_pci_driver); 259a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek} 260a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 261a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekmodule_init(qxl_init); 262a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhekmodule_exit(qxl_exit); 263a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek 264a66098daacee2f354dab311b58011e7076aa248cLennert BuytenhekMODULE_AUTHOR(DRIVER_AUTHOR); 265a66098daacee2f354dab311b58011e7076aa248cLennert BuytenhekMODULE_DESCRIPTION(DRIVER_DESC); 266a66098daacee2f354dab311b58011e7076aa248cLennert BuytenhekMODULE_LICENSE("GPL and additional rights"); 267a66098daacee2f354dab311b58011e7076aa248cLennert Buytenhek