mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-24 19:30:11 +01:00
Added kernel part of hotplug ioctl
This commit is contained in:
parent
34b76e0fac
commit
0618ac8a07
4 changed files with 47 additions and 10 deletions
|
|
@ -770,6 +770,7 @@ void drm_mode_config_init(struct drm_device *dev)
|
|||
dev->mode_config.num_fb = 0;
|
||||
dev->mode_config.num_output = 0;
|
||||
dev->mode_config.num_crtc = 0;
|
||||
dev->mode_config.hotplug_counter = 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_config_init);
|
||||
|
||||
|
|
@ -1130,10 +1131,18 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,
|
|||
* RETURNS:
|
||||
* Zero on success, errno on failure.
|
||||
*/
|
||||
int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output)
|
||||
int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output,
|
||||
bool connected)
|
||||
{
|
||||
int has_config = 0;
|
||||
|
||||
/* We might want to do something more here */
|
||||
if (!connected) {
|
||||
DRM_DEBUG("not connected\n");
|
||||
dev->mode_config.hotplug_counter++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (output->crtc && output->crtc->desired_mode) {
|
||||
DRM_DEBUG("drm thinks that the output already has a config\n");
|
||||
has_config = 1;
|
||||
|
|
@ -1146,7 +1155,7 @@ int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output)
|
|||
|
||||
if (!output->crtc || !output->crtc->desired_mode) {
|
||||
DRM_DEBUG("could not find a desired mode or crtc for output\n");
|
||||
return 1;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
/* We should realy check if there is a fb using this crtc */
|
||||
|
|
@ -1161,10 +1170,25 @@ int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output)
|
|||
|
||||
drm_disable_unused_functions(dev);
|
||||
|
||||
dev->mode_config.hotplug_counter++;
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
dev->mode_config.hotplug_counter++;
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_hotplug_stage_two);
|
||||
|
||||
int drm_mode_hotplug_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_mode_hotplug *arg = data;
|
||||
|
||||
arg->counter = dev->mode_config.hotplug_counter;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
|
||||
* @out: drm_mode_modeinfo struct to return to the user
|
||||
|
|
|
|||
|
|
@ -547,6 +547,9 @@ struct drm_mode_config {
|
|||
struct drm_property *dpms_property;
|
||||
struct drm_property *connector_type_property;
|
||||
struct drm_property *connector_num_property;
|
||||
|
||||
/* hotplug */
|
||||
uint32_t hotplug_counter;
|
||||
};
|
||||
|
||||
struct drm_output *drm_output_create(struct drm_device *dev,
|
||||
|
|
@ -603,7 +606,7 @@ extern int drmfb_probe(struct drm_device *dev, struct drm_crtc *crtc);
|
|||
extern int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
|
||||
extern bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
|
||||
int x, int y);
|
||||
extern int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output);
|
||||
extern int drm_hotplug_stage_two(struct drm_device *dev, struct drm_output *output, bool connected);
|
||||
|
||||
extern int drm_output_attach_property(struct drm_output *output,
|
||||
struct drm_property *property, uint64_t init_val);
|
||||
|
|
@ -646,5 +649,8 @@ extern int drm_mode_getblob_ioctl(struct drm_device *dev,
|
|||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_output_property_set_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
extern int drm_mode_hotplug_ioctl(struct drm_device *dev,
|
||||
void *data, struct drm_file *file_priv);
|
||||
|
||||
#endif /* __DRM_CRTC_H__ */
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
|
|||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_ROOT_ONLY | DRM_CONTROL_ALLOW),
|
||||
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_HOTPLUG, drm_mode_hotplug_ioctl, DRM_CONTROL_ALLOW),
|
||||
|
||||
DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl,
|
||||
DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||
|
|
|
|||
|
|
@ -413,6 +413,7 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
|
|||
}
|
||||
|
||||
#define HOTPLUG_CMD_CRT 1
|
||||
#define HOTPLUG_CMD_CRT_DIS 2
|
||||
#define HOTPLUG_CMD_SDVOB 4
|
||||
#define HOTPLUG_CMD_SDVOC 8
|
||||
|
||||
|
|
@ -420,7 +421,7 @@ static struct drm_device *hotplug_dev;
|
|||
static int hotplug_cmd = 0;
|
||||
static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED;
|
||||
|
||||
static void i915_hotplug_crt(struct drm_device *dev)
|
||||
static void i915_hotplug_crt(struct drm_device *dev, bool connected)
|
||||
{
|
||||
struct drm_output *output;
|
||||
struct intel_output *iout;
|
||||
|
|
@ -439,7 +440,7 @@ static void i915_hotplug_crt(struct drm_device *dev)
|
|||
if (iout == 0)
|
||||
goto unlock;
|
||||
|
||||
drm_hotplug_stage_two(dev, output);
|
||||
drm_hotplug_stage_two(dev, output, connected);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
|
@ -462,9 +463,9 @@ static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB)
|
|||
status = output->funcs->detect(output);
|
||||
|
||||
if (status != output_status_connected)
|
||||
DRM_DEBUG("disconnect or unkown we don't do anything then\n");
|
||||
drm_hotplug_stage_two(dev, output, false);
|
||||
else
|
||||
drm_hotplug_stage_two(dev, output);
|
||||
drm_hotplug_stage_two(dev, output, true);
|
||||
|
||||
/* wierd hw bug, sdvo stop sending interupts */
|
||||
intel_sdvo_set_hotplug(output, 1);
|
||||
|
|
@ -484,18 +485,22 @@ static void i915_hotplug_work_func(struct work_struct *work)
|
|||
{
|
||||
struct drm_device *dev = hotplug_dev;
|
||||
int crt;
|
||||
int crtDis;
|
||||
int sdvoB;
|
||||
int sdvoC;
|
||||
|
||||
spin_lock(&hotplug_lock);
|
||||
crt = hotplug_cmd & HOTPLUG_CMD_CRT;
|
||||
crtDis = hotplug_cmd & HOTPLUG_CMD_CRT_DIS;
|
||||
sdvoB = hotplug_cmd & HOTPLUG_CMD_SDVOB;
|
||||
sdvoC = hotplug_cmd & HOTPLUG_CMD_SDVOC;
|
||||
hotplug_cmd = 0;
|
||||
spin_unlock(&hotplug_lock);
|
||||
|
||||
if (crt)
|
||||
i915_hotplug_crt(dev);
|
||||
i915_hotplug_crt(dev, true);
|
||||
if (crtDis)
|
||||
i915_hotplug_crt(dev, false);
|
||||
|
||||
if (sdvoB)
|
||||
i915_hotplug_sdvo(dev, 1);
|
||||
|
|
@ -524,7 +529,9 @@ static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat)
|
|||
hotplug_cmd |= HOTPLUG_CMD_CRT;
|
||||
spin_unlock(&hotplug_lock);
|
||||
} else {
|
||||
/* handle crt disconnects */
|
||||
spin_lock(&hotplug_lock);
|
||||
hotplug_cmd |= HOTPLUG_CMD_CRT_DIS;
|
||||
spin_unlock(&hotplug_lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue