aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/imx/imx-drm-core.c
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2016-08-11 05:18:48 -0400
committerPhilipp Zabel <p.zabel@pengutronix.de>2016-08-29 06:45:05 -0400
commit54db5decce17b3258475a011a00b9c5c51c57a35 (patch)
tree2a60d0b2b9504fdab514e23004279efe7be60c84 /drivers/gpu/drm/imx/imx-drm-core.c
parent73cde76a61b622e768af23b0e0062dc39e6891bf (diff)
drm/imx: drop deprecated load/unload drm_driver ops
Drop the load/unload driver ops, as they are deprecated because of their inherent races, with devices being visible to userspace before they are fully initialized. Move this code into the driver bind/unbind routines bracketed by the proper drm_dev_alloc/register and drm_dev_unregister/unref calls. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Diffstat (limited to 'drivers/gpu/drm/imx/imx-drm-core.c')
-rw-r--r--drivers/gpu/drm/imx/imx-drm-core.c240
1 files changed, 112 insertions, 128 deletions
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index 75f35eaffb78..7a1ddf8b04cf 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -64,25 +64,6 @@ static void imx_drm_driver_lastclose(struct drm_device *drm)
64 drm_fbdev_cma_restore_mode(imxdrm->fbhelper); 64 drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
65} 65}
66 66
67static int imx_drm_driver_unload(struct drm_device *drm)
68{
69 struct imx_drm_device *imxdrm = drm->dev_private;
70
71 drm_kms_helper_poll_fini(drm);
72
73 if (imxdrm->fbhelper)
74 drm_fbdev_cma_fini(imxdrm->fbhelper);
75
76 component_unbind_all(drm->dev, drm);
77
78 drm_vblank_cleanup(drm);
79 drm_mode_config_cleanup(drm);
80
81 platform_set_drvdata(drm->platformdev, NULL);
82
83 return 0;
84}
85
86static int imx_drm_enable_vblank(struct drm_device *drm, unsigned int pipe) 67static int imx_drm_enable_vblank(struct drm_device *drm, unsigned int pipe)
87{ 68{
88 struct imx_drm_device *imxdrm = drm->dev_private; 69 struct imx_drm_device *imxdrm = drm->dev_private;
@@ -235,111 +216,6 @@ static struct drm_mode_config_helper_funcs imx_drm_mode_config_helpers = {
235}; 216};
236 217
237/* 218/*
238 * Main DRM initialisation. This binds, initialises and registers
239 * with DRM the subcomponents of the driver.
240 */
241static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
242{
243 struct imx_drm_device *imxdrm;
244 struct drm_connector *connector;
245 int ret;
246
247 imxdrm = devm_kzalloc(drm->dev, sizeof(*imxdrm), GFP_KERNEL);
248 if (!imxdrm)
249 return -ENOMEM;
250
251 imxdrm->drm = drm;
252
253 drm->dev_private = imxdrm;
254
255 /*
256 * enable drm irq mode.
257 * - with irq_enabled = true, we can use the vblank feature.
258 *
259 * P.S. note that we wouldn't use drm irq handler but
260 * just specific driver own one instead because
261 * drm framework supports only one irq handler and
262 * drivers can well take care of their interrupts
263 */
264 drm->irq_enabled = true;
265
266 /*
267 * set max width and height as default value(4096x4096).
268 * this value would be used to check framebuffer size limitation
269 * at drm_mode_addfb().
270 */
271 drm->mode_config.min_width = 64;
272 drm->mode_config.min_height = 64;
273 drm->mode_config.max_width = 4096;
274 drm->mode_config.max_height = 4096;
275 drm->mode_config.funcs = &imx_drm_mode_config_funcs;
276 drm->mode_config.helper_private = &imx_drm_mode_config_helpers;
277
278 drm_mode_config_init(drm);
279
280 ret = drm_vblank_init(drm, MAX_CRTC);
281 if (ret)
282 goto err_kms;
283
284 platform_set_drvdata(drm->platformdev, drm);
285
286 /* Now try and bind all our sub-components */
287 ret = component_bind_all(drm->dev, drm);
288 if (ret)
289 goto err_vblank;
290
291 /*
292 * All components are now added, we can publish the connector sysfs
293 * entries to userspace. This will generate hotplug events and so
294 * userspace will expect to be able to access DRM at this point.
295 */
296 list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
297 ret = drm_connector_register(connector);
298 if (ret) {
299 dev_err(drm->dev,
300 "[CONNECTOR:%d:%s] drm_connector_register failed: %d\n",
301 connector->base.id,
302 connector->name, ret);
303 goto err_unbind;
304 }
305 }
306
307 drm_mode_config_reset(drm);
308
309 /*
310 * All components are now initialised, so setup the fb helper.
311 * The fb helper takes copies of key hardware information, so the
312 * crtcs/connectors/encoders must not change after this point.
313 */
314#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
315 if (legacyfb_depth != 16 && legacyfb_depth != 32) {
316 dev_warn(drm->dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n");
317 legacyfb_depth = 16;
318 }
319 imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
320 drm->mode_config.num_crtc, MAX_CRTC);
321 if (IS_ERR(imxdrm->fbhelper)) {
322 ret = PTR_ERR(imxdrm->fbhelper);
323 imxdrm->fbhelper = NULL;
324 goto err_unbind;
325 }
326#endif
327
328 drm_kms_helper_poll_init(drm);
329
330 return 0;
331
332err_unbind:
333 component_unbind_all(drm->dev, drm);
334err_vblank:
335 drm_vblank_cleanup(drm);
336err_kms:
337 drm_mode_config_cleanup(drm);
338
339 return ret;
340}
341
342/*
343 * imx_drm_add_crtc - add a new crtc 219 * imx_drm_add_crtc - add a new crtc
344 */ 220 */
345int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, 221int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
@@ -431,8 +307,6 @@ static const struct drm_ioctl_desc imx_drm_ioctls[] = {
431static struct drm_driver imx_drm_driver = { 307static struct drm_driver imx_drm_driver = {
432 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | 308 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
433 DRIVER_ATOMIC, 309 DRIVER_ATOMIC,
434 .load = imx_drm_driver_load,
435 .unload = imx_drm_driver_unload,
436 .lastclose = imx_drm_driver_lastclose, 310 .lastclose = imx_drm_driver_lastclose,
437 .gem_free_object_unlocked = drm_gem_cma_free_object, 311 .gem_free_object_unlocked = drm_gem_cma_free_object,
438 .gem_vm_ops = &drm_gem_cma_vm_ops, 312 .gem_vm_ops = &drm_gem_cma_vm_ops,
@@ -485,12 +359,122 @@ static int compare_of(struct device *dev, void *data)
485 359
486static int imx_drm_bind(struct device *dev) 360static int imx_drm_bind(struct device *dev)
487{ 361{
488 return drm_platform_init(&imx_drm_driver, to_platform_device(dev)); 362 struct drm_device *drm;
363 struct imx_drm_device *imxdrm;
364 int ret;
365
366 drm = drm_dev_alloc(&imx_drm_driver, dev);
367 if (!drm)
368 return -ENOMEM;
369
370 imxdrm = devm_kzalloc(dev, sizeof(*imxdrm), GFP_KERNEL);
371 if (!imxdrm) {
372 ret = -ENOMEM;
373 goto err_unref;
374 }
375
376 imxdrm->drm = drm;
377 drm->dev_private = imxdrm;
378
379 /*
380 * enable drm irq mode.
381 * - with irq_enabled = true, we can use the vblank feature.
382 *
383 * P.S. note that we wouldn't use drm irq handler but
384 * just specific driver own one instead because
385 * drm framework supports only one irq handler and
386 * drivers can well take care of their interrupts
387 */
388 drm->irq_enabled = true;
389
390 /*
391 * set max width and height as default value(4096x4096).
392 * this value would be used to check framebuffer size limitation
393 * at drm_mode_addfb().
394 */
395 drm->mode_config.min_width = 64;
396 drm->mode_config.min_height = 64;
397 drm->mode_config.max_width = 4096;
398 drm->mode_config.max_height = 4096;
399 drm->mode_config.funcs = &imx_drm_mode_config_funcs;
400 drm->mode_config.helper_private = &imx_drm_mode_config_helpers;
401
402 drm_mode_config_init(drm);
403
404 ret = drm_vblank_init(drm, MAX_CRTC);
405 if (ret)
406 goto err_kms;
407
408 dev_set_drvdata(dev, drm);
409
410 /* Now try and bind all our sub-components */
411 ret = component_bind_all(dev, drm);
412 if (ret)
413 goto err_vblank;
414
415 drm_mode_config_reset(drm);
416
417 /*
418 * All components are now initialised, so setup the fb helper.
419 * The fb helper takes copies of key hardware information, so the
420 * crtcs/connectors/encoders must not change after this point.
421 */
422#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION)
423 if (legacyfb_depth != 16 && legacyfb_depth != 32) {
424 dev_warn(dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n");
425 legacyfb_depth = 16;
426 }
427 imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
428 drm->mode_config.num_crtc, MAX_CRTC);
429 if (IS_ERR(imxdrm->fbhelper)) {
430 ret = PTR_ERR(imxdrm->fbhelper);
431 imxdrm->fbhelper = NULL;
432 goto err_unbind;
433 }
434#endif
435
436 drm_kms_helper_poll_init(drm);
437
438 ret = drm_dev_register(drm, 0);
439 if (ret)
440 goto err_fbhelper;
441
442 return 0;
443
444err_fbhelper:
445 drm_kms_helper_poll_fini(drm);
446 if (imxdrm->fbhelper)
447 drm_fbdev_cma_fini(imxdrm->fbhelper);
448err_unbind:
449 component_unbind_all(drm->dev, drm);
450err_vblank:
451 drm_vblank_cleanup(drm);
452err_kms:
453 drm_mode_config_cleanup(drm);
454err_unref:
455 drm_dev_unref(drm);
456
457 return ret;
489} 458}
490 459
491static void imx_drm_unbind(struct device *dev) 460static void imx_drm_unbind(struct device *dev)
492{ 461{
493 drm_put_dev(dev_get_drvdata(dev)); 462 struct drm_device *drm = dev_get_drvdata(dev);
463 struct imx_drm_device *imxdrm = drm->dev_private;
464
465 drm_dev_unregister(drm);
466
467 drm_kms_helper_poll_fini(drm);
468
469 if (imxdrm->fbhelper)
470 drm_fbdev_cma_fini(imxdrm->fbhelper);
471
472 component_unbind_all(drm->dev, drm);
473 dev_set_drvdata(dev, NULL);
474
475 drm_mode_config_cleanup(drm);
476
477 drm_dev_unref(drm);
494} 478}
495 479
496static const struct component_master_ops imx_drm_ops = { 480static const struct component_master_ops imx_drm_ops = {