fix kernel oops when removing fb

drm_crtc->fb may point to NULL, f.e X server will allocate a new fb
and assign it to the CRTC at startup, when X server exits, it will destroy
the allocated fb, making drm_crtc->fb points to NULL.
main
Hong Liu 2008-05-09 10:06:17 +08:00 committed by Jesse Barnes
parent b2dee13f5d
commit a51e38548c
6 changed files with 6 additions and 8 deletions

View File

@ -744,7 +744,7 @@ struct drm_driver {
/* FB routines, if present */ /* FB routines, if present */
int (*fb_probe)(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output); int (*fb_probe)(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output);
int (*fb_remove)(struct drm_device *dev, struct drm_crtc *crtc); int (*fb_remove)(struct drm_device *dev, struct drm_framebuffer *fb);
int (*fb_resize)(struct drm_device *dev, struct drm_crtc *crtc); int (*fb_resize)(struct drm_device *dev, struct drm_crtc *crtc);
/* Master routines */ /* Master routines */

View File

@ -1095,7 +1095,7 @@ void drm_mode_config_cleanup(struct drm_device *dev)
if (fb->bo->type != drm_bo_type_kernel) if (fb->bo->type != drm_bo_type_kernel)
drm_framebuffer_destroy(fb); drm_framebuffer_destroy(fb);
else else
dev->driver->fb_remove(dev, drm_crtc_from_fb(dev, fb)); dev->driver->fb_remove(dev, fb);
} }
list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) { list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {

View File

@ -91,7 +91,7 @@ extern int intel_sdvo_supports_hotplug(struct drm_output *output);
extern void intel_sdvo_set_hotplug(struct drm_output *output, int enable); extern void intel_sdvo_set_hotplug(struct drm_output *output, int enable);
extern int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output); extern int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output);
extern int intelfb_remove(struct drm_device *dev, struct drm_crtc *crtc); extern int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
extern int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc); extern int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc);
#endif /* __INTEL_DRV_H__ */ #endif /* __INTEL_DRV_H__ */

View File

@ -767,9 +767,8 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_outp
} }
EXPORT_SYMBOL(intelfb_probe); EXPORT_SYMBOL(intelfb_probe);
int intelfb_remove(struct drm_device *dev, struct drm_crtc *crtc) int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
{ {
struct drm_framebuffer *fb = crtc->fb;
struct fb_info *info; struct fb_info *info;
if (!fb) if (!fb)
@ -784,7 +783,6 @@ int intelfb_remove(struct drm_device *dev, struct drm_crtc *crtc)
drm_framebuffer_destroy(fb); drm_framebuffer_destroy(fb);
framebuffer_release(info); framebuffer_release(info);
} }
crtc->fb = NULL;
return 0; return 0;
} }
EXPORT_SYMBOL(intelfb_remove); EXPORT_SYMBOL(intelfb_remove);

View File

@ -438,7 +438,7 @@ int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_out
} }
EXPORT_SYMBOL(radeonfb_probe); EXPORT_SYMBOL(radeonfb_probe);
int radeonfb_remove(struct drm_device *dev, struct drm_crtc *crtc) int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *kern_fb)
{ {
struct drm_radeon_private *dev_priv = dev->dev_private; struct drm_radeon_private *dev_priv = dev->dev_private;
struct amd_fb *fb = dev_priv->fb; struct amd_fb *fb = dev_priv->fb;

View File

@ -436,7 +436,7 @@ int r3xx_fence_types(struct drm_buffer_object *bo,
/* radeon_ms_fb.c */ /* radeon_ms_fb.c */
int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output); int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output);
int radeonfb_remove(struct drm_device *dev, struct drm_crtc *crtc); int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
/* radeon_ms_gpu.c */ /* radeon_ms_gpu.c */
int radeon_ms_gpu_initialize(struct drm_device *dev); int radeon_ms_gpu_initialize(struct drm_device *dev);