diff options
author | Jacopo Mondi <jacopo+renesas@jmondi.org> | 2018-09-17 14:30:54 +0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-10-04 21:47:56 +0300 |
commit | eccf442ce156ec2b4e06b1239d5fdcb0c732f63f (patch) | |
tree | 27fdff81a8f2fbf360ad9769e1caae13c7ff0f29 /drivers/media/i2c/adv748x/adv748x-csi2.c | |
parent | bf7464a7a81717518b0fc46b1af6dc9d9bf4ec90 (diff) | |
download | linux-eccf442ce156ec2b4e06b1239d5fdcb0c732f63f.tar.xz |
media: i2c: adv748x: Support probing a single output
Currently the adv748x driver will fail to probe unless both of its
output endpoints (TXA and TXB) are connected.
Make the driver support probing provided that there is at least one
input, and one output connected and protect the clean-up function from
accessing un-initialized fields.
Following patches will fix other uses of un-initialized TXs in the driver,
such as power management functions.
Tested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/i2c/adv748x/adv748x-csi2.c')
-rw-r--r-- | drivers/media/i2c/adv748x/adv748x-csi2.c | 18 |
1 files changed, 6 insertions, 12 deletions
diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c index 265d9f5290cf..b8e4ea7e18f4 100644 --- a/drivers/media/i2c/adv748x/adv748x-csi2.c +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c @@ -262,19 +262,10 @@ static int adv748x_csi2_init_controls(struct adv748x_csi2 *tx) int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) { - struct device_node *ep; int ret; - /* We can not use container_of to get back to the state with two TXs */ - tx->state = state; - tx->page = is_txa(tx) ? ADV748X_PAGE_TXA : ADV748X_PAGE_TXB; - - ep = state->endpoints[is_txa(tx) ? ADV748X_PORT_TXA : ADV748X_PORT_TXB]; - if (!ep) { - adv_err(state, "No endpoint found for %s\n", - is_txa(tx) ? "txa" : "txb"); - return -ENODEV; - } + if (!is_tx_enabled(tx)) + return 0; /* Initialise the virtual channel */ adv748x_csi2_set_virtual_channel(tx, 0); @@ -284,7 +275,7 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) is_txa(tx) ? "txa" : "txb"); /* Ensure that matching is based upon the endpoint fwnodes */ - tx->sd.fwnode = of_fwnode_handle(ep); + tx->sd.fwnode = of_fwnode_handle(state->endpoints[tx->port]); /* Register internal ops for incremental subdev registration */ tx->sd.internal_ops = &adv748x_csi2_internal_ops; @@ -317,6 +308,9 @@ err_free_media: void adv748x_csi2_cleanup(struct adv748x_csi2 *tx) { + if (!is_tx_enabled(tx)) + return; + v4l2_async_unregister_subdev(&tx->sd); media_entity_cleanup(&tx->sd.entity); v4l2_ctrl_handler_free(&tx->ctrl_hdl); |