static int sun4i_drv_bind(struct device *dev) { struct drm_device *drm; struct sun4i_drv *drv; int ret; drm = drm_dev_alloc(&sun4i_drv_driver, dev); if (IS_ERR(drm)) return PTR_ERR(drm); drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL); if (!drv) { ret = -ENOMEM; goto free_drm; } dev_set_drvdata(dev, drm); drm->dev_private = drv; INIT_LIST_HEAD(&drv->frontend_list); INIT_LIST_HEAD(&drv->engine_list); INIT_LIST_HEAD(&drv->tcon_list); ret = of_reserved_mem_device_init(dev); if (ret && ret != -ENODEV) { dev_err(drm->dev, "Couldn't claim our memory region\n"); goto free_drm; } drm_mode_config_init(drm); drm->mode_config.allow_fb_modifiers = true; ret = component_bind_all(drm->dev, drm); if (ret) { dev_err(drm->dev, "Couldn't bind all pipelines components\n"); goto cleanup_mode_config; } /* drm_vblank_init calls kcalloc, which can fail */ ret = drm_vblank_init(drm, drm->mode_config.num_crtc); if (ret) goto cleanup_mode_config; drm->irq_enabled = true; /* Remove early framebuffers (ie. simplefb) */ drm_fb_helper_remove_conflicting_framebuffers(NULL, "sun4i-drm-fb", false); sun4i_framebuffer_init(drm); /* Enable connectors polling */ drm_kms_helper_poll_init(drm); ret = drm_dev_register(drm, 0); if (ret) goto finish_poll; drm_fbdev_generic_setup(drm, 32); return 0; finish_poll: drm_kms_helper_poll_fini(drm); cleanup_mode_config: drm_mode_config_cleanup(drm); of_reserved_mem_device_release(dev); free_drm: drm_dev_put(drm); return ret; }
static int sun4i_drv_bind(struct device *dev) { struct drm_device *drm; struct sun4i_drv *drv; int ret; drm = drm_dev_alloc(&sun4i_drv_driver, dev); if (IS_ERR(drm)) return PTR_ERR(drm); drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL); if (!drv) { ret = -ENOMEM; goto free_drm; } drm->dev_private = drv; ret = of_reserved_mem_device_init(dev); if (ret && ret != -ENODEV) { dev_err(drm->dev, "Couldn't claim our memory region\n"); goto free_drm; } /* drm_vblank_init calls kcalloc, which can fail */ ret = drm_vblank_init(drm, 1); if (ret) goto free_mem_region; drm_mode_config_init(drm); ret = component_bind_all(drm->dev, drm); if (ret) { dev_err(drm->dev, "Couldn't bind all pipelines components\n"); goto cleanup_mode_config; } drm->irq_enabled = true; /* Remove early framebuffers (ie. simplefb) */ sun4i_remove_framebuffers(); /* Create our framebuffer */ drv->fbdev = sun4i_framebuffer_init(drm); if (IS_ERR(drv->fbdev)) { dev_err(drm->dev, "Couldn't create our framebuffer\n"); ret = PTR_ERR(drv->fbdev); goto cleanup_mode_config; } /* Enable connectors polling */ drm_kms_helper_poll_init(drm); ret = drm_dev_register(drm, 0); if (ret) goto finish_poll; return 0; finish_poll: drm_kms_helper_poll_fini(drm); sun4i_framebuffer_free(drm); cleanup_mode_config: drm_mode_config_cleanup(drm); drm_vblank_cleanup(drm); free_mem_region: of_reserved_mem_device_release(dev); free_drm: drm_dev_unref(drm); return ret; }
static int sun4i_drv_bind(struct device *dev) { struct drm_device *drm; struct sun4i_drv *drv; int ret; drm = drm_dev_alloc(&sun4i_drv_driver, dev); if (!drm) return -ENOMEM; drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL); if (!drv) { ret = -ENOMEM; goto free_drm; } drm->dev_private = drv; drm_vblank_init(drm, 1); drm_mode_config_init(drm); ret = component_bind_all(drm->dev, drm); if (ret) { dev_err(drm->dev, "Couldn't bind all pipelines components\n"); goto free_drm; } /* Create our layers */ drv->layers = sun4i_layers_init(drm); if (!drv->layers) { dev_err(drm->dev, "Couldn't create the planes\n"); ret = -EINVAL; goto free_drm; } /* Create our CRTC */ drv->crtc = sun4i_crtc_init(drm); if (!drv->crtc) { dev_err(drm->dev, "Couldn't create the CRTC\n"); ret = -EINVAL; goto free_drm; } drm->irq_enabled = true; /* Remove early framebuffers (ie. simplefb) */ sun4i_remove_framebuffers(); /* Create our framebuffer */ drv->fbdev = sun4i_framebuffer_init(drm); if (IS_ERR(drv->fbdev)) { dev_err(drm->dev, "Couldn't create our framebuffer\n"); ret = PTR_ERR(drv->fbdev); goto free_drm; } /* Enable connectors polling */ drm_kms_helper_poll_init(drm); ret = drm_dev_register(drm, 0); if (ret) goto free_drm; return 0; free_drm: drm_dev_unref(drm); return ret; }