staging: drm/imx: fix pageflip events during device close
During a device close the drm core frees all pending events in drm_events_release(). If at that time a pageflip is pending the interrupt handler will try to complete the now unitialized event resulting in a NULL pointer exception. Seen on imx-drm when userspace is killed during a page flip. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
b8fbb34181
commit
6ee4d7fe1b
2 changed files with 15 additions and 7 deletions
|
@ -185,6 +185,18 @@ static void imx_drm_disable_vblank(struct drm_device *drm, int crtc)
|
||||||
imx_drm_crtc->imx_drm_helper_funcs.disable_vblank(imx_drm_crtc->crtc);
|
imx_drm_crtc->imx_drm_helper_funcs.disable_vblank(imx_drm_crtc->crtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void imx_drm_driver_preclose(struct drm_device *drm,
|
||||||
|
struct drm_file *file)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!file->is_master)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
imx_drm_disable_vblank(drm , i);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct file_operations imx_drm_driver_fops = {
|
static const struct file_operations imx_drm_driver_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.open = drm_open,
|
.open = drm_open,
|
||||||
|
@ -766,6 +778,7 @@ static struct drm_driver imx_drm_driver = {
|
||||||
.load = imx_drm_driver_load,
|
.load = imx_drm_driver_load,
|
||||||
.unload = imx_drm_driver_unload,
|
.unload = imx_drm_driver_unload,
|
||||||
.lastclose = imx_drm_driver_lastclose,
|
.lastclose = imx_drm_driver_lastclose,
|
||||||
|
.preclose = imx_drm_driver_preclose,
|
||||||
.gem_free_object = drm_gem_cma_free_object,
|
.gem_free_object = drm_gem_cma_free_object,
|
||||||
.gem_vm_ops = &drm_gem_cma_vm_ops,
|
.gem_vm_ops = &drm_gem_cma_vm_ops,
|
||||||
.dumb_create = drm_gem_cma_dumb_create,
|
.dumb_create = drm_gem_cma_dumb_create,
|
||||||
|
|
|
@ -368,10 +368,6 @@ static struct drm_crtc_helper_funcs ipu_helper_funcs = {
|
||||||
|
|
||||||
static int ipu_enable_vblank(struct drm_crtc *crtc)
|
static int ipu_enable_vblank(struct drm_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
|
|
||||||
|
|
||||||
enable_irq(ipu_crtc->irq);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,7 +375,8 @@ static void ipu_disable_vblank(struct drm_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
|
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
|
||||||
|
|
||||||
disable_irq(ipu_crtc->irq);
|
ipu_crtc->page_flip_event = NULL;
|
||||||
|
ipu_crtc->newfb = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type,
|
static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type,
|
||||||
|
@ -502,8 +499,6 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
|
||||||
goto err_put_resources;
|
goto err_put_resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
disable_irq(ipu_crtc->irq);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_put_resources:
|
err_put_resources:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue