summaryrefslogtreecommitdiff
path: root/drivers/staging/media/imx/imx-ic-prp.c
diff options
context:
space:
mode:
authorSteve Longerbeam <slongerbeam@gmail.com>2019-05-10 17:50:05 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-05-28 14:08:21 -0400
commit6d01b7ff523375e22db5d2c37a18bdf332376b2f (patch)
tree97e9a48ef18cc439c93d75582a92a36518b93853 /drivers/staging/media/imx/imx-ic-prp.c
parent411c59881c776cfc6a5d4c72fa7675dfd5674818 (diff)
media: staging/imx: Switch to sync registration for IPU subdevs
Because the IPU sub-devices VDIC and IC are not present in the device-tree, platform devices were created for them instead. This allowed these sub-devices to be added to the media device's async notifier and registered asynchronously along with the other sub-devices that do have a device-tree presence (CSI and devices external to the IPU and SoC). But that approach isn't really necessary. The IPU sub-devices don't actually require a backing device (sd->dev is allowed to be NULL). And that approach can't get around the fact that the IPU sub-devices are not part of a device hierarchy, which makes it awkward to retrieve the parent IPU of these devices. By registering them synchronously, they can be registered from the CSI async bound notifier, so the init function for them can be given the CSI subdev, who's dev->parent is the IPU. That is a somewhat cleaner way to retrieve the parent IPU. So convert to synchronous registration for the VDIC and IC task sub-devices, at the time a CSI sub-device is bound. There is no longer a backing device for them (sd->dev is NULL), but that's ok. Also set the VDIC/IC sub-device owner as the IPU, so that a reference can be taken on the IPU module. Since the VDIC and IC task drivers are no longer platform drivers, they are now statically linked to imx-media module. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/staging/media/imx/imx-ic-prp.c')
-rw-r--r--drivers/staging/media/imx/imx-ic-prp.c34
1 files changed, 13 insertions, 21 deletions
diff --git a/drivers/staging/media/imx/imx-ic-prp.c b/drivers/staging/media/imx/imx-ic-prp.c
index 10ffe00f1a54..3caeba38638c 100644
--- a/drivers/staging/media/imx/imx-ic-prp.c
+++ b/drivers/staging/media/imx/imx-ic-prp.c
@@ -35,16 +35,12 @@
#define S_ALIGN 1 /* multiple of 2 */
struct prp_priv {
- struct imx_media_dev *md;
struct imx_ic_priv *ic_priv;
struct media_pad pad[PRP_NUM_PADS];
/* lock to protect all members below */
struct mutex lock;
- /* IPU units we require */
- struct ipu_soc *ipu;
-
struct v4l2_subdev *src_sd;
struct v4l2_subdev *sink_sd_prpenc;
struct v4l2_subdev *sink_sd_prpvf;
@@ -62,7 +58,7 @@ static inline struct prp_priv *sd_to_priv(struct v4l2_subdev *sd)
{
struct imx_ic_priv *ic_priv = v4l2_get_subdevdata(sd);
- return ic_priv->prp_priv;
+ return ic_priv->task_priv;
}
static int prp_start(struct prp_priv *priv)
@@ -70,12 +66,10 @@ static int prp_start(struct prp_priv *priv)
struct imx_ic_priv *ic_priv = priv->ic_priv;
bool src_is_vdic;
- priv->ipu = priv->md->ipu[ic_priv->ipu_id];
-
/* set IC to receive from CSI or VDI depending on source */
src_is_vdic = !!(priv->src_sd->grp_id & IMX_MEDIA_GRP_ID_IPU_VDIC);
- ipu_set_ic_src_mux(priv->ipu, priv->csi_id, src_is_vdic);
+ ipu_set_ic_src_mux(ic_priv->ipu, priv->csi_id, src_is_vdic);
return 0;
}
@@ -216,12 +210,12 @@ static int prp_link_setup(struct media_entity *entity,
{
struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
struct imx_ic_priv *ic_priv = v4l2_get_subdevdata(sd);
- struct prp_priv *priv = ic_priv->prp_priv;
+ struct prp_priv *priv = ic_priv->task_priv;
struct v4l2_subdev *remote_sd;
int ret = 0;
- dev_dbg(ic_priv->dev, "link setup %s -> %s", remote->entity->name,
- local->entity->name);
+ dev_dbg(ic_priv->ipu_dev, "%s: link setup %s -> %s",
+ ic_priv->sd.name, remote->entity->name, local->entity->name);
remote_sd = media_entity_to_v4l2_subdev(remote->entity);
@@ -295,7 +289,7 @@ static int prp_link_validate(struct v4l2_subdev *sd,
struct v4l2_subdev_format *sink_fmt)
{
struct imx_ic_priv *ic_priv = v4l2_get_subdevdata(sd);
- struct prp_priv *priv = ic_priv->prp_priv;
+ struct prp_priv *priv = ic_priv->task_priv;
struct v4l2_subdev *csi;
int ret;
@@ -304,7 +298,7 @@ static int prp_link_validate(struct v4l2_subdev *sd,
if (ret)
return ret;
- csi = imx_media_find_upstream_subdev(priv->md, &ic_priv->sd.entity,
+ csi = imx_media_find_upstream_subdev(ic_priv->md, &ic_priv->sd.entity,
IMX_MEDIA_GRP_ID_IPU_CSI);
if (IS_ERR(csi))
csi = NULL;
@@ -351,7 +345,7 @@ out:
static int prp_s_stream(struct v4l2_subdev *sd, int enable)
{
struct imx_ic_priv *ic_priv = v4l2_get_subdevdata(sd);
- struct prp_priv *priv = ic_priv->prp_priv;
+ struct prp_priv *priv = ic_priv->task_priv;
int ret = 0;
mutex_lock(&priv->lock);
@@ -368,7 +362,8 @@ static int prp_s_stream(struct v4l2_subdev *sd, int enable)
if (priv->stream_count != !enable)
goto update_count;
- dev_dbg(ic_priv->dev, "stream %s\n", enable ? "ON" : "OFF");
+ dev_dbg(ic_priv->ipu_dev, "%s: stream %s\n", sd->name,
+ enable ? "ON" : "OFF");
if (enable)
ret = prp_start(priv);
@@ -440,9 +435,6 @@ static int prp_registered(struct v4l2_subdev *sd)
int i, ret;
u32 code;
- /* get media device */
- priv->md = dev_get_drvdata(sd->v4l2_dev->dev);
-
for (i = 0; i < PRP_NUM_PADS; i++) {
priv->pad[i].flags = (i == PRP_SINK_PAD) ?
MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
@@ -494,12 +486,12 @@ static int prp_init(struct imx_ic_priv *ic_priv)
{
struct prp_priv *priv;
- priv = devm_kzalloc(ic_priv->dev, sizeof(*priv), GFP_KERNEL);
+ priv = devm_kzalloc(ic_priv->ipu_dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
mutex_init(&priv->lock);
- ic_priv->prp_priv = priv;
+ ic_priv->task_priv = priv;
priv->ic_priv = ic_priv;
return 0;
@@ -507,7 +499,7 @@ static int prp_init(struct imx_ic_priv *ic_priv)
static void prp_remove(struct imx_ic_priv *ic_priv)
{
- struct prp_priv *priv = ic_priv->prp_priv;
+ struct prp_priv *priv = ic_priv->task_priv;
mutex_destroy(&priv->lock);
}