Added kernel part of hotplug ioctl

This commit is contained in:
Jakob Bornecrantz 2008-02-07 19:24:58 +01:00
parent 34b76e0fac
commit 0618ac8a07
4 changed files with 47 additions and 10 deletions

View file

@ -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

View file

@ -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__ */

View file

@ -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),

View file

@ -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);
}
}