static int fimc_md_get_clocks(struct fimc_md *fmd) { struct device *dev = &fmd->pdev->dev; char clk_name[32]; struct clk *clock; int i, ret = 0; for (i = 0; i < FIMC_MAX_CAMCLKS; i++) fmd->camclk[i].clock = ERR_PTR(-EINVAL); for (i = 0; i < FIMC_MAX_CAMCLKS; i++) { snprintf(clk_name, sizeof(clk_name), "sclk_cam%u", i); clock = clk_get(dev, clk_name); if (IS_ERR(clock)) { dev_err(dev, "Failed to get clock: %s\n", clk_name); ret = PTR_ERR(clock); break; } fmd->camclk[i].clock = clock; } if (ret) fimc_md_put_clocks(fmd); if (!fmd->use_isp) return 0; /* * For now get only PIXELASYNCM1 clock (Writeback B/ISP), * leave PIXELASYNCM0 out for the LCD Writeback driver. */ fmd->wbclk[CLK_IDX_WB_A] = ERR_PTR(-EINVAL); for (i = CLK_IDX_WB_B; i < FIMC_MAX_WBCLKS; i++) { snprintf(clk_name, sizeof(clk_name), "pxl_async%u", i); clock = clk_get(dev, clk_name); if (IS_ERR(clock)) { v4l2_err(&fmd->v4l2_dev, "Failed to get clock: %s\n", clk_name); ret = PTR_ERR(clock); break; } fmd->wbclk[i] = clock; } if (ret) fimc_md_put_clocks(fmd); return ret; }
static int __devexit fimc_md_remove(struct platform_device *pdev) { struct fimc_md *fmd = platform_get_drvdata(pdev); if (!fmd) return 0; device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode); fimc_md_unregister_entities(fmd); media_device_unregister(&fmd->media_dev); fimc_md_put_clocks(fmd); return 0; }
static int __devinit fimc_md_probe(struct platform_device *pdev) { struct v4l2_device *v4l2_dev; struct fimc_md *fmd; int ret; fmd = devm_kzalloc(&pdev->dev, sizeof(*fmd), GFP_KERNEL); if (!fmd) return -ENOMEM; spin_lock_init(&fmd->slock); fmd->pdev = pdev; strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC", sizeof(fmd->media_dev.model)); fmd->media_dev.link_notify = fimc_md_link_notify; fmd->media_dev.dev = &pdev->dev; v4l2_dev = &fmd->v4l2_dev; v4l2_dev->mdev = &fmd->media_dev; v4l2_dev->notify = fimc_sensor_notify; snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s", dev_name(&pdev->dev)); ret = v4l2_device_register(&pdev->dev, &fmd->v4l2_dev); if (ret < 0) { v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret); return ret; } ret = media_device_register(&fmd->media_dev); if (ret < 0) { v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret); goto err2; } ret = fimc_md_get_clocks(fmd); if (ret) goto err3; fmd->user_subdev_api = false; ret = fimc_md_register_platform_entities(fmd); if (ret) goto err3; if (pdev->dev.platform_data) { ret = fimc_md_register_sensor_entities(fmd); if (ret) goto err3; } ret = fimc_md_create_links(fmd); if (ret) goto err3; ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev); if (ret) goto err3; ret = fimc_md_register_video_nodes(fmd); if (ret) goto err3; ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode); if (!ret) { platform_set_drvdata(pdev, fmd); return 0; } err3: media_device_unregister(&fmd->media_dev); fimc_md_put_clocks(fmd); fimc_md_unregister_entities(fmd); err2: v4l2_device_unregister(&fmd->v4l2_dev); return ret; }
static int fimc_md_probe(struct platform_device *pdev) { struct s5p_platform_fimc *pdata = pdev->dev.platform_data; struct v4l2_device *v4l2_dev; struct fimc_md *fmd; int ret; fmd = devm_kzalloc(&pdev->dev, sizeof(*fmd), GFP_KERNEL); if (!fmd) return -ENOMEM; spin_lock_init(&fmd->slock); fmd->pdev = pdev; strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC", sizeof(fmd->media_dev.model)); fmd->media_dev.link_notify = fimc_md_link_notify; fmd->media_dev.dev = &pdev->dev; v4l2_dev = &fmd->v4l2_dev; v4l2_dev->mdev = &fmd->media_dev; v4l2_dev->notify = fimc_sensor_notify; snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s", dev_name(&pdev->dev)); ret = v4l2_device_register(&pdev->dev, &fmd->v4l2_dev); if (ret < 0) { v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret); return ret; } ret = media_device_register(&fmd->media_dev); if (ret < 0) { v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret); goto err_md; } ret = fimc_md_get_clocks(fmd, pdata); if (ret) goto err_clk; fmd->user_subdev_api = true; /* Protect the media graph while we're registering entities */ mutex_lock(&fmd->media_dev.graph_mutex); ret = fimc_md_register_platform_entities(fmd); if (ret) goto err_unlock; if (pdata) { ret = fimc_md_register_sensor_entities(fmd); if (ret) goto err_unlock; } ret = fimc_md_create_links(fmd); if (ret) goto err_unlock; ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev); if (ret) goto err_unlock; ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode); if (ret) goto err_unlock; platform_set_drvdata(pdev, fmd); mutex_unlock(&fmd->media_dev.graph_mutex); return 0; err_unlock: mutex_unlock(&fmd->media_dev.graph_mutex); err_clk: media_device_unregister(&fmd->media_dev); fimc_md_put_clocks(fmd); fimc_md_unregister_entities(fmd); err_md: v4l2_device_unregister(&fmd->v4l2_dev); return ret; }