xfree86: add platform bus hotplug support (v3)
This provides add/remove support for platform devices at xfree86 ddx level. v2: cleanup properly if no driver found. v3: load the modesetting driver before checking driver list. Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
b27cf30995
commit
ef6686480a
|
@ -376,4 +376,107 @@ xf86platformProbeDev(DriverPtr drvp)
|
||||||
return foundScreen;
|
return foundScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
xf86platformAddDevice(int index)
|
||||||
|
{
|
||||||
|
int i, old_screens, scr_index;
|
||||||
|
DriverPtr drvp = NULL;
|
||||||
|
int entity;
|
||||||
|
screenLayoutPtr layout;
|
||||||
|
static char *hotplug_driver_name = "modesetting";
|
||||||
|
|
||||||
|
/* force load the driver for now */
|
||||||
|
xf86LoadOneModule(hotplug_driver_name, NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < xf86NumDrivers; i++) {
|
||||||
|
if (!xf86DriverList[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!strcmp(xf86DriverList[i]->driverName, hotplug_driver_name)) {
|
||||||
|
drvp = xf86DriverList[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == xf86NumDrivers)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
old_screens = xf86NumGPUScreens;
|
||||||
|
entity = xf86ClaimPlatformSlot(&xf86_platform_devices[index],
|
||||||
|
drvp, 0, 0, 0);
|
||||||
|
if (!drvp->platformProbe(drvp, entity, PLATFORM_PROBE_GPU_SCREEN, &xf86_platform_devices[index], 0)) {
|
||||||
|
xf86UnclaimPlatformSlot(&xf86_platform_devices[index], NULL);
|
||||||
|
}
|
||||||
|
if (old_screens == xf86NumGPUScreens)
|
||||||
|
return -1;
|
||||||
|
i = old_screens;
|
||||||
|
|
||||||
|
for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
|
||||||
|
layout++) {
|
||||||
|
xf86GPUScreens[i]->confScreen = layout->screen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xf86GPUScreens[i]->PreInit &&
|
||||||
|
xf86GPUScreens[i]->PreInit(xf86GPUScreens[i], 0))
|
||||||
|
xf86GPUScreens[i]->configured = TRUE;
|
||||||
|
|
||||||
|
if (!xf86GPUScreens[i]->configured) {
|
||||||
|
ErrorF("hotplugged device %d didn't configure\n", i);
|
||||||
|
xf86DeleteScreen(xf86GPUScreens[i]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
scr_index = AddGPUScreen(xf86GPUScreens[i]->ScreenInit, 0, NULL);
|
||||||
|
|
||||||
|
dixSetPrivate(&xf86GPUScreens[i]->pScreen->devPrivates,
|
||||||
|
xf86ScreenKey, xf86GPUScreens[i]);
|
||||||
|
|
||||||
|
CreateScratchPixmapsForScreen(xf86GPUScreens[i]->pScreen);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xf86platformRemoveDevice(int index)
|
||||||
|
{
|
||||||
|
EntityPtr entity;
|
||||||
|
int ent_num, i, j;
|
||||||
|
Bool found;
|
||||||
|
|
||||||
|
for (ent_num = 0; ent_num < xf86NumEntities; ent_num++) {
|
||||||
|
entity = xf86Entities[ent_num];
|
||||||
|
if (entity->bus.type == BUS_PLATFORM &&
|
||||||
|
entity->bus.id.plat == &xf86_platform_devices[index])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ent_num == xf86NumEntities)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
found = FALSE;
|
||||||
|
for (i = 0; i < xf86NumGPUScreens; i++) {
|
||||||
|
for (j = 0; j < xf86GPUScreens[i]->numEntities; j++)
|
||||||
|
if (xf86GPUScreens[i]->entityList[j] == ent_num) {
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
ErrorF("failed to find screen to remove\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
xf86GPUScreens[i]->pScreen->CloseScreen(xf86GPUScreens[i]->pScreen);
|
||||||
|
|
||||||
|
RemoveGPUScreen(xf86GPUScreens[i]->pScreen);
|
||||||
|
xf86DeleteScreen(xf86GPUScreens[i]);
|
||||||
|
|
||||||
|
xf86UnclaimPlatformSlot(&xf86_platform_devices[index], NULL);
|
||||||
|
|
||||||
|
xf86_remove_platform_device(index);
|
||||||
|
|
||||||
|
out:
|
||||||
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -47,6 +47,11 @@ xf86_remove_platform_device(int dev_index);
|
||||||
extern Bool
|
extern Bool
|
||||||
xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_str);
|
xf86_add_platform_device_attrib(int index, int attrib_id, char *attrib_str);
|
||||||
|
|
||||||
|
extern int
|
||||||
|
xf86platformAddDevice(int index);
|
||||||
|
extern void
|
||||||
|
xf86platformRemoveDevice(int index);
|
||||||
|
|
||||||
extern _X_EXPORT char *
|
extern _X_EXPORT char *
|
||||||
xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib_id);
|
xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib_id);
|
||||||
extern _X_EXPORT Bool
|
extern _X_EXPORT Bool
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#include "xf86platformBus.h"
|
#include "xf86platformBus.h"
|
||||||
#include "xf86Bus.h"
|
#include "xf86Bus.h"
|
||||||
|
|
||||||
|
#include "hotplug.h"
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
get_drm_info(struct OdevAttributes *attribs, char *path)
|
get_drm_info(struct OdevAttributes *attribs, char *path)
|
||||||
{
|
{
|
||||||
|
@ -127,4 +129,51 @@ out_free:
|
||||||
config_odev_free_attribute_list(attribs);
|
config_odev_free_attribute_list(attribs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NewGPUDeviceRequest(struct OdevAttributes *attribs)
|
||||||
|
{
|
||||||
|
int old_num = xf86_num_platform_devices;
|
||||||
|
int ret;
|
||||||
|
xf86PlatformDeviceProbe(attribs);
|
||||||
|
|
||||||
|
if (old_num == xf86_num_platform_devices)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ret = xf86platformAddDevice(xf86_num_platform_devices-1);
|
||||||
|
if (ret == -1)
|
||||||
|
xf86_remove_platform_device(xf86_num_platform_devices-1);
|
||||||
|
|
||||||
|
ErrorF("xf86: found device %d\n", xf86_num_platform_devices);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteGPUDeviceRequest(struct OdevAttributes *attribs)
|
||||||
|
{
|
||||||
|
struct OdevAttribute *attrib;
|
||||||
|
int index;
|
||||||
|
char *syspath = NULL;
|
||||||
|
|
||||||
|
xorg_list_for_each_entry(attrib, &attribs->list, member) {
|
||||||
|
if (attrib->attrib_id == ODEV_ATTRIB_SYSPATH) {
|
||||||
|
syspath = attrib->attrib_name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (index = 0; index < xf86_num_platform_devices; index++) {
|
||||||
|
char *dspath;
|
||||||
|
dspath = xf86_get_platform_attrib(index, ODEV_ATTRIB_SYSPATH);
|
||||||
|
if (!strcmp(syspath, dspath))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == xf86_num_platform_devices)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ErrorF("xf86: remove device %d %s\n", index, syspath);
|
||||||
|
|
||||||
|
xf86platformRemoveDevice(index);
|
||||||
|
out:
|
||||||
|
config_odev_free_attribute_list(attribs);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue