From d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 11 Dec 2023 02:45:28 +0000 Subject: [PATCH] add boot partition size --- kernel/drivers/staging/media/imx/imx6-mipi-csi2.c | 131 ++++++++++++++++++++++++++----------------- 1 files changed, 80 insertions(+), 51 deletions(-) diff --git a/kernel/drivers/staging/media/imx/imx6-mipi-csi2.c b/kernel/drivers/staging/media/imx/imx6-mipi-csi2.c index 212fa06..9457761 100644 --- a/kernel/drivers/staging/media/imx/imx6-mipi-csi2.c +++ b/kernel/drivers/staging/media/imx/imx6-mipi-csi2.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * MIPI CSI-2 Receiver Subdev for Freescale i.MX6 SOC. * * Copyright (c) 2012-2017 Mentor Graphics Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include <linux/clk.h> #include <linux/interrupt.h> @@ -18,6 +14,7 @@ #include <linux/platform_device.h> #include <media/v4l2-device.h> #include <media/v4l2-fwnode.h> +#include <media/v4l2-mc.h> #include <media/v4l2-subdev.h> #include "imx-media.h" @@ -39,6 +36,7 @@ struct csi2_dev { struct device *dev; struct v4l2_subdev sd; + struct v4l2_async_notifier notifier; struct media_pad pad[CSI2_NUM_PADS]; struct clk *dphy_clk; struct clk *pllref_clk; @@ -92,6 +90,11 @@ static inline struct csi2_dev *sd_to_dev(struct v4l2_subdev *sdev) { return container_of(sdev, struct csi2_dev, sd); +} + +static inline struct csi2_dev *notifier_to_dev(struct v4l2_async_notifier *n) +{ + return container_of(n, struct csi2_dev, notifier); } /* @@ -501,31 +504,19 @@ return ret; } -/* - * retrieve our pads parsed from the OF graph by the media device - */ static int csi2_registered(struct v4l2_subdev *sd) { struct csi2_dev *csi2 = sd_to_dev(sd); - int i, ret; - - for (i = 0; i < CSI2_NUM_PADS; i++) { - csi2->pad[i].flags = (i == CSI2_SINK_PAD) ? - MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; - } /* set a default mbus format */ - ret = imx_media_init_mbus_fmt(&csi2->format_mbus, + return imx_media_init_mbus_fmt(&csi2->format_mbus, 640, 480, 0, V4L2_FIELD_NONE, NULL); - if (ret) - return ret; - - return media_entity_pads_init(&sd->entity, CSI2_NUM_PADS, csi2->pad); } static const struct media_entity_operations csi2_entity_ops = { .link_setup = csi2_link_setup, .link_validate = v4l2_subdev_link_validate, + .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1, }; static const struct v4l2_subdev_video_ops csi2_video_ops = { @@ -547,38 +538,71 @@ .registered = csi2_registered, }; -static int csi2_parse_endpoints(struct csi2_dev *csi2) +static int csi2_notify_bound(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *sd, + struct v4l2_async_subdev *asd) { - struct device_node *node = csi2->dev->of_node; - struct device_node *epnode; - struct v4l2_fwnode_endpoint ep; + struct csi2_dev *csi2 = notifier_to_dev(notifier); + struct media_pad *sink = &csi2->sd.entity.pads[CSI2_SINK_PAD]; - epnode = of_graph_get_endpoint_by_regs(node, 0, -1); - if (!epnode) { - v4l2_err(&csi2->sd, "failed to get sink endpoint node\n"); - return -EINVAL; - } + return v4l2_create_fwnode_links_to_pad(sd, sink); +} - v4l2_fwnode_endpoint_parse(of_fwnode_handle(epnode), &ep); - of_node_put(epnode); +static const struct v4l2_async_notifier_operations csi2_notify_ops = { + .bound = csi2_notify_bound, +}; - if (ep.bus_type != V4L2_MBUS_CSI2) { - v4l2_err(&csi2->sd, "invalid bus type, must be MIPI CSI2\n"); - return -EINVAL; - } +static int csi2_async_register(struct csi2_dev *csi2) +{ + struct v4l2_fwnode_endpoint vep = { + .bus_type = V4L2_MBUS_CSI2_DPHY, + }; + struct v4l2_async_subdev *asd; + struct fwnode_handle *ep; + int ret; - csi2->bus = ep.bus.mipi_csi2; + v4l2_async_notifier_init(&csi2->notifier); + + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi2->dev), 0, 0, + FWNODE_GRAPH_ENDPOINT_NEXT); + if (!ep) + return -ENOTCONN; + + ret = v4l2_fwnode_endpoint_parse(ep, &vep); + if (ret) + goto err_parse; + + csi2->bus = vep.bus.mipi_csi2; dev_dbg(csi2->dev, "data lanes: %d\n", csi2->bus.num_data_lanes); dev_dbg(csi2->dev, "flags: 0x%08x\n", csi2->bus.flags); - return 0; + + asd = v4l2_async_notifier_add_fwnode_remote_subdev( + &csi2->notifier, ep, sizeof(*asd)); + fwnode_handle_put(ep); + + if (IS_ERR(asd)) + return PTR_ERR(asd); + + csi2->notifier.ops = &csi2_notify_ops; + + ret = v4l2_async_subdev_notifier_register(&csi2->sd, + &csi2->notifier); + if (ret) + return ret; + + return v4l2_async_register_subdev(&csi2->sd); + +err_parse: + fwnode_handle_put(ep); + return ret; } static int csi2_probe(struct platform_device *pdev) { struct csi2_dev *csi2; struct resource *res; - int ret; + int i, ret; csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL); if (!csi2) @@ -593,33 +617,36 @@ csi2->sd.dev = &pdev->dev; csi2->sd.owner = THIS_MODULE; csi2->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; - strcpy(csi2->sd.name, DEVICE_NAME); + strscpy(csi2->sd.name, DEVICE_NAME, sizeof(csi2->sd.name)); csi2->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; csi2->sd.grp_id = IMX_MEDIA_GRP_ID_CSI2; - ret = csi2_parse_endpoints(csi2); + for (i = 0; i < CSI2_NUM_PADS; i++) { + csi2->pad[i].flags = (i == CSI2_SINK_PAD) ? + MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; + } + + ret = media_entity_pads_init(&csi2->sd.entity, CSI2_NUM_PADS, + csi2->pad); if (ret) return ret; csi2->pllref_clk = devm_clk_get(&pdev->dev, "ref"); if (IS_ERR(csi2->pllref_clk)) { v4l2_err(&csi2->sd, "failed to get pll reference clock\n"); - ret = PTR_ERR(csi2->pllref_clk); - return ret; + return PTR_ERR(csi2->pllref_clk); } csi2->dphy_clk = devm_clk_get(&pdev->dev, "dphy"); if (IS_ERR(csi2->dphy_clk)) { v4l2_err(&csi2->sd, "failed to get dphy clock\n"); - ret = PTR_ERR(csi2->dphy_clk); - return ret; + return PTR_ERR(csi2->dphy_clk); } csi2->pix_clk = devm_clk_get(&pdev->dev, "pix"); if (IS_ERR(csi2->pix_clk)) { v4l2_err(&csi2->sd, "failed to get pixel clock\n"); - ret = PTR_ERR(csi2->pix_clk); - return ret; + return PTR_ERR(csi2->pix_clk); } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -629,10 +656,8 @@ } csi2->base = devm_ioremap(&pdev->dev, res->start, PAGE_SIZE); - if (!csi2->base) { - v4l2_err(&csi2->sd, "failed to map CSI-2 registers\n"); + if (!csi2->base) return -ENOMEM; - } mutex_init(&csi2->lock); @@ -650,13 +675,15 @@ platform_set_drvdata(pdev, &csi2->sd); - ret = v4l2_async_register_subdev(&csi2->sd); + ret = csi2_async_register(csi2); if (ret) - goto dphy_off; + goto clean_notifier; return 0; -dphy_off: +clean_notifier: + v4l2_async_notifier_unregister(&csi2->notifier); + v4l2_async_notifier_cleanup(&csi2->notifier); clk_disable_unprepare(csi2->dphy_clk); pllref_off: clk_disable_unprepare(csi2->pllref_clk); @@ -670,6 +697,8 @@ struct v4l2_subdev *sd = platform_get_drvdata(pdev); struct csi2_dev *csi2 = sd_to_dev(sd); + v4l2_async_notifier_unregister(&csi2->notifier); + v4l2_async_notifier_cleanup(&csi2->notifier); v4l2_async_unregister_subdev(sd); clk_disable_unprepare(csi2->dphy_clk); clk_disable_unprepare(csi2->pllref_clk); -- Gitblit v1.6.2