]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/bochs/bochs_drv.c
drm/bochs: drop use of drmP.h
[linux.git] / drivers / gpu / drm / bochs / bochs_drv.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  */
4
5 #include <linux/module.h>
6 #include <linux/pci.h>
7
8 #include <drm/drm_drv.h>
9 #include <drm/drm_atomic_helper.h>
10
11 #include "bochs.h"
12
13 static int bochs_modeset = -1;
14 module_param_named(modeset, bochs_modeset, int, 0444);
15 MODULE_PARM_DESC(modeset, "enable/disable kernel modesetting");
16
17 /* ---------------------------------------------------------------------- */
18 /* drm interface                                                          */
19
20 static void bochs_unload(struct drm_device *dev)
21 {
22         struct bochs_device *bochs = dev->dev_private;
23
24         bochs_kms_fini(bochs);
25         bochs_mm_fini(bochs);
26         bochs_hw_fini(dev);
27         kfree(bochs);
28         dev->dev_private = NULL;
29 }
30
31 static int bochs_load(struct drm_device *dev)
32 {
33         struct bochs_device *bochs;
34         int ret;
35
36         bochs = kzalloc(sizeof(*bochs), GFP_KERNEL);
37         if (bochs == NULL)
38                 return -ENOMEM;
39         dev->dev_private = bochs;
40         bochs->dev = dev;
41
42         ret = bochs_hw_init(dev);
43         if (ret)
44                 goto err;
45
46         ret = bochs_mm_init(bochs);
47         if (ret)
48                 goto err;
49
50         ret = bochs_kms_init(bochs);
51         if (ret)
52                 goto err;
53
54         return 0;
55
56 err:
57         bochs_unload(dev);
58         return ret;
59 }
60
61 static const struct file_operations bochs_fops = {
62         .owner          = THIS_MODULE,
63         DRM_VRAM_MM_FILE_OPERATIONS
64 };
65
66 static struct drm_driver bochs_driver = {
67         .driver_features        = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
68         .fops                   = &bochs_fops,
69         .name                   = "bochs-drm",
70         .desc                   = "bochs dispi vga interface (qemu stdvga)",
71         .date                   = "20130925",
72         .major                  = 1,
73         .minor                  = 0,
74         DRM_GEM_VRAM_DRIVER,
75 };
76
77 /* ---------------------------------------------------------------------- */
78 /* pm interface                                                           */
79
80 #ifdef CONFIG_PM_SLEEP
81 static int bochs_pm_suspend(struct device *dev)
82 {
83         struct pci_dev *pdev = to_pci_dev(dev);
84         struct drm_device *drm_dev = pci_get_drvdata(pdev);
85
86         return drm_mode_config_helper_suspend(drm_dev);
87 }
88
89 static int bochs_pm_resume(struct device *dev)
90 {
91         struct pci_dev *pdev = to_pci_dev(dev);
92         struct drm_device *drm_dev = pci_get_drvdata(pdev);
93
94         return drm_mode_config_helper_resume(drm_dev);
95 }
96 #endif
97
98 static const struct dev_pm_ops bochs_pm_ops = {
99         SET_SYSTEM_SLEEP_PM_OPS(bochs_pm_suspend,
100                                 bochs_pm_resume)
101 };
102
103 /* ---------------------------------------------------------------------- */
104 /* pci interface                                                          */
105
106 static int bochs_pci_probe(struct pci_dev *pdev,
107                            const struct pci_device_id *ent)
108 {
109         struct drm_device *dev;
110         unsigned long fbsize;
111         int ret;
112
113         fbsize = pci_resource_len(pdev, 0);
114         if (fbsize < 4 * 1024 * 1024) {
115                 DRM_ERROR("less than 4 MB video memory, ignoring device\n");
116                 return -ENOMEM;
117         }
118
119         ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, 0, "bochsdrmfb");
120         if (ret)
121                 return ret;
122
123         dev = drm_dev_alloc(&bochs_driver, &pdev->dev);
124         if (IS_ERR(dev))
125                 return PTR_ERR(dev);
126
127         ret = pci_enable_device(pdev);
128         if (ret)
129                 goto err_free_dev;
130
131         dev->pdev = pdev;
132         pci_set_drvdata(pdev, dev);
133
134         ret = bochs_load(dev);
135         if (ret)
136                 goto err_free_dev;
137
138         ret = drm_dev_register(dev, 0);
139         if (ret)
140                 goto err_unload;
141
142         drm_fbdev_generic_setup(dev, 32);
143         return ret;
144
145 err_unload:
146         bochs_unload(dev);
147 err_free_dev:
148         drm_dev_put(dev);
149         return ret;
150 }
151
152 static void bochs_pci_remove(struct pci_dev *pdev)
153 {
154         struct drm_device *dev = pci_get_drvdata(pdev);
155
156         drm_atomic_helper_shutdown(dev);
157         drm_dev_unregister(dev);
158         bochs_unload(dev);
159         drm_dev_put(dev);
160 }
161
162 static const struct pci_device_id bochs_pci_tbl[] = {
163         {
164                 .vendor      = 0x1234,
165                 .device      = 0x1111,
166                 .subvendor   = PCI_SUBVENDOR_ID_REDHAT_QUMRANET,
167                 .subdevice   = PCI_SUBDEVICE_ID_QEMU,
168                 .driver_data = BOCHS_QEMU_STDVGA,
169         },
170         {
171                 .vendor      = 0x1234,
172                 .device      = 0x1111,
173                 .subvendor   = PCI_ANY_ID,
174                 .subdevice   = PCI_ANY_ID,
175                 .driver_data = BOCHS_UNKNOWN,
176         },
177         { /* end of list */ }
178 };
179
180 static struct pci_driver bochs_pci_driver = {
181         .name =         "bochs-drm",
182         .id_table =     bochs_pci_tbl,
183         .probe =        bochs_pci_probe,
184         .remove =       bochs_pci_remove,
185         .driver.pm =    &bochs_pm_ops,
186 };
187
188 /* ---------------------------------------------------------------------- */
189 /* module init/exit                                                       */
190
191 static int __init bochs_init(void)
192 {
193         if (vgacon_text_force() && bochs_modeset == -1)
194                 return -EINVAL;
195
196         if (bochs_modeset == 0)
197                 return -EINVAL;
198
199         return pci_register_driver(&bochs_pci_driver);
200 }
201
202 static void __exit bochs_exit(void)
203 {
204         pci_unregister_driver(&bochs_pci_driver);
205 }
206
207 module_init(bochs_init);
208 module_exit(bochs_exit);
209
210 MODULE_DEVICE_TABLE(pci, bochs_pci_tbl);
211 MODULE_AUTHOR("Gerd Hoffmann <kraxel@redhat.com>");
212 MODULE_LICENSE("GPL");