diff options
Diffstat (limited to 'drivers/media/platform/exynos4-is/media-dev.c')
-rw-r--r-- | drivers/media/platform/exynos4-is/media-dev.c | 89 |
1 files changed, 47 insertions, 42 deletions
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 16dd660137a8..e636c33e847b 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -19,6 +19,7 @@ #include <linux/of_platform.h> #include <linux/of_device.h> #include <linux/of_graph.h> +#include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/types.h> @@ -92,7 +93,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p, switch (sd->grp_id) { case GRP_ID_SENSOR: sensor = sd; - /* fall through */ + fallthrough; case GRP_ID_FIMC_IS_SENSOR: p->subdevs[IDX_SENSOR] = sd; break; @@ -289,11 +290,26 @@ static int __fimc_pipeline_s_stream(struct exynos_media_pipeline *ep, bool on) { IDX_CSIS, IDX_FLITE, IDX_FIMC, IDX_SENSOR, IDX_IS_ISP }, }; struct fimc_pipeline *p = to_fimc_pipeline(ep); - struct fimc_md *fmd = entity_to_fimc_mdev(&p->subdevs[IDX_CSIS]->entity); enum fimc_subdev_index sd_id; int i, ret = 0; if (p->subdevs[IDX_SENSOR] == NULL) { + struct fimc_md *fmd; + struct v4l2_subdev *sd = p->subdevs[IDX_CSIS]; + + if (!sd) + sd = p->subdevs[IDX_FIMC]; + + if (!sd) { + /* + * If neither CSIS nor FIMC was set up, + * it's impossible to have any sensors + */ + return -ENODEV; + } + + fmd = entity_to_fimc_mdev(&sd->entity); + if (!fmd->user_subdev_api) { /* * Sensor must be already discovered if we @@ -379,21 +395,15 @@ static void fimc_md_pipelines_free(struct fimc_md *fmd) } } -/* Parse port node and register as a sub-device any sensor specified there. */ -static int fimc_md_parse_port_node(struct fimc_md *fmd, - struct device_node *port, - unsigned int index) +static int fimc_md_parse_one_endpoint(struct fimc_md *fmd, + struct device_node *ep) { + int index = fmd->num_sensors; struct fimc_source_info *pd = &fmd->sensor[index].pdata; - struct device_node *rem, *ep, *np; + struct device_node *rem, *np; struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 }; int ret; - /* Assume here a port node can have only one endpoint node. */ - ep = of_get_next_child(port, NULL); - if (!ep) - return 0; - ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &endpoint); if (ret) { of_node_put(ep); @@ -467,13 +477,28 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd, return 0; } +/* Parse port node and register as a sub-device any sensor specified there. */ +static int fimc_md_parse_port_node(struct fimc_md *fmd, + struct device_node *port) +{ + struct device_node *ep; + int ret; + + for_each_child_of_node(port, ep) { + ret = fimc_md_parse_one_endpoint(fmd, ep); + if (ret < 0) + return ret; + } + + return 0; +} + /* Register all SoC external sub-devices */ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) { struct device_node *parent = fmd->pdev->dev.of_node; struct device_node *ports = NULL; struct device_node *node; - int index = 0; int ret; /* @@ -484,8 +509,10 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) return -ENXIO; ret = pm_runtime_get_sync(fmd->pmf); - if (ret < 0) + if (ret < 0) { + pm_runtime_put(fmd->pmf); return ret; + } fmd->num_sensors = 0; @@ -500,13 +527,12 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) if (!port) continue; - ret = fimc_md_parse_port_node(fmd, port, index); + ret = fimc_md_parse_port_node(fmd, port); of_node_put(port); if (ret < 0) { of_node_put(node); goto cleanup; } - index++; } /* Attach sensors listed in the parallel-ports node */ @@ -515,12 +541,11 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) goto rpm_put; for_each_child_of_node(ports, node) { - ret = fimc_md_parse_port_node(fmd, node, index); + ret = fimc_md_parse_port_node(fmd, node); if (ret < 0) { of_node_put(node); goto cleanup; } - index++; } of_node_put(ports); @@ -1254,28 +1279,6 @@ static ssize_t fimc_md_sysfs_store(struct device *dev, static DEVICE_ATTR(subdev_conf_mode, S_IWUSR | S_IRUGO, fimc_md_sysfs_show, fimc_md_sysfs_store); -static int fimc_md_get_pinctrl(struct fimc_md *fmd) -{ - struct device *dev = &fmd->pdev->dev; - struct fimc_pinctrl *pctl = &fmd->pinctl; - - pctl->pinctrl = devm_pinctrl_get(dev); - if (IS_ERR(pctl->pinctrl)) - return PTR_ERR(pctl->pinctrl); - - pctl->state_default = pinctrl_lookup_state(pctl->pinctrl, - PINCTRL_STATE_DEFAULT); - if (IS_ERR(pctl->state_default)) - return PTR_ERR(pctl->state_default); - - pctl->state_idle = pinctrl_lookup_state(pctl->pinctrl, - PINCTRL_STATE_IDLE); - if (IS_ERR(pctl->state_idle)) - return PTR_ERR(pctl->state_idle); - - return 0; -} - static int cam_clk_prepare(struct clk_hw *hw) { struct cam_clk *camclk = to_cam_clk(hw); @@ -1431,6 +1434,7 @@ static int fimc_md_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct v4l2_device *v4l2_dev; + struct pinctrl *pinctrl; struct fimc_md *fmd; int ret; @@ -1467,8 +1471,9 @@ static int fimc_md_probe(struct platform_device *pdev) if (ret) goto err_v4l2dev; - ret = fimc_md_get_pinctrl(fmd); - if (ret < 0) { + pinctrl = devm_pinctrl_get(dev); + if (IS_ERR(pinctrl)) { + ret = PTR_ERR(pinctrl); if (ret != EPROBE_DEFER) dev_err(dev, "Failed to get pinctrl: %d\n", ret); goto err_clk; |