Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 306497
b: refs/heads/master
c: 693f5c4
h: refs/heads/master
i:
  306495: c9898e9
v: v3
  • Loading branch information
Sylwester Nawrocki authored and Mauro Carvalho Chehab committed May 20, 2012
1 parent 262a3e8 commit afabc1a
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 132 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 97d974226575227ebafdf3ab009f0212d8a7e223
refs/heads/master: 693f5c40825e91632478624bf0366e6ebf862a25
142 changes: 77 additions & 65 deletions trunk/drivers/media/video/s5p-fimc/fimc-capture.c
Original file line number Diff line number Diff line change
Expand Up @@ -993,7 +993,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc)
if (!(pad->flags & MEDIA_PAD_FL_SINK))
break;
/* Don't call FIMC subdev operation to avoid nested locking */
if (sd == fimc->vid_cap.subdev) {
if (sd == &fimc->vid_cap.subdev) {
struct fimc_frame *ff = &vid_cap->ctx->s_frame;
sink_fmt.format.width = ff->f_width;
sink_fmt.format.height = ff->f_height;
Expand Down Expand Up @@ -1489,53 +1489,6 @@ static struct v4l2_subdev_ops fimc_subdev_ops = {
.pad = &fimc_subdev_pad_ops,
};

static int fimc_create_capture_subdev(struct fimc_dev *fimc,
struct v4l2_device *v4l2_dev)
{
struct v4l2_subdev *sd;
int ret;

sd = kzalloc(sizeof(*sd), GFP_KERNEL);
if (!sd)
return -ENOMEM;

v4l2_subdev_init(sd, &fimc_subdev_ops);
sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->pdev->id);

fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
fimc->vid_cap.sd_pads, 0);
if (ret)
goto me_err;
ret = v4l2_device_register_subdev(v4l2_dev, sd);
if (ret)
goto sd_err;

fimc->vid_cap.subdev = sd;
v4l2_set_subdevdata(sd, fimc);
sd->entity.ops = &fimc_sd_media_ops;
return 0;
sd_err:
media_entity_cleanup(&sd->entity);
me_err:
kfree(sd);
return ret;
}

static void fimc_destroy_capture_subdev(struct fimc_dev *fimc)
{
struct v4l2_subdev *sd = fimc->vid_cap.subdev;

if (!sd)
return;
media_entity_cleanup(&sd->entity);
v4l2_device_unregister_subdev(sd);
kfree(sd);
fimc->vid_cap.subdev = NULL;
}

/* Set default format at the sensor and host interface */
static int fimc_capture_set_default_format(struct fimc_dev *fimc)
{
Expand All @@ -1554,7 +1507,7 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc)
}

/* fimc->lock must be already initialized */
int fimc_register_capture_device(struct fimc_dev *fimc,
static int fimc_register_capture_device(struct fimc_dev *fimc,
struct v4l2_device *v4l2_dev)
{
struct video_device *vfd;
Expand All @@ -1572,16 +1525,15 @@ int fimc_register_capture_device(struct fimc_dev *fimc,
ctx->out_path = FIMC_DMA;
ctx->state = FIMC_CTX_CAP;
ctx->s_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0);
ctx->d_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0);
ctx->d_frame.fmt = ctx->s_frame.fmt;

vfd = video_device_alloc();
if (!vfd) {
v4l2_err(v4l2_dev, "Failed to allocate video device\n");
goto err_vd_alloc;
}

snprintf(vfd->name, sizeof(vfd->name), "%s.capture",
dev_name(&fimc->pdev->dev));
snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.capture", fimc->id);

vfd->fops = &fimc_capture_fops;
vfd->ioctl_ops = &fimc_capture_ioctl_ops;
Expand Down Expand Up @@ -1616,18 +1568,22 @@ int fimc_register_capture_device(struct fimc_dev *fimc,

vb2_queue_init(q);

fimc->vid_cap.vd_pad.flags = MEDIA_PAD_FL_SINK;
ret = media_entity_init(&vfd->entity, 1, &fimc->vid_cap.vd_pad, 0);
vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
if (ret)
goto err_ent;
ret = fimc_create_capture_subdev(fimc, v4l2_dev);

ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
if (ret)
goto err_sd_reg;
goto err_vd;

v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
vfd->name, video_device_node_name(vfd));

vfd->ctrl_handler = &ctx->ctrl_handler;
return 0;

err_sd_reg:
err_vd:
media_entity_cleanup(&vfd->entity);
err_ent:
video_device_release(vfd);
Expand All @@ -1636,17 +1592,73 @@ int fimc_register_capture_device(struct fimc_dev *fimc,
return ret;
}

void fimc_unregister_capture_device(struct fimc_dev *fimc)
static int fimc_capture_subdev_registered(struct v4l2_subdev *sd)
{
struct video_device *vfd = fimc->vid_cap.vfd;
struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
int ret;

if (vfd) {
media_entity_cleanup(&vfd->entity);
/* Can also be called if video device was
not registered */
video_unregister_device(vfd);
ret = fimc_register_m2m_device(fimc, sd->v4l2_dev);
if (ret)
return ret;

ret = fimc_register_capture_device(fimc, sd->v4l2_dev);
if (ret)
fimc_unregister_m2m_device(fimc);

return ret;
}

static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
{
struct fimc_dev *fimc = v4l2_get_subdevdata(sd);

if (fimc == NULL)
return;

fimc_unregister_m2m_device(fimc);

if (fimc->vid_cap.vfd) {
media_entity_cleanup(&fimc->vid_cap.vfd->entity);
video_unregister_device(fimc->vid_cap.vfd);
fimc->vid_cap.vfd = NULL;
}
fimc_destroy_capture_subdev(fimc);

kfree(fimc->vid_cap.ctx);
fimc->vid_cap.ctx = NULL;
}

static const struct v4l2_subdev_internal_ops fimc_capture_sd_internal_ops = {
.registered = fimc_capture_subdev_registered,
.unregistered = fimc_capture_subdev_unregistered,
};

int fimc_initialize_capture_subdev(struct fimc_dev *fimc)
{
struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
int ret;

v4l2_subdev_init(sd, &fimc_subdev_ops);
sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->pdev->id);

fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
fimc->vid_cap.sd_pads, 0);
if (ret)
return ret;

sd->entity.ops = &fimc_sd_media_ops;
sd->internal_ops = &fimc_capture_sd_internal_ops;
v4l2_set_subdevdata(sd, fimc);
return 0;
}

