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.10 183 lines 4.4 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 .compat_ioctl = drm_compat_ioctl, 130}; 131static struct drm_driver driver = { 132 .driver_features = DRIVER_MODESET | DRIVER_GEM, 133 .load = cirrus_driver_load, 134 .unload = cirrus_driver_unload, 135 .set_busid = drm_pci_set_busid, 136 .fops = &cirrus_driver_fops, 137 .name = DRIVER_NAME, 138 .desc = DRIVER_DESC, 139 .date = DRIVER_DATE, 140 .major = DRIVER_MAJOR, 141 .minor = DRIVER_MINOR, 142 .patchlevel = DRIVER_PATCHLEVEL, 143 .gem_free_object_unlocked = cirrus_gem_free_object, 144 .dumb_create = cirrus_dumb_create, 145 .dumb_map_offset = cirrus_dumb_mmap_offset, 146 .dumb_destroy = drm_gem_dumb_destroy, 147}; 148 149static const struct dev_pm_ops cirrus_pm_ops = { 150 SET_SYSTEM_SLEEP_PM_OPS(cirrus_pm_suspend, 151 cirrus_pm_resume) 152}; 153 154static struct pci_driver cirrus_pci_driver = { 155 .name = DRIVER_NAME, 156 .id_table = pciidlist, 157 .probe = cirrus_pci_probe, 158 .remove = cirrus_pci_remove, 159 .driver.pm = &cirrus_pm_ops, 160}; 161 162static int __init cirrus_init(void) 163{ 164 if (vgacon_text_force() && cirrus_modeset == -1) 165 return -EINVAL; 166 167 if (cirrus_modeset == 0) 168 return -EINVAL; 169 return drm_pci_init(&driver, &cirrus_pci_driver); 170} 171 172static void __exit cirrus_exit(void) 173{ 174 drm_pci_exit(&driver, &cirrus_pci_driver); 175} 176 177module_init(cirrus_init); 178module_exit(cirrus_exit); 179 180MODULE_DEVICE_TABLE(pci, pciidlist); 181MODULE_AUTHOR(DRIVER_AUTHOR); 182MODULE_DESCRIPTION(DRIVER_DESC); 183MODULE_LICENSE("GPL");