Skip to content

Commit

Permalink
[media] coda: Improve runtime PM support
Browse files Browse the repository at this point in the history
For several reasons it's good practice to leave devices in runtime PM
active state while those have been probed.

In this cases we also want to prevent the device from going inactive,
until the firmware has been completely installed, especially when using
a PM domain.

Signed-off-by: Ulf Hansson <[email protected]>
Signed-off-by: Philipp Zabel <[email protected]>
Signed-off-by: Kamil Debski <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
  • Loading branch information
storulf authored and mchehab committed Sep 26, 2014
1 parent 7c67281 commit c5d28e2
Showing 1 changed file with 21 additions and 34 deletions.
55 changes: 21 additions & 34 deletions drivers/media/platform/coda/coda-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1688,58 +1688,35 @@ static void coda_fw_callback(const struct firmware *fw, void *context)

if (!fw) {
v4l2_err(&dev->v4l2_dev, "firmware request failed\n");
return;
goto put_pm;
}

/* allocate auxiliary per-device code buffer for the BIT processor */
ret = coda_alloc_aux_buf(dev, &dev->codebuf, fw->size, "codebuf",
dev->debugfs_root);
if (ret < 0) {
dev_err(&pdev->dev, "failed to allocate code buffer\n");
return;
goto put_pm;
}

/* Copy the whole firmware image to the code buffer */
memcpy(dev->codebuf.vaddr, fw->data, fw->size);
release_firmware(fw);

if (pm_runtime_enabled(&pdev->dev) && pdev->dev.pm_domain) {
/*
* Enabling power temporarily will cause coda_hw_init to be
* called via coda_runtime_resume by the pm domain.
*/
ret = pm_runtime_get_sync(&dev->plat_dev->dev);
if (ret < 0) {
v4l2_err(&dev->v4l2_dev, "failed to power on: %d\n",
ret);
return;
}

ret = coda_check_firmware(dev);
if (ret < 0)
return;

pm_runtime_put_sync(&dev->plat_dev->dev);
} else {
/*
* If runtime pm is disabled or pm_domain is not set,
* initialize once manually.
*/
ret = coda_hw_init(dev);
if (ret < 0) {
v4l2_err(&dev->v4l2_dev, "HW initialization failed\n");
return;
}

ret = coda_check_firmware(dev);
if (ret < 0)
return;
ret = coda_hw_init(dev);
if (ret < 0) {
v4l2_err(&dev->v4l2_dev, "HW initialization failed\n");
goto put_pm;
}

ret = coda_check_firmware(dev);
if (ret < 0)
goto put_pm;

dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
if (IS_ERR(dev->alloc_ctx)) {
v4l2_err(&dev->v4l2_dev, "Failed to alloc vb2 context\n");
return;
goto put_pm;
}

dev->m2m_dev = v4l2_m2m_init(&coda_m2m_ops);
Expand Down Expand Up @@ -1771,12 +1748,15 @@ static void coda_fw_callback(const struct firmware *fw, void *context)
v4l2_info(&dev->v4l2_dev, "codec registered as /dev/video[%d-%d]\n",
dev->vfd[0].num, dev->vfd[1].num);

pm_runtime_put_sync(&pdev->dev);
return;

rel_m2m:
v4l2_m2m_release(dev->m2m_dev);
rel_ctx:
vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
put_pm:
pm_runtime_put_sync(&pdev->dev);
}

static int coda_firmware_request(struct coda_dev *dev)
Expand Down Expand Up @@ -1998,6 +1978,13 @@ static int coda_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, dev);

/*
* Start activated so we can directly call coda_hw_init in
* coda_fw_callback regardless of whether CONFIG_PM_RUNTIME is
* enabled or whether the device is associated with a PM domain.
*/
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);

return coda_firmware_request(dev);
Expand Down

0 comments on commit c5d28e2

Please sign in to comment.