void fimc_unregister_capture_subdev(struct fimc_dev *fimc)
{
struct v4l2_subdev *sd = &fimc->vid_cap.subdev;

v4l2_device_unregister_subdev(sd);
media_entity_cleanup(&sd->entity);
v4l2_set_subdevdata(sd, NULL);
}
13 changes: 9 additions & 4 deletions trunk/drivers/media/video/s5p-fimc/fimc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -842,19 +842,22 @@ static int fimc_probe(struct platform_device *pdev)
clk_set_rate(fimc->clock[CLK_BUS], drv_data->lclk_frequency);
clk_enable(fimc->clock[CLK_BUS]);

platform_set_drvdata(pdev, fimc);

ret = devm_request_irq(&pdev->dev, res->start, fimc_irq_handler,
0, pdev->name, fimc);
if (ret) {
dev_err(&pdev->dev, "failed to install irq (%d)\n", ret);
goto err_clk;
}

ret = fimc_initialize_capture_subdev(fimc);
if (ret)
goto err_clk;

platform_set_drvdata(pdev, fimc);
pm_runtime_enable(&pdev->dev);
ret = pm_runtime_get_sync(&pdev->dev);
if (ret < 0)
goto err_clk;
goto err_sd;
/* Initialize contiguous memory allocator */
fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
if (IS_ERR(fimc->alloc_ctx)) {
Expand All @@ -866,9 +869,10 @@ static int fimc_probe(struct platform_device *pdev)

pm_runtime_put(&pdev->dev);
return 0;

err_pm:
pm_runtime_put(&pdev->dev);
err_sd:
fimc_unregister_capture_subdev(fimc);
err_clk:
fimc_clk_put(fimc);
return ret;
Expand Down Expand Up @@ -953,6 +957,7 @@ static int __devexit fimc_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);

fimc_unregister_capture_subdev(fimc);
vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);

clk_disable(fimc->clock[CLK_BUS]);
Expand Down
7 changes: 3 additions & 4 deletions trunk/drivers/media/video/s5p-fimc/fimc-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ struct fimc_vid_cap {
struct fimc_ctx *ctx;
struct vb2_alloc_ctx *alloc_ctx;
struct video_device *vfd;
struct v4l2_subdev *subdev;
struct v4l2_subdev subdev;
struct media_pad vd_pad;
struct v4l2_mbus_framefmt mf;
struct media_pad sd_pads[FIMC_SD_PADS_NUM];
Expand Down Expand Up @@ -737,9 +737,8 @@ void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state);

/* -----------------------------------------------------*/
/* fimc-capture.c */
int fimc_register_capture_device(struct fimc_dev *fimc,
struct v4l2_device *v4l2_dev);
void fimc_unregister_capture_device(struct fimc_dev *fimc);
int fimc_initialize_capture_subdev(struct fimc_dev *fimc);
void fimc_unregister_capture_subdev(struct fimc_dev *fimc);
int fimc_capture_ctrls_create(struct fimc_dev *fimc);
void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
void *arg);
Expand Down
17 changes: 14 additions & 3 deletions trunk/drivers/media/video/s5p-fimc/fimc-m2m.c
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ int fimc_register_m2m_device(struct fimc_dev *fimc,
This driver needs auditing so that this flag can be removed. */
set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);

snprintf(vfd->name, sizeof(vfd->name), "%s.m2m", dev_name(&pdev->dev));
snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id);
video_set_drvdata(vfd, fimc);

fimc->m2m.vfd = vfd;
Expand All @@ -788,9 +788,20 @@ int fimc_register_m2m_device(struct fimc_dev *fimc,
}

ret = media_entity_init(&vfd->entity, 0, NULL, 0);
if (!ret)
return 0;
if (ret)
goto err_me;

ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
if (ret)
goto err_vd;

v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
vfd->name, video_device_node_name(vfd));
return 0;

err_vd:
media_entity_cleanup(&vfd->entity);
err_me:
v4l2_m2m_release(fimc->m2m.m2m_dev);
err_init:
video_device_release(fimc->m2m.vfd);
Expand Down
Loading

0 comments on commit afabc1a

Please sign in to comment.