]> git.ipfire.org Git - thirdparty/kernel/stable.git/blob - drivers/gpu/drm/cirrus/cirrus_drv.c
drm/amd/display: Check hpd_gpio for NULL before accessing it
[thirdparty/kernel/stable.git] / drivers / gpu / drm / cirrus / cirrus_drv.c
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
18 int cirrus_modeset = -1;
19 int cirrus_bpp = 16;
20
21 MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
22 module_param_named(modeset, cirrus_modeset, int, 0400);
23 MODULE_PARM_DESC(bpp, "Max bits-per-pixel (default:16)");
24 module_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
32 static struct drm_driver driver;
33
34 /* only bind to the cirrus chip in qemu */
35 static 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
45 static int cirrus_pci_probe(struct pci_dev *pdev,
46 const struct pci_device_id *ent)
47 {
48 int ret;
49
50 ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, 0, "cirrusdrmfb");
51 if (ret)
52 return ret;
53
54 return drm_get_pci_dev(pdev, ent, &driver);
55 }
56
57 static void cirrus_pci_remove(struct pci_dev *pdev)
58 {
59 struct drm_device *dev = pci_get_drvdata(pdev);
60
61 drm_put_dev(dev);
62 }
63
64 #ifdef CONFIG_PM_SLEEP
65 static int cirrus_pm_suspend(struct device *dev)
66 {
67 struct pci_dev *pdev = to_pci_dev(dev);
68 struct drm_device *drm_dev = pci_get_drvdata(pdev);
69 struct cirrus_device *cdev = drm_dev->dev_private;
70
71 drm_kms_helper_poll_disable(drm_dev);
72
73 if (cdev->mode_info.gfbdev) {
74 console_lock();
75 drm_fb_helper_set_suspend(&cdev->mode_info.gfbdev->helper, 1);
76 console_unlock();
77 }
78
79 return 0;
80 }
81
82 static int cirrus_pm_resume(struct device *dev)
83 {
84 struct pci_dev *pdev = to_pci_dev(dev);
85 struct drm_device *drm_dev = pci_get_drvdata(pdev);
86 struct cirrus_device *cdev = drm_dev->dev_private;
87
88 drm_helper_resume_force_mode(drm_dev);
89
90 if (cdev->mode_info.gfbdev) {
91 console_lock();
92 drm_fb_helper_set_suspend(&cdev->mode_info.gfbdev->helper, 0);
93 console_unlock();
94 }
95
96 drm_kms_helper_poll_enable(drm_dev);
97 return 0;
98 }
99 #endif
100
101 static const struct file_operations cirrus_driver_fops = {
102 .owner = THIS_MODULE,
103 .open = drm_open,
104 .release = drm_release,
105 .unlocked_ioctl = drm_ioctl,
106 .mmap = cirrus_mmap,
107 .poll = drm_poll,
108 .compat_ioctl = drm_compat_ioctl,
109 };
110 static struct drm_driver driver = {
111 .driver_features = DRIVER_MODESET | DRIVER_GEM,
112 .load = cirrus_driver_load,
113 .unload = cirrus_driver_unload,
114 .fops = &cirrus_driver_fops,
115 .name = DRIVER_NAME,
116 .desc = DRIVER_DESC,
117 .date = DRIVER_DATE,
118 .major = DRIVER_MAJOR,
119 .minor = DRIVER_MINOR,
120 .patchlevel = DRIVER_PATCHLEVEL,
121 .gem_free_object_unlocked = cirrus_gem_free_object,
122 .dumb_create = cirrus_dumb_create,
123 .dumb_map_offset = cirrus_dumb_mmap_offset,
124 };
125
126 static const struct dev_pm_ops cirrus_pm_ops = {
127 SET_SYSTEM_SLEEP_PM_OPS(cirrus_pm_suspend,
128 cirrus_pm_resume)
129 };
130
131 static struct pci_driver cirrus_pci_driver = {
132 .name = DRIVER_NAME,
133 .id_table = pciidlist,
134 .probe = cirrus_pci_probe,
135 .remove = cirrus_pci_remove,
136 .driver.pm = &cirrus_pm_ops,
137 };
138
139 static int __init cirrus_init(void)
140 {
141 if (vgacon_text_force() && cirrus_modeset == -1)
142 return -EINVAL;
143
144 if (cirrus_modeset == 0)
145 return -EINVAL;
146 return pci_register_driver(&cirrus_pci_driver);
147 }
148
149 static void __exit cirrus_exit(void)
150 {
151 pci_unregister_driver(&cirrus_pci_driver);
152 }
153
154 module_init(cirrus_init);
155 module_exit(cirrus_exit);
156
157 MODULE_DEVICE_TABLE(pci, pciidlist);
158 MODULE_AUTHOR(DRIVER_AUTHOR);
159 MODULE_DESCRIPTION(DRIVER_DESC);
160 MODULE_LICENSE("GPL");