diff options
author | Dave Airlie <airlied@redhat.com> | 2010-03-30 01:34:18 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-04-06 20:30:38 -0400 |
commit | 4abe35204af82a018ca3ce6db4102aa09719698e (patch) | |
tree | fcc91e2e109fe311a673d5b99dc758aba3bb4a79 /drivers/gpu/drm/i915/intel_fb.c | |
parent | 5c4426a782bc9509573fc7958a786ebd14fafdf3 (diff) |
drm/kms/fb: use slow work mechanism for normal hotplug also.
a) slow work is always used now for any fbcon hotplug, as its not
a fast task and is more suited to being ran under slow work.
b) attempt to not do any fbdev changes when X is running as we'll
just mess it up. This hooks set_par to hopefully do the changes
once X hands control to fbdev.
This also adds the nouveau/intel hotplug support.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_fb.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_fb.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 8f7a7c476098..cc726ff0a02d 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -65,12 +65,6 @@ static struct fb_ops intelfb_ops = { | |||
65 | .fb_setcmap = drm_fb_helper_setcmap, | 65 | .fb_setcmap = drm_fb_helper_setcmap, |
66 | }; | 66 | }; |
67 | 67 | ||
68 | static struct drm_fb_helper_funcs intel_fb_helper_funcs = { | ||
69 | .gamma_set = intel_crtc_fb_gamma_set, | ||
70 | .gamma_get = intel_crtc_fb_gamma_get, | ||
71 | }; | ||
72 | |||
73 | |||
74 | static int intelfb_create(struct intel_fbdev *ifbdev, | 68 | static int intelfb_create(struct intel_fbdev *ifbdev, |
75 | struct drm_fb_helper_surface_size *sizes) | 69 | struct drm_fb_helper_surface_size *sizes) |
76 | { | 70 | { |
@@ -129,7 +123,6 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
129 | 123 | ||
130 | ifbdev->helper.fb = fb; | 124 | ifbdev->helper.fb = fb; |
131 | ifbdev->helper.fbdev = info; | 125 | ifbdev->helper.fbdev = info; |
132 | ifbdev->helper.funcs = &intel_fb_helper_funcs; | ||
133 | 126 | ||
134 | strcpy(info->fix.id, "inteldrmfb"); | 127 | strcpy(info->fix.id, "inteldrmfb"); |
135 | 128 | ||
@@ -154,6 +147,12 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
154 | ret = -ENOSPC; | 147 | ret = -ENOSPC; |
155 | goto out_unpin; | 148 | goto out_unpin; |
156 | } | 149 | } |
150 | |||
151 | ret = fb_alloc_cmap(&info->cmap, 256, 0); | ||
152 | if (ret) { | ||
153 | ret = -ENOMEM; | ||
154 | goto out_unpin; | ||
155 | } | ||
157 | info->screen_size = size; | 156 | info->screen_size = size; |
158 | 157 | ||
159 | // memset(info->screen_base, 0, size); | 158 | // memset(info->screen_base, 0, size); |
@@ -205,15 +204,18 @@ static int intel_fb_find_or_create_single(struct drm_fb_helper *helper, | |||
205 | return new_fb; | 204 | return new_fb; |
206 | } | 205 | } |
207 | 206 | ||
208 | static int intelfb_probe(struct intel_fbdev *ifbdev) | 207 | void intelfb_hotplug(struct drm_device *dev, bool polled) |
209 | { | 208 | { |
210 | int ret; | 209 | drm_i915_private_t *dev_priv = dev->dev_private; |
211 | 210 | drm_helper_fb_hpd_irq_event(&dev_priv->fbdev->helper); | |
212 | DRM_DEBUG_KMS("\n"); | ||
213 | ret = drm_fb_helper_single_fb_probe(&ifbdev->helper, 32); | ||
214 | return ret; | ||
215 | } | 211 | } |
216 | 212 | ||
213 | static struct drm_fb_helper_funcs intel_fb_helper_funcs = { | ||
214 | .gamma_set = intel_crtc_fb_gamma_set, | ||
215 | .gamma_get = intel_crtc_fb_gamma_get, | ||
216 | .fb_probe = intel_fb_find_or_create_single, | ||
217 | }; | ||
218 | |||
217 | int intel_fbdev_destroy(struct drm_device *dev, | 219 | int intel_fbdev_destroy(struct drm_device *dev, |
218 | struct intel_fbdev *ifbdev) | 220 | struct intel_fbdev *ifbdev) |
219 | { | 221 | { |
@@ -224,10 +226,12 @@ int intel_fbdev_destroy(struct drm_device *dev, | |||
224 | info = ifbdev->helper.fbdev; | 226 | info = ifbdev->helper.fbdev; |
225 | unregister_framebuffer(info); | 227 | unregister_framebuffer(info); |
226 | iounmap(info->screen_base); | 228 | iounmap(info->screen_base); |
229 | if (info->cmap.len) | ||
230 | fb_dealloc_cmap(&info->cmap); | ||
227 | framebuffer_release(info); | 231 | framebuffer_release(info); |
228 | } | 232 | } |
229 | 233 | ||
230 | drm_fb_helper_free(&ifbdev->helper); | 234 | drm_fb_helper_fini(&ifbdev->helper); |
231 | 235 | ||
232 | drm_framebuffer_cleanup(&ifb->base); | 236 | drm_framebuffer_cleanup(&ifb->base); |
233 | if (ifb->obj) | 237 | if (ifb->obj) |
@@ -246,13 +250,13 @@ int intel_fbdev_init(struct drm_device *dev) | |||
246 | return -ENOMEM; | 250 | return -ENOMEM; |
247 | 251 | ||
248 | dev_priv->fbdev = ifbdev; | 252 | dev_priv->fbdev = ifbdev; |
253 | ifbdev->helper.funcs = &intel_fb_helper_funcs; | ||
254 | |||
255 | drm_fb_helper_init(dev, &ifbdev->helper, 2, | ||
256 | INTELFB_CONN_LIMIT, false); | ||
249 | 257 | ||
250 | drm_fb_helper_init_crtc_count(dev, &ifbdev->helper, 2, | ||
251 | INTELFB_CONN_LIMIT); | ||
252 | drm_fb_helper_single_add_all_connectors(&ifbdev->helper); | 258 | drm_fb_helper_single_add_all_connectors(&ifbdev->helper); |
253 | ifbdev->helper.fb_probe = intel_fb_find_or_create_single; | 259 | drm_fb_helper_initial_config(&ifbdev->helper, 32); |
254 | drm_fb_helper_initial_config(&ifbdev->helper); | ||
255 | intelfb_probe(ifbdev); | ||
256 | return 0; | 260 | return 0; |
257 | } | 261 | } |
258 | 262 | ||