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 v4.9 185 lines 4.5 kB view raw
1/* 2 * Copyright 2012 Red Hat <mjg@redhat.com> 3 * 4 * This file is subject to the terms and conditions of the GNU General 5 * Public License version 2. See the file COPYING in the main 6 * directory of this archive for more details. 7 * 8 * Authors: Matthew Garrett 9 * Dave Airlie 10 */ 11#include <linux/module.h> 12#include <linux/console.h> 13#include <drm/drmP.h> 14#include <drm/drm_crtc_helper.h> 15 16#include "cirrus_drv.h" 17 18int cirrus_modeset = -1; 19int cirrus_bpp = 24; 20 21MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); 22module_param_named(modeset, cirrus_modeset, int, 0400); 23MODULE_PARM_DESC(bpp, "Max bits-per-pixel (default:24)"); 24module_param_named(bpp, cirrus_bpp, int, 0400); 25 26/* 27 * This is the generic driver code. This binds the driver to the drm core, 28 * which then performs further device association and calls our graphics init 29 * functions 30 */ 31 32static struct drm_driver driver; 33 34/* only bind to the cirrus chip in qemu */ 35static const struct pci_device_id pciidlist[] = { 36 { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, 37 PCI_SUBVENDOR_ID_REDHAT_QUMRANET, PCI_SUBDEVICE_ID_QEMU, 38 0, 0, 0 }, 39 { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, PCI_VENDOR_ID_XEN, 40 0x0001, 0, 0, 0 }, 41 {0,} 42}; 43 44 45static int cirrus_kick_out_firmware_fb(struct pci_dev *pdev) 46{ 47 struct apertures_struct *ap; 48 bool primary = false; 49 50 ap = alloc_apertures(1); 51 if (!ap) 52 return -ENOMEM; 53 54 ap->ranges[0].base = pci_resource_start(pdev, 0); 55 ap->ranges[0].size = pci_resource_len(pdev, 0); 56 57#ifdef CONFIG_X86 58 primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; 59#endif 60 drm_fb_helper_remove_conflicting_framebuffers(ap, "cirrusdrmfb", primary); 61 kfree(ap); 62 63 return 0; 64} 65 66static int cirrus_pci_probe(struct pci_dev *pdev, 67 const struct pci_device_id *ent) 68{ 69 int ret; 70 71 ret = cirrus_kick_out_firmware_fb(pdev); 72 if (ret) 73 return ret; 74 75 return drm_get_pci_dev(pdev, ent, &driver); 76} 77 78static void cirrus_pci_remove(struct pci_dev *pdev) 79{ 80 struct drm_device *dev = pci_get_drvdata(pdev); 81 82 drm_put_dev(dev); 83} 84 85#ifdef CONFIG_PM_SLEEP 86static int cirrus_pm_suspend(struct device *dev) 87{ 88 struct pci_dev *pdev = to_pci_dev(dev); 89 struct drm_device *drm_dev = pci_get_drvdata(pdev); 90 struct cirrus_device *cdev = drm_dev->dev_private; 91 92 drm_kms_helper_poll_disable(drm_dev); 93 94 if (cdev->mode_info.gfbdev) { 95 console_lock(); 96 drm_fb_helper_set_suspend(&cdev->mode_info.gfbdev->helper, 1); 97 console_unlock(); 98 } 99 100 return 0; 101} 102 103static int cirrus_pm_resume(struct device *dev) 104{ 105 struct pci_dev *pdev = to_pci_dev(dev); 106 struct drm_device *drm_dev = pci_get_drvdata(pdev); 107 struct cirrus_device *cdev = drm_dev->dev_private; 108 109 drm_helper_resume_force_mode(drm_dev); 110 111 if (cdev->mode_info.gfbdev) { 112 console_lock(); 113 drm_fb_helper_set_suspend(&cdev->mode_info.gfbdev->helper, 0); 114 console_unlock(); 115 } 116 117 drm_kms_helper_poll_enable(drm_dev); 118 return 0; 119} 120#endif 121 122static const struct file_operations cirrus_driver_fops = { 123 .owner = THIS_MODULE, 124 .open = drm_open, 125 .release = drm_release, 126 .unlocked_ioctl = drm_ioctl, 127 .mmap = cirrus_mmap, 128 .poll = drm_poll, 129#ifdef CONFIG_COMPAT 130 .compat_ioctl = drm_compat_ioctl, 131#endif 132}; 133static struct drm_driver driver = { 134 .driver_features = DRIVER_MODESET | DRIVER_GEM, 135 .load = cirrus_driver_load, 136 .unload = cirrus_driver_unload, 137 .set_busid = drm_pci_set_busid, 138 .fops = &cirrus_driver_fops, 139 .name = DRIVER_NAME, 140 .desc = DRIVER_DESC, 141 .date = DRIVER_DATE, 142 .major = DRIVER_MAJOR, 143 .minor = DRIVER_MINOR, 144 .patchlevel = DRIVER_PATCHLEVEL, 145 .gem_free_object_unlocked = cirrus_gem_free_object, 146 .dumb_create = cirrus_dumb_create, 147 .dumb_map_offset = cirrus_dumb_mmap_offset, 148 .dumb_destroy = drm_gem_dumb_destroy, 149}; 150 151static const struct dev_pm_ops cirrus_pm_ops = { 152 SET_SYSTEM_SLEEP_PM_OPS(cirrus_pm_suspend, 153 cirrus_pm_resume) 154}; 155 156static struct pci_driver cirrus_pci_driver = { 157 .name = DRIVER_NAME, 158 .id_table = pciidlist, 159 .probe = cirrus_pci_probe, 160 .remove = cirrus_pci_remove, 161 .driver.pm = &cirrus_pm_ops, 162}; 163 164static int __init cirrus_init(void) 165{ 166 if (vgacon_text_force() && cirrus_modeset == -1) 167 return -EINVAL; 168 169 if (cirrus_modeset == 0) 170 return -EINVAL; 171 return drm_pci_init(&driver, &cirrus_pci_driver); 172} 173 174static void __exit cirrus_exit(void) 175{ 176 drm_pci_exit(&driver, &cirrus_pci_driver); 177} 178 179module_init(cirrus_init); 180module_exit(cirrus_exit); 181 182MODULE_DEVICE_TABLE(pci, pciidlist); 183MODULE_AUTHOR(DRIVER_AUTHOR); 184MODULE_DESCRIPTION(DRIVER_DESC); 185MODULE_LICENSE("GPL");