On Thu, Jun 14, 2012 at 03:43:23PM +0200, Sascha Hauer wrote: ...
+struct drm_device *imx_drm_device_get(void) +{
- struct imx_drm_device *imxdrm = __imx_drm_device();
- struct imx_drm_encoder *enc;
- struct imx_drm_connector *con;
- struct imx_drm_crtc *crtc;
- mutex_lock(&imxdrm->mutex);
- list_for_each_entry(enc, &imxdrm->encoder_list, list) {
if (!try_module_get(enc->owner)) {
dev_err(imxdrm->dev, "could not get module %s\n",
module_name(enc->owner));
goto unwind_enc;
}
- }
- list_for_each_entry(con, &imxdrm->connector_list, list) {
if (!try_module_get(con->owner)) {
dev_err(imxdrm->dev, "could not get module %s\n",
module_name(con->owner));
goto unwind_con;
}
- }
- list_for_each_entry(crtc, &imxdrm->crtc_list, list) {
if (!try_module_get(crtc->owner)) {
dev_err(imxdrm->dev, "could not get module %s\n",
module_name(crtc->owner));
goto unwind_crtc;
}
- }
- imxdrm->references++;
- mutex_unlock(&imxdrm->mutex);
- return imx_drm_device->drm;
Though I'm not quite sure about the point of retrieving the static variable imx_drm_device from calling __imx_drm_device(), shouldn't imxdrm be used here since you already retrieve it?
+unwind_crtc:
- list_for_each_entry_continue_reverse(crtc, &imxdrm->crtc_list, list)
module_put(crtc->owner);
+unwind_con:
- list_for_each_entry_continue_reverse(con, &imxdrm->connector_list, list)
module_put(con->owner);
+unwind_enc:
- list_for_each_entry_continue_reverse(enc, &imxdrm->encoder_list, list)
module_put(enc->owner);
- mutex_unlock(&imxdrm->mutex);
- return NULL;
+} +EXPORT_SYMBOL_GPL(imx_drm_device_get);
...
+/*
- register a connector to the drm core
- */
+static int imx_drm_connector_register(
struct imx_drm_connector *imx_drm_connector)
+{
- struct imx_drm_device *imxdrm = __imx_drm_device();
- int ret;
- drm_connector_init(imxdrm->drm, imx_drm_connector->connector,
imx_drm_connector->connector->funcs,
imx_drm_connector->connector->connector_type);
- drm_mode_group_reinit(imxdrm->drm);
- ret = drm_sysfs_connector_add(imx_drm_connector->connector);
- if (ret)
goto err;
Simply return ret to save the err path?
- return 0;
+err:
- return ret;
+}
...
+/*
- imx_drm_add_encoder - add a new encoder
- */
+int imx_drm_add_encoder(struct drm_encoder *encoder,
struct imx_drm_encoder **newenc, struct module *owner)
+{
- struct imx_drm_device *imxdrm = __imx_drm_device();
- struct imx_drm_encoder *imx_drm_encoder;
- int ret;
- mutex_lock(&imxdrm->mutex);
- if (imxdrm->references) {
ret = -EBUSY;
goto err_busy;
- }
- imx_drm_encoder = kzalloc(sizeof(struct imx_drm_encoder), GFP_KERNEL);
sizeof(*imx_drm_encoder)
- if (!imx_drm_encoder) {
ret = -ENOMEM;
goto err_alloc;
- }
- imx_drm_encoder->encoder = encoder;
- imx_drm_encoder->owner = owner;
- ret = imx_drm_encoder_register(imx_drm_encoder);
- if (ret) {
kfree(imx_drm_encoder);
ret = -ENOMEM;
goto err_register;
- }
- list_add_tail(&imx_drm_encoder->list, &imxdrm->encoder_list);
- *newenc = imx_drm_encoder;
- mutex_unlock(&imxdrm->mutex);
- return 0;
+err_register:
- kfree(imx_drm_encoder);
+err_alloc: +err_busy:
- mutex_unlock(&imxdrm->mutex);
- return ret;
+} +EXPORT_SYMBOL_GPL(imx_drm_add_encoder);
...
+/*
- imx_drm_add_connector - add a connector
- */
+int imx_drm_add_connector(struct drm_connector *connector,
struct imx_drm_connector **new_con,
struct module *owner)
+{
- struct imx_drm_device *imxdrm = __imx_drm_device();
- struct imx_drm_connector *imx_drm_connector;
- int ret;
- mutex_lock(&imxdrm->mutex);
- if (imxdrm->references) {
ret = -EBUSY;
goto err_busy;
- }
- imx_drm_connector = kzalloc(sizeof(struct imx_drm_connector),
sizeof(*imx_drm_connector)
GFP_KERNEL);
- if (!imx_drm_connector) {
ret = -ENOMEM;
goto err_alloc;
- }
- imx_drm_connector->connector = connector;
- imx_drm_connector->owner = owner;
- ret = imx_drm_connector_register(imx_drm_connector);
- if (ret)
goto err_register;
- list_add_tail(&imx_drm_connector->list, &imxdrm->connector_list);
- *new_con = imx_drm_connector;
- mutex_unlock(&imxdrm->mutex);
- return 0;
+err_register:
- kfree(imx_drm_connector);
+err_alloc: +err_busy:
- mutex_unlock(&imxdrm->mutex);
- return ret;
+} +EXPORT_SYMBOL_GPL(imx_drm_add_connector);
...
+static int __init imx_drm_init(void) +{
- int ret;
- imx_drm_device = kzalloc(sizeof(*imx_drm_device), GFP_KERNEL);
- if (!imx_drm_device)
return -ENOMEM;
- mutex_init(&imx_drm_device->mutex);
- INIT_LIST_HEAD(&imx_drm_device->crtc_list);
- INIT_LIST_HEAD(&imx_drm_device->connector_list);
- INIT_LIST_HEAD(&imx_drm_device->encoder_list);
- imx_drm_pdev = platform_device_register_simple("imx-drm", -1, NULL, 0);
- if (!imx_drm_pdev) {
ret = -EINVAL;
goto err_pdev;
- }
- imx_drm_pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32),
- ret = platform_driver_register(&imx_drm_pdrv);
- if (ret)
goto err_pdrv;
- return 0;
+err_pdev:
- kfree(imx_drm_device);
+err_pdrv:
- platform_device_unregister(imx_drm_pdev);
The order between these two blocks looks wrong.
- return ret;
+}
...
+static int __init imx_fb_helper_init(void) +{
- struct drm_device *drm = imx_drm_device_get();
- if (!drm)
return -EINVAL;
- fbdev_cma = drm_fbdev_cma_init(drm, PREFERRED_BPP,
drm->mode_config.num_crtc, MAX_CONNECTOR);
- imx_drm_fb_helper_set(fbdev_cma);
- if (IS_ERR(fbdev_cma)) {
imx_drm_device_put();
return PTR_ERR(fbdev_cma);
- }
Shouldn't this error check be put right after drm_fbdev_cma_init call?
- return 0;
+}