xref: /OK3568_Linux_fs/external/xserver/hw/xfree86/common/xf86platformBus.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright © 2012 Red Hat.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining a
5*4882a593Smuzhiyun  * copy of this software and associated documentation files (the "Software"),
6*4882a593Smuzhiyun  * to deal in the Software without restriction, including without limitation
7*4882a593Smuzhiyun  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*4882a593Smuzhiyun  * and/or sell copies of the Software, and to permit persons to whom the
9*4882a593Smuzhiyun  * Software is furnished to do so, subject to the following conditions:
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  * The above copyright notice and this permission notice shall be included in
12*4882a593Smuzhiyun  * all copies or substantial portions of the Software.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*4882a593Smuzhiyun  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17*4882a593Smuzhiyun  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18*4882a593Smuzhiyun  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19*4882a593Smuzhiyun  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20*4882a593Smuzhiyun  * DEALINGS IN THE SOFTWARE.
21*4882a593Smuzhiyun  *
22*4882a593Smuzhiyun  * Author: Dave Airlie <airlied@redhat.com>
23*4882a593Smuzhiyun  */
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun /*
26*4882a593Smuzhiyun  * This file contains the interfaces to the bus-specific code
27*4882a593Smuzhiyun  */
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #ifdef HAVE_XORG_CONFIG_H
30*4882a593Smuzhiyun #include <xorg-config.h>
31*4882a593Smuzhiyun #endif
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #ifdef XSERVER_PLATFORM_BUS
34*4882a593Smuzhiyun #include <errno.h>
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #include <pciaccess.h>
37*4882a593Smuzhiyun #include <fcntl.h>
38*4882a593Smuzhiyun #include <unistd.h>
39*4882a593Smuzhiyun #include "os.h"
40*4882a593Smuzhiyun #include "hotplug.h"
41*4882a593Smuzhiyun #include "systemd-logind.h"
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun #include "loaderProcs.h"
44*4882a593Smuzhiyun #include "xf86.h"
45*4882a593Smuzhiyun #include "xf86_OSproc.h"
46*4882a593Smuzhiyun #include "xf86Priv.h"
47*4882a593Smuzhiyun #include "xf86str.h"
48*4882a593Smuzhiyun #include "xf86Bus.h"
49*4882a593Smuzhiyun #include "Pci.h"
50*4882a593Smuzhiyun #include "xf86platformBus.h"
51*4882a593Smuzhiyun #include "xf86Config.h"
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun #include "randrstr.h"
54*4882a593Smuzhiyun int platformSlotClaimed;
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun int xf86_num_platform_devices;
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun struct xf86_platform_device *xf86_platform_devices;
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun int
xf86_add_platform_device(struct OdevAttributes * attribs,Bool unowned)61*4882a593Smuzhiyun xf86_add_platform_device(struct OdevAttributes *attribs, Bool unowned)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun     xf86_platform_devices = xnfreallocarray(xf86_platform_devices,
64*4882a593Smuzhiyun                                             xf86_num_platform_devices + 1,
65*4882a593Smuzhiyun                                             sizeof(struct xf86_platform_device));
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun     xf86_platform_devices[xf86_num_platform_devices].attribs = attribs;
68*4882a593Smuzhiyun     xf86_platform_devices[xf86_num_platform_devices].pdev = NULL;
69*4882a593Smuzhiyun     xf86_platform_devices[xf86_num_platform_devices].flags =
70*4882a593Smuzhiyun         unowned ? XF86_PDEV_UNOWNED : 0;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun     xf86_num_platform_devices++;
73*4882a593Smuzhiyun     return 0;
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun int
xf86_remove_platform_device(int dev_index)77*4882a593Smuzhiyun xf86_remove_platform_device(int dev_index)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun     int j;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun     config_odev_free_attributes(xf86_platform_devices[dev_index].attribs);
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun     for (j = dev_index; j < xf86_num_platform_devices - 1; j++)
84*4882a593Smuzhiyun         memcpy(&xf86_platform_devices[j], &xf86_platform_devices[j + 1], sizeof(struct xf86_platform_device));
85*4882a593Smuzhiyun     xf86_num_platform_devices--;
86*4882a593Smuzhiyun     return 0;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun Bool
xf86_get_platform_device_unowned(int index)90*4882a593Smuzhiyun xf86_get_platform_device_unowned(int index)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun     return (xf86_platform_devices[index].flags & XF86_PDEV_UNOWNED) ?
93*4882a593Smuzhiyun         TRUE : FALSE;
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun struct xf86_platform_device *
xf86_find_platform_device_by_devnum(int major,int minor)97*4882a593Smuzhiyun xf86_find_platform_device_by_devnum(int major, int minor)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun     int i, attr_major, attr_minor;
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun     for (i = 0; i < xf86_num_platform_devices; i++) {
102*4882a593Smuzhiyun         attr_major = xf86_platform_odev_attributes(i)->major;
103*4882a593Smuzhiyun         attr_minor = xf86_platform_odev_attributes(i)->minor;
104*4882a593Smuzhiyun         if (attr_major == major && attr_minor == minor)
105*4882a593Smuzhiyun             return &xf86_platform_devices[i];
106*4882a593Smuzhiyun     }
107*4882a593Smuzhiyun     return NULL;
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun /*
111*4882a593Smuzhiyun  * xf86IsPrimaryPlatform() -- return TRUE if primary device
112*4882a593Smuzhiyun  * is a platform device and it matches this one.
113*4882a593Smuzhiyun  */
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun static Bool
xf86IsPrimaryPlatform(struct xf86_platform_device * plat)116*4882a593Smuzhiyun xf86IsPrimaryPlatform(struct xf86_platform_device *plat)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun     /* Add max. 1 screen for the IgnorePrimary fallback path */
119*4882a593Smuzhiyun     if (xf86ProbeIgnorePrimary && xf86NumScreens == 0)
120*4882a593Smuzhiyun         return TRUE;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun     if (primaryBus.type == BUS_PLATFORM)
123*4882a593Smuzhiyun         return plat == primaryBus.id.plat;
124*4882a593Smuzhiyun #ifdef XSERVER_LIBPCIACCESS
125*4882a593Smuzhiyun     if (primaryBus.type == BUS_PCI)
126*4882a593Smuzhiyun         if (plat->pdev)
127*4882a593Smuzhiyun             if (MATCH_PCI_DEVICES(primaryBus.id.pci, plat->pdev))
128*4882a593Smuzhiyun                 return TRUE;
129*4882a593Smuzhiyun #endif
130*4882a593Smuzhiyun     return FALSE;
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun static void
platform_find_pci_info(struct xf86_platform_device * pd,char * busid)134*4882a593Smuzhiyun platform_find_pci_info(struct xf86_platform_device *pd, char *busid)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun     struct pci_slot_match devmatch;
137*4882a593Smuzhiyun     struct pci_device *info;
138*4882a593Smuzhiyun     struct pci_device_iterator *iter;
139*4882a593Smuzhiyun     int ret;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun     ret = sscanf(busid, "pci:%04x:%02x:%02x.%u",
142*4882a593Smuzhiyun                  &devmatch.domain, &devmatch.bus, &devmatch.dev,
143*4882a593Smuzhiyun                  &devmatch.func);
144*4882a593Smuzhiyun     if (ret != 4)
145*4882a593Smuzhiyun         return;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun     iter = pci_slot_match_iterator_create(&devmatch);
148*4882a593Smuzhiyun     info = pci_device_next(iter);
149*4882a593Smuzhiyun     if (info)
150*4882a593Smuzhiyun         pd->pdev = info;
151*4882a593Smuzhiyun     pci_iterator_destroy(iter);
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun static Bool
xf86_check_platform_slot(const struct xf86_platform_device * pd)155*4882a593Smuzhiyun xf86_check_platform_slot(const struct xf86_platform_device *pd)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun     int i;
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun     for (i = 0; i < xf86NumEntities; i++) {
160*4882a593Smuzhiyun         const EntityPtr u = xf86Entities[i];
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun         if (pd->pdev && u->bus.type == BUS_PCI &&
163*4882a593Smuzhiyun             MATCH_PCI_DEVICES(pd->pdev, u->bus.id.pci)) {
164*4882a593Smuzhiyun             return FALSE;
165*4882a593Smuzhiyun         }
166*4882a593Smuzhiyun         if ((u->bus.type == BUS_PLATFORM) && (pd == u->bus.id.plat)) {
167*4882a593Smuzhiyun             return FALSE;
168*4882a593Smuzhiyun         }
169*4882a593Smuzhiyun     }
170*4882a593Smuzhiyun     return TRUE;
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun static Bool
MatchToken(const char * value,struct xorg_list * patterns,int (* compare)(const char *,const char *))174*4882a593Smuzhiyun MatchToken(const char *value, struct xorg_list *patterns,
175*4882a593Smuzhiyun            int (*compare)(const char *, const char *))
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun     const xf86MatchGroup *group;
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun     /* If there are no patterns, accept the match */
180*4882a593Smuzhiyun     if (xorg_list_is_empty(patterns))
181*4882a593Smuzhiyun         return TRUE;
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun     /* If there are patterns but no attribute, reject the match */
184*4882a593Smuzhiyun     if (!value)
185*4882a593Smuzhiyun         return FALSE;
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun     /*
188*4882a593Smuzhiyun      * Otherwise, iterate the list of patterns ensuring each entry has a
189*4882a593Smuzhiyun      * match. Each list entry is a separate Match line of the same type.
190*4882a593Smuzhiyun      */
191*4882a593Smuzhiyun     xorg_list_for_each_entry(group, patterns, entry) {
192*4882a593Smuzhiyun         Bool match = FALSE;
193*4882a593Smuzhiyun         char *const *cur;
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun         for (cur = group->values; *cur; cur++) {
196*4882a593Smuzhiyun             if ((*compare)(value, *cur) == 0) {
197*4882a593Smuzhiyun                 match = TRUE;
198*4882a593Smuzhiyun                 break;
199*4882a593Smuzhiyun             }
200*4882a593Smuzhiyun         }
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun         if (!match)
203*4882a593Smuzhiyun             return FALSE;
204*4882a593Smuzhiyun     }
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun     /* All the entries in the list matched the attribute */
207*4882a593Smuzhiyun     return TRUE;
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun static Bool
OutputClassMatches(const XF86ConfOutputClassPtr oclass,struct xf86_platform_device * dev)211*4882a593Smuzhiyun OutputClassMatches(const XF86ConfOutputClassPtr oclass,
212*4882a593Smuzhiyun                    struct xf86_platform_device *dev)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun     char *driver = dev->attribs->driver;
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun     if (!MatchToken(driver, &oclass->match_driver, strcmp))
217*4882a593Smuzhiyun         return FALSE;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun     return TRUE;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun static void
xf86OutputClassDriverList(int index,XF86MatchedDrivers * md)223*4882a593Smuzhiyun xf86OutputClassDriverList(int index, XF86MatchedDrivers *md)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun     XF86ConfOutputClassPtr cl;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun     for (cl = xf86configptr->conf_outputclass_lst; cl; cl = cl->list.next) {
228*4882a593Smuzhiyun         if (OutputClassMatches(cl, &xf86_platform_devices[index])) {
229*4882a593Smuzhiyun             char *path = xf86_platform_odev_attributes(index)->path;
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun             xf86Msg(X_INFO, "Applying OutputClass \"%s\" to %s\n",
232*4882a593Smuzhiyun                     cl->identifier, path);
233*4882a593Smuzhiyun             xf86Msg(X_NONE, "\tloading driver: %s\n", cl->driver);
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun             xf86AddMatchedDriver(md, cl->driver);
236*4882a593Smuzhiyun         }
237*4882a593Smuzhiyun     }
238*4882a593Smuzhiyun }
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun /**
241*4882a593Smuzhiyun  *  @return The numbers of found devices that match with the current system
242*4882a593Smuzhiyun  *  drivers.
243*4882a593Smuzhiyun  */
244*4882a593Smuzhiyun void
xf86PlatformMatchDriver(XF86MatchedDrivers * md)245*4882a593Smuzhiyun xf86PlatformMatchDriver(XF86MatchedDrivers *md)
246*4882a593Smuzhiyun {
247*4882a593Smuzhiyun     int i;
248*4882a593Smuzhiyun     struct pci_device *info = NULL;
249*4882a593Smuzhiyun     int pass = 0;
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun     for (pass = 0; pass < 2; pass++) {
252*4882a593Smuzhiyun         for (i = 0; i < xf86_num_platform_devices; i++) {
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun             if (xf86IsPrimaryPlatform(&xf86_platform_devices[i]) && (pass == 1))
255*4882a593Smuzhiyun                 continue;
256*4882a593Smuzhiyun             else if (!xf86IsPrimaryPlatform(&xf86_platform_devices[i]) && (pass == 0))
257*4882a593Smuzhiyun                 continue;
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun             xf86OutputClassDriverList(i, md);
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun             info = xf86_platform_devices[i].pdev;
262*4882a593Smuzhiyun #ifdef __linux__
263*4882a593Smuzhiyun             if (info)
264*4882a593Smuzhiyun                 xf86MatchDriverFromFiles(info->vendor_id, info->device_id, md);
265*4882a593Smuzhiyun #endif
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun             if (info != NULL) {
268*4882a593Smuzhiyun                 xf86VideoPtrToDriverList(info, md);
269*4882a593Smuzhiyun             }
270*4882a593Smuzhiyun         }
271*4882a593Smuzhiyun     }
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun int
xf86platformProbe(void)275*4882a593Smuzhiyun xf86platformProbe(void)
276*4882a593Smuzhiyun {
277*4882a593Smuzhiyun     int i;
278*4882a593Smuzhiyun     Bool pci = TRUE;
279*4882a593Smuzhiyun     XF86ConfOutputClassPtr cl, cl_head = (xf86configptr) ?
280*4882a593Smuzhiyun             xf86configptr->conf_outputclass_lst : NULL;
281*4882a593Smuzhiyun     char *old_path, *path = NULL;
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun     config_odev_probe(xf86PlatformDeviceProbe);
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun     if (!xf86scanpci()) {
286*4882a593Smuzhiyun         pci = FALSE;
287*4882a593Smuzhiyun     }
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun     for (i = 0; i < xf86_num_platform_devices; i++) {
290*4882a593Smuzhiyun         char *busid = xf86_platform_odev_attributes(i)->busid;
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun         if (pci && (strncmp(busid, "pci:", 4) == 0)) {
293*4882a593Smuzhiyun             platform_find_pci_info(&xf86_platform_devices[i], busid);
294*4882a593Smuzhiyun         }
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun         /*
297*4882a593Smuzhiyun          * Deal with OutputClass ModulePath directives, these must be
298*4882a593Smuzhiyun          * processed before we do any module loading.
299*4882a593Smuzhiyun          */
300*4882a593Smuzhiyun         for (cl = cl_head; cl; cl = cl->list.next) {
301*4882a593Smuzhiyun             if (!OutputClassMatches(cl, &xf86_platform_devices[i]))
302*4882a593Smuzhiyun                 continue;
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun             if (cl->modulepath && xf86ModPathFrom != X_CMDLINE) {
305*4882a593Smuzhiyun                 old_path = path;
306*4882a593Smuzhiyun                 XNFasprintf(&path, "%s,%s", cl->modulepath,
307*4882a593Smuzhiyun                             path ? path : xf86ModulePath);
308*4882a593Smuzhiyun                 free(old_path);
309*4882a593Smuzhiyun                 xf86Msg(X_CONFIG, "OutputClass \"%s\" ModulePath extended to \"%s\"\n",
310*4882a593Smuzhiyun                         cl->identifier, path);
311*4882a593Smuzhiyun                 LoaderSetPath(path);
312*4882a593Smuzhiyun             }
313*4882a593Smuzhiyun         }
314*4882a593Smuzhiyun     }
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun     free(path);
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun     /* First see if there is an OutputClass match marking a device as primary */
319*4882a593Smuzhiyun     for (i = 0; i < xf86_num_platform_devices; i++) {
320*4882a593Smuzhiyun         struct xf86_platform_device *dev = &xf86_platform_devices[i];
321*4882a593Smuzhiyun         for (cl = cl_head; cl; cl = cl->list.next) {
322*4882a593Smuzhiyun             if (!OutputClassMatches(cl, dev))
323*4882a593Smuzhiyun                 continue;
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun             if (xf86CheckBoolOption(cl->option_lst, "PrimaryGPU", FALSE)) {
326*4882a593Smuzhiyun                 xf86Msg(X_CONFIG, "OutputClass \"%s\" setting %s as PrimaryGPU\n",
327*4882a593Smuzhiyun                         cl->identifier, dev->attribs->path);
328*4882a593Smuzhiyun                 primaryBus.type = BUS_PLATFORM;
329*4882a593Smuzhiyun                 primaryBus.id.plat = dev;
330*4882a593Smuzhiyun                 return 0;
331*4882a593Smuzhiyun             }
332*4882a593Smuzhiyun         }
333*4882a593Smuzhiyun     }
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun     /* Then check for pci_device_is_boot_vga() */
336*4882a593Smuzhiyun     for (i = 0; i < xf86_num_platform_devices; i++) {
337*4882a593Smuzhiyun         struct xf86_platform_device *dev = &xf86_platform_devices[i];
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun         if (!dev->pdev)
340*4882a593Smuzhiyun             continue;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun         pci_device_probe(dev->pdev);
343*4882a593Smuzhiyun         if (pci_device_is_boot_vga(dev->pdev)) {
344*4882a593Smuzhiyun             primaryBus.type = BUS_PLATFORM;
345*4882a593Smuzhiyun             primaryBus.id.plat = dev;
346*4882a593Smuzhiyun         }
347*4882a593Smuzhiyun     }
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun     return 0;
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun void
xf86MergeOutputClassOptions(int entityIndex,void ** options)353*4882a593Smuzhiyun xf86MergeOutputClassOptions(int entityIndex, void **options)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun     const EntityPtr entity = xf86Entities[entityIndex];
356*4882a593Smuzhiyun     struct xf86_platform_device *dev = NULL;
357*4882a593Smuzhiyun     XF86ConfOutputClassPtr cl;
358*4882a593Smuzhiyun     XF86OptionPtr classopts;
359*4882a593Smuzhiyun     int i = 0;
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun     switch (entity->bus.type) {
362*4882a593Smuzhiyun     case BUS_PLATFORM:
363*4882a593Smuzhiyun         dev = entity->bus.id.plat;
364*4882a593Smuzhiyun         break;
365*4882a593Smuzhiyun     case BUS_PCI:
366*4882a593Smuzhiyun         for (i = 0; i < xf86_num_platform_devices; i++) {
367*4882a593Smuzhiyun             if (MATCH_PCI_DEVICES(xf86_platform_devices[i].pdev,
368*4882a593Smuzhiyun                                   entity->bus.id.pci)) {
369*4882a593Smuzhiyun                 dev = &xf86_platform_devices[i];
370*4882a593Smuzhiyun                 break;
371*4882a593Smuzhiyun             }
372*4882a593Smuzhiyun         }
373*4882a593Smuzhiyun         break;
374*4882a593Smuzhiyun     default:
375*4882a593Smuzhiyun         xf86Msg(X_DEBUG, "xf86MergeOutputClassOptions unsupported bus type %d\n",
376*4882a593Smuzhiyun                 entity->bus.type);
377*4882a593Smuzhiyun     }
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun     if (!dev)
380*4882a593Smuzhiyun         return;
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun     for (cl = xf86configptr->conf_outputclass_lst; cl; cl = cl->list.next) {
383*4882a593Smuzhiyun         if (!OutputClassMatches(cl, dev) || !cl->option_lst)
384*4882a593Smuzhiyun             continue;
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun         xf86Msg(X_INFO, "Applying OutputClass \"%s\" options to %s\n",
387*4882a593Smuzhiyun                 cl->identifier, dev->attribs->path);
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun         classopts = xf86optionListDup(cl->option_lst);
390*4882a593Smuzhiyun         *options = xf86optionListMerge(*options, classopts);
391*4882a593Smuzhiyun     }
392*4882a593Smuzhiyun }
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun static int
xf86ClaimPlatformSlot(struct xf86_platform_device * d,DriverPtr drvp,int chipset,GDevPtr dev,Bool active)395*4882a593Smuzhiyun xf86ClaimPlatformSlot(struct xf86_platform_device * d, DriverPtr drvp,
396*4882a593Smuzhiyun                   int chipset, GDevPtr dev, Bool active)
397*4882a593Smuzhiyun {
398*4882a593Smuzhiyun     EntityPtr p = NULL;
399*4882a593Smuzhiyun     int num;
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun     if (xf86_check_platform_slot(d)) {
402*4882a593Smuzhiyun         num = xf86AllocateEntity();
403*4882a593Smuzhiyun         p = xf86Entities[num];
404*4882a593Smuzhiyun         p->driver = drvp;
405*4882a593Smuzhiyun         p->chipset = chipset;
406*4882a593Smuzhiyun         p->bus.type = BUS_PLATFORM;
407*4882a593Smuzhiyun         p->bus.id.plat = d;
408*4882a593Smuzhiyun         p->active = active;
409*4882a593Smuzhiyun         p->inUse = FALSE;
410*4882a593Smuzhiyun         if (dev)
411*4882a593Smuzhiyun             xf86AddDevToEntity(num, dev);
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun         platformSlotClaimed++;
414*4882a593Smuzhiyun         return num;
415*4882a593Smuzhiyun     }
416*4882a593Smuzhiyun     else
417*4882a593Smuzhiyun         return -1;
418*4882a593Smuzhiyun }
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun static int
xf86UnclaimPlatformSlot(struct xf86_platform_device * d,GDevPtr dev)421*4882a593Smuzhiyun xf86UnclaimPlatformSlot(struct xf86_platform_device *d, GDevPtr dev)
422*4882a593Smuzhiyun {
423*4882a593Smuzhiyun     int i;
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun     for (i = 0; i < xf86NumEntities; i++) {
426*4882a593Smuzhiyun         const EntityPtr p = xf86Entities[i];
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun         if ((p->bus.type == BUS_PLATFORM) && (p->bus.id.plat == d)) {
429*4882a593Smuzhiyun             if (dev)
430*4882a593Smuzhiyun                 xf86RemoveDevFromEntity(i, dev);
431*4882a593Smuzhiyun             platformSlotClaimed--;
432*4882a593Smuzhiyun             p->bus.type = BUS_NONE;
433*4882a593Smuzhiyun             return 0;
434*4882a593Smuzhiyun         }
435*4882a593Smuzhiyun     }
436*4882a593Smuzhiyun     return 0;
437*4882a593Smuzhiyun }
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun #define END_OF_MATCHES(m)                                               \
441*4882a593Smuzhiyun     (((m).vendor_id == 0) && ((m).device_id == 0) && ((m).subvendor_id == 0))
442*4882a593Smuzhiyun 
doPlatformProbe(struct xf86_platform_device * dev,DriverPtr drvp,GDevPtr gdev,int flags,intptr_t match_data)443*4882a593Smuzhiyun static Bool doPlatformProbe(struct xf86_platform_device *dev, DriverPtr drvp,
444*4882a593Smuzhiyun                             GDevPtr gdev, int flags, intptr_t match_data)
445*4882a593Smuzhiyun {
446*4882a593Smuzhiyun     Bool foundScreen = FALSE;
447*4882a593Smuzhiyun     int entity;
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun     if (gdev && gdev->screen == 0 && !xf86_check_platform_slot(dev))
450*4882a593Smuzhiyun         return FALSE;
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun     entity = xf86ClaimPlatformSlot(dev, drvp, 0,
453*4882a593Smuzhiyun                                    gdev, gdev ? gdev->active : 0);
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun     if ((entity == -1) && gdev && (gdev->screen > 0)) {
456*4882a593Smuzhiyun         unsigned nent;
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun         for (nent = 0; nent < xf86NumEntities; nent++) {
459*4882a593Smuzhiyun             EntityPtr pEnt = xf86Entities[nent];
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun             if (pEnt->bus.type != BUS_PLATFORM)
462*4882a593Smuzhiyun                 continue;
463*4882a593Smuzhiyun             if (pEnt->bus.id.plat == dev) {
464*4882a593Smuzhiyun                 entity = nent;
465*4882a593Smuzhiyun                 xf86AddDevToEntity(nent, gdev);
466*4882a593Smuzhiyun                 break;
467*4882a593Smuzhiyun             }
468*4882a593Smuzhiyun         }
469*4882a593Smuzhiyun     }
470*4882a593Smuzhiyun     if (entity != -1) {
471*4882a593Smuzhiyun         if ((dev->flags & XF86_PDEV_SERVER_FD) && (!drvp->driverFunc ||
472*4882a593Smuzhiyun                 !drvp->driverFunc(NULL, SUPPORTS_SERVER_FDS, NULL))) {
473*4882a593Smuzhiyun             systemd_logind_release_fd(dev->attribs->major, dev->attribs->minor, dev->attribs->fd);
474*4882a593Smuzhiyun             dev->attribs->fd = -1;
475*4882a593Smuzhiyun             dev->flags &= ~XF86_PDEV_SERVER_FD;
476*4882a593Smuzhiyun         }
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun         if (drvp->platformProbe(drvp, entity, flags, dev, match_data))
479*4882a593Smuzhiyun             foundScreen = TRUE;
480*4882a593Smuzhiyun         else
481*4882a593Smuzhiyun             xf86UnclaimPlatformSlot(dev, gdev);
482*4882a593Smuzhiyun     }
483*4882a593Smuzhiyun     return foundScreen;
484*4882a593Smuzhiyun }
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun static Bool
probeSingleDevice(struct xf86_platform_device * dev,DriverPtr drvp,GDevPtr gdev,int flags)487*4882a593Smuzhiyun probeSingleDevice(struct xf86_platform_device *dev, DriverPtr drvp, GDevPtr gdev, int flags)
488*4882a593Smuzhiyun {
489*4882a593Smuzhiyun     int k;
490*4882a593Smuzhiyun     Bool foundScreen = FALSE;
491*4882a593Smuzhiyun     struct pci_device *pPci;
492*4882a593Smuzhiyun     const struct pci_id_match *const devices = drvp->supported_devices;
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun     if (dev->pdev && devices) {
495*4882a593Smuzhiyun         int device_id = dev->pdev->device_id;
496*4882a593Smuzhiyun         pPci = dev->pdev;
497*4882a593Smuzhiyun         for (k = 0; !END_OF_MATCHES(devices[k]); k++) {
498*4882a593Smuzhiyun             if (PCI_ID_COMPARE(devices[k].vendor_id, pPci->vendor_id)
499*4882a593Smuzhiyun                 && PCI_ID_COMPARE(devices[k].device_id, device_id)
500*4882a593Smuzhiyun                 && ((devices[k].device_class_mask & pPci->device_class)
501*4882a593Smuzhiyun                     ==  devices[k].device_class)) {
502*4882a593Smuzhiyun                 foundScreen = doPlatformProbe(dev, drvp, gdev, flags, devices[k].match_data);
503*4882a593Smuzhiyun                 if (foundScreen)
504*4882a593Smuzhiyun                     break;
505*4882a593Smuzhiyun             }
506*4882a593Smuzhiyun         }
507*4882a593Smuzhiyun     }
508*4882a593Smuzhiyun     else if (dev->pdev && !devices)
509*4882a593Smuzhiyun         return FALSE;
510*4882a593Smuzhiyun     else
511*4882a593Smuzhiyun         foundScreen = doPlatformProbe(dev, drvp, gdev, flags, 0);
512*4882a593Smuzhiyun     return foundScreen;
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun static Bool
isGPUDevice(GDevPtr gdev)516*4882a593Smuzhiyun isGPUDevice(GDevPtr gdev)
517*4882a593Smuzhiyun {
518*4882a593Smuzhiyun     int i;
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun     for (i = 0; i < gdev->myScreenSection->num_gpu_devices; i++) {
521*4882a593Smuzhiyun         if (gdev == gdev->myScreenSection->gpu_devices[i])
522*4882a593Smuzhiyun             return TRUE;
523*4882a593Smuzhiyun     }
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun     return FALSE;
526*4882a593Smuzhiyun }
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun int
xf86platformProbeDev(DriverPtr drvp)529*4882a593Smuzhiyun xf86platformProbeDev(DriverPtr drvp)
530*4882a593Smuzhiyun {
531*4882a593Smuzhiyun     Bool foundScreen = FALSE;
532*4882a593Smuzhiyun     GDevPtr *devList;
533*4882a593Smuzhiyun     const unsigned numDevs = xf86MatchDevice(drvp->driverName, &devList);
534*4882a593Smuzhiyun     int i, j;
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun     /* find the main device or any device specificed in xorg.conf */
537*4882a593Smuzhiyun     for (i = 0; i < numDevs; i++) {
538*4882a593Smuzhiyun         const char *devpath;
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun         /* skip inactive devices */
541*4882a593Smuzhiyun         if (!devList[i]->active)
542*4882a593Smuzhiyun             continue;
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun         /* This is specific to modesetting. */
545*4882a593Smuzhiyun         devpath = xf86FindOptionValue(devList[i]->options, "kmsdev");
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun         for (j = 0; j < xf86_num_platform_devices; j++) {
548*4882a593Smuzhiyun             if (devpath && *devpath) {
549*4882a593Smuzhiyun                 if (strcmp(xf86_platform_devices[j].attribs->path, devpath) == 0)
550*4882a593Smuzhiyun                     break;
551*4882a593Smuzhiyun             } else if (devList[i]->busID && *devList[i]->busID) {
552*4882a593Smuzhiyun                 if (xf86PlatformDeviceCheckBusID(&xf86_platform_devices[j], devList[i]->busID))
553*4882a593Smuzhiyun                     break;
554*4882a593Smuzhiyun             }
555*4882a593Smuzhiyun             else {
556*4882a593Smuzhiyun                 /* for non-seat0 servers assume first device is the master */
557*4882a593Smuzhiyun                 if (ServerIsNotSeat0())
558*4882a593Smuzhiyun                     break;
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun                 if (xf86IsPrimaryPlatform(&xf86_platform_devices[j]))
561*4882a593Smuzhiyun                     break;
562*4882a593Smuzhiyun             }
563*4882a593Smuzhiyun         }
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun         if (j == xf86_num_platform_devices)
566*4882a593Smuzhiyun              continue;
567*4882a593Smuzhiyun 
568*4882a593Smuzhiyun         foundScreen = probeSingleDevice(&xf86_platform_devices[j], drvp, devList[i],
569*4882a593Smuzhiyun                                         isGPUDevice(devList[i]) ? PLATFORM_PROBE_GPU_SCREEN : 0);
570*4882a593Smuzhiyun     }
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun     free(devList);
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun     return foundScreen;
575*4882a593Smuzhiyun }
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun int
xf86platformAddGPUDevices(DriverPtr drvp)578*4882a593Smuzhiyun xf86platformAddGPUDevices(DriverPtr drvp)
579*4882a593Smuzhiyun {
580*4882a593Smuzhiyun     Bool foundScreen = FALSE;
581*4882a593Smuzhiyun     GDevPtr *devList;
582*4882a593Smuzhiyun     int j;
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun     if (!drvp->platformProbe)
585*4882a593Smuzhiyun         return FALSE;
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun     xf86MatchDevice(drvp->driverName, &devList);
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun     /* if autoaddgpu devices is enabled then go find any unclaimed platform
590*4882a593Smuzhiyun      * devices and add them as GPU screens */
591*4882a593Smuzhiyun     if (xf86Info.autoAddGPU) {
592*4882a593Smuzhiyun         for (j = 0; j < xf86_num_platform_devices; j++) {
593*4882a593Smuzhiyun             if (probeSingleDevice(&xf86_platform_devices[j], drvp,
594*4882a593Smuzhiyun                                   devList ?  devList[0] : NULL,
595*4882a593Smuzhiyun                                   PLATFORM_PROBE_GPU_SCREEN))
596*4882a593Smuzhiyun                 foundScreen = TRUE;
597*4882a593Smuzhiyun         }
598*4882a593Smuzhiyun     }
599*4882a593Smuzhiyun 
600*4882a593Smuzhiyun     free(devList);
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun     return foundScreen;
603*4882a593Smuzhiyun }
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun int
xf86platformAddDevice(int index)606*4882a593Smuzhiyun xf86platformAddDevice(int index)
607*4882a593Smuzhiyun {
608*4882a593Smuzhiyun     int i, old_screens, scr_index;
609*4882a593Smuzhiyun     DriverPtr drvp = NULL;
610*4882a593Smuzhiyun     screenLayoutPtr layout;
611*4882a593Smuzhiyun     static const char *hotplug_driver_name = "modesetting";
612*4882a593Smuzhiyun 
613*4882a593Smuzhiyun     if (!xf86Info.autoAddGPU)
614*4882a593Smuzhiyun         return -1;
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun     /* force load the driver for now */
617*4882a593Smuzhiyun     xf86LoadOneModule(hotplug_driver_name, NULL);
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun     for (i = 0; i < xf86NumDrivers; i++) {
620*4882a593Smuzhiyun         if (!xf86DriverList[i])
621*4882a593Smuzhiyun             continue;
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun         if (!strcmp(xf86DriverList[i]->driverName, hotplug_driver_name)) {
624*4882a593Smuzhiyun             drvp = xf86DriverList[i];
625*4882a593Smuzhiyun             break;
626*4882a593Smuzhiyun         }
627*4882a593Smuzhiyun     }
628*4882a593Smuzhiyun     if (i == xf86NumDrivers)
629*4882a593Smuzhiyun         return -1;
630*4882a593Smuzhiyun 
631*4882a593Smuzhiyun     old_screens = xf86NumGPUScreens;
632*4882a593Smuzhiyun     doPlatformProbe(&xf86_platform_devices[index], drvp, NULL,
633*4882a593Smuzhiyun                     PLATFORM_PROBE_GPU_SCREEN, 0);
634*4882a593Smuzhiyun     if (old_screens == xf86NumGPUScreens)
635*4882a593Smuzhiyun         return -1;
636*4882a593Smuzhiyun     i = old_screens;
637*4882a593Smuzhiyun 
638*4882a593Smuzhiyun     for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
639*4882a593Smuzhiyun          layout++) {
640*4882a593Smuzhiyun         xf86GPUScreens[i]->confScreen = layout->screen;
641*4882a593Smuzhiyun         break;
642*4882a593Smuzhiyun     }
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun     if (xf86GPUScreens[i]->PreInit &&
645*4882a593Smuzhiyun         xf86GPUScreens[i]->PreInit(xf86GPUScreens[i], 0))
646*4882a593Smuzhiyun         xf86GPUScreens[i]->configured = TRUE;
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun     if (!xf86GPUScreens[i]->configured) {
649*4882a593Smuzhiyun         ErrorF("hotplugged device %d didn't configure\n", i);
650*4882a593Smuzhiyun         xf86DeleteScreen(xf86GPUScreens[i]);
651*4882a593Smuzhiyun         return -1;
652*4882a593Smuzhiyun     }
653*4882a593Smuzhiyun 
654*4882a593Smuzhiyun    scr_index = AddGPUScreen(xf86GPUScreens[i]->ScreenInit, 0, NULL);
655*4882a593Smuzhiyun    if (scr_index == -1) {
656*4882a593Smuzhiyun        xf86DeleteScreen(xf86GPUScreens[i]);
657*4882a593Smuzhiyun        xf86UnclaimPlatformSlot(&xf86_platform_devices[index], NULL);
658*4882a593Smuzhiyun        xf86NumGPUScreens = old_screens;
659*4882a593Smuzhiyun        return -1;
660*4882a593Smuzhiyun    }
661*4882a593Smuzhiyun    dixSetPrivate(&xf86GPUScreens[i]->pScreen->devPrivates,
662*4882a593Smuzhiyun                  xf86ScreenKey, xf86GPUScreens[i]);
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun    CreateScratchPixmapsForScreen(xf86GPUScreens[i]->pScreen);
665*4882a593Smuzhiyun 
666*4882a593Smuzhiyun    if (xf86GPUScreens[i]->pScreen->CreateScreenResources &&
667*4882a593Smuzhiyun        !(*xf86GPUScreens[i]->pScreen->CreateScreenResources) (xf86GPUScreens[i]->pScreen)) {
668*4882a593Smuzhiyun        RemoveGPUScreen(xf86GPUScreens[i]->pScreen);
669*4882a593Smuzhiyun        xf86DeleteScreen(xf86GPUScreens[i]);
670*4882a593Smuzhiyun        xf86UnclaimPlatformSlot(&xf86_platform_devices[index], NULL);
671*4882a593Smuzhiyun        xf86NumGPUScreens = old_screens;
672*4882a593Smuzhiyun        return -1;
673*4882a593Smuzhiyun    }
674*4882a593Smuzhiyun    /* attach unbound to 0 protocol screen */
675*4882a593Smuzhiyun    AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen);
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun    RRResourcesChanged(xf86Screens[0]->pScreen);
678*4882a593Smuzhiyun    RRTellChanged(xf86Screens[0]->pScreen);
679*4882a593Smuzhiyun 
680*4882a593Smuzhiyun    return 0;
681*4882a593Smuzhiyun }
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun void
xf86platformRemoveDevice(int index)684*4882a593Smuzhiyun xf86platformRemoveDevice(int index)
685*4882a593Smuzhiyun {
686*4882a593Smuzhiyun     EntityPtr entity;
687*4882a593Smuzhiyun     int ent_num, i, j;
688*4882a593Smuzhiyun     Bool found;
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun     for (ent_num = 0; ent_num < xf86NumEntities; ent_num++) {
691*4882a593Smuzhiyun         entity = xf86Entities[ent_num];
692*4882a593Smuzhiyun         if (entity->bus.type == BUS_PLATFORM &&
693*4882a593Smuzhiyun             entity->bus.id.plat == &xf86_platform_devices[index])
694*4882a593Smuzhiyun             break;
695*4882a593Smuzhiyun     }
696*4882a593Smuzhiyun     if (ent_num == xf86NumEntities)
697*4882a593Smuzhiyun         goto out;
698*4882a593Smuzhiyun 
699*4882a593Smuzhiyun     found = FALSE;
700*4882a593Smuzhiyun     for (i = 0; i < xf86NumGPUScreens; i++) {
701*4882a593Smuzhiyun         for (j = 0; j < xf86GPUScreens[i]->numEntities; j++)
702*4882a593Smuzhiyun             if (xf86GPUScreens[i]->entityList[j] == ent_num) {
703*4882a593Smuzhiyun                 found = TRUE;
704*4882a593Smuzhiyun                 break;
705*4882a593Smuzhiyun             }
706*4882a593Smuzhiyun         if (found)
707*4882a593Smuzhiyun             break;
708*4882a593Smuzhiyun     }
709*4882a593Smuzhiyun     if (!found) {
710*4882a593Smuzhiyun         ErrorF("failed to find screen to remove\n");
711*4882a593Smuzhiyun         goto out;
712*4882a593Smuzhiyun     }
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun     xf86GPUScreens[i]->pScreen->CloseScreen(xf86GPUScreens[i]->pScreen);
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun     RemoveGPUScreen(xf86GPUScreens[i]->pScreen);
717*4882a593Smuzhiyun     xf86DeleteScreen(xf86GPUScreens[i]);
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun     xf86UnclaimPlatformSlot(&xf86_platform_devices[index], NULL);
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun     xf86_remove_platform_device(index);
722*4882a593Smuzhiyun 
723*4882a593Smuzhiyun     RRResourcesChanged(xf86Screens[0]->pScreen);
724*4882a593Smuzhiyun     RRTellChanged(xf86Screens[0]->pScreen);
725*4882a593Smuzhiyun  out:
726*4882a593Smuzhiyun     return;
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun /* called on return from VT switch to find any new devices */
xf86platformVTProbe(void)730*4882a593Smuzhiyun void xf86platformVTProbe(void)
731*4882a593Smuzhiyun {
732*4882a593Smuzhiyun     int i;
733*4882a593Smuzhiyun 
734*4882a593Smuzhiyun     for (i = 0; i < xf86_num_platform_devices; i++) {
735*4882a593Smuzhiyun         if (!(xf86_platform_devices[i].flags & XF86_PDEV_UNOWNED))
736*4882a593Smuzhiyun             continue;
737*4882a593Smuzhiyun 
738*4882a593Smuzhiyun         xf86_platform_devices[i].flags &= ~XF86_PDEV_UNOWNED;
739*4882a593Smuzhiyun         xf86PlatformReprobeDevice(i, xf86_platform_devices[i].attribs);
740*4882a593Smuzhiyun     }
741*4882a593Smuzhiyun }
742*4882a593Smuzhiyun 
xf86platformPrimary(void)743*4882a593Smuzhiyun void xf86platformPrimary(void)
744*4882a593Smuzhiyun {
745*4882a593Smuzhiyun     /* use the first platform device as a fallback */
746*4882a593Smuzhiyun     if (primaryBus.type == BUS_NONE) {
747*4882a593Smuzhiyun         xf86Msg(X_INFO, "no primary bus or device found\n");
748*4882a593Smuzhiyun 
749*4882a593Smuzhiyun         if (xf86_num_platform_devices > 0) {
750*4882a593Smuzhiyun             primaryBus.id.plat = &xf86_platform_devices[0];
751*4882a593Smuzhiyun             primaryBus.type = BUS_PLATFORM;
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun             xf86Msg(X_NONE, "\tfalling back to %s\n", primaryBus.id.plat->attribs->syspath);
754*4882a593Smuzhiyun         }
755*4882a593Smuzhiyun     }
756*4882a593Smuzhiyun }
757*4882a593Smuzhiyun #endif
758