* Re: [RFC PATCH] ARM: zynq: Use memcpy_toio instead of memcpy on smp bring-up
From: Luis Araneda @ 2019-08-06 1:52 UTC (permalink / raw)
To: Michal Simek
Cc: Russell King - ARM Linux admin, linux-arm-kernel, linux-kernel
In-Reply-To: <26427757-9ed1-36fa-3e4d-7357703ec548@xilinx.com>
Hi Michal,
Thanks for the review.
On Mon, Aug 5, 2019 at 5:53 AM Michal Simek <michal.simek@xilinx.com> wrote:
>
> On 31. 07. 19 6:12, Luis Araneda wrote:
> > Hi Russell,
> >
> > Thanks for reviewing.
> >
> > On Tue, Jul 30, 2019 at 6:47 AM Russell King - ARM Linux admin
> > <linux@armlinux.org.uk> wrote:
> >>
> >> On Tue, Jul 30, 2019 at 12:43:26AM -0400, Luis Araneda wrote:
> >>> This fixes a kernel panic (read overflow) on memcpy when
> >>> FORTIFY_SOURCE is enabled.
> > [...]
> >>
> >> I'm not convinced that this is correct. It looks like
> >> zynq_secondary_trampoline could be either ARM or Thumb code - there is
> >> no .arm directive before it. If it's ARM code, then this is fine. If
> >> Thumb code, then zynq_secondary_trampoline will be offset by one, and
> >> we will miss copying the first byte of code.
> >
> > You're right, I tested what happens if the zynq_secondary_trampoline
> > is ARM or Thumb by editing the file where it's defined, headsmp.S
> >
> > When the .arm directive is used, the CPU is brought-up correctly,
> > but if I use .thumb, I get the following message (no panic):
> >> CPU1: failed to come online
> >
> > This seems unrelated to solving the panic, as the message
> > even appears with memcpy and FORTIFY_SOURCE disabled.
> >
> > I could add the .arm directive to headsmp.S
> > Is that your expected solution?
> > Should that change be on a separate commit?
> >
> > I'd like to know Michal's opinion, as he wrote the code.
> >
>
> There are two things together. Thanks Russel to pointing to it.
> 1. How to support SMP in thumb2 mode?
> Adding .arm mode to headsmp.S which ensure that cpu starts in proper
> mode and correct code size is copied.
> And also point to secondary_startup_arm in zynq_boot_secondary to switch
> cpu from arm to thumb mode.
>
> 2. And the second is this patch to fix FORTIFY_SOURCE.
>
> Feel free to create the first patch too or I will do it myself.
I'll be sending the two patches as a series (I already tested that
they work), so they can be picked by the stable trees.
Thanks,
Luis Araneda.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v4 2/2] mmc: Add support for the ASPEED SD controller
From: Andrew Jeffery @ 2019-08-06 0:39 UTC (permalink / raw)
To: Adrian Hunter, linux-mmc
Cc: mark.rutland, devicetree, Ulf Hansson, linux-aspeed, Ryan Chen,
linux-kernel, Rob Herring, Joel Stanley, linux-arm-kernel
In-Reply-To: <497ab8d6-24aa-c505-a1fa-e71fa1560da1@intel.com>
On Mon, 5 Aug 2019, at 23:08, Adrian Hunter wrote:
> On 5/08/19 5:51 AM, Andrew Jeffery wrote:
> > Add a minimal driver for ASPEED's SD controller, which exposes two
> > SDHCIs.
> >
> > The ASPEED design implements a common register set for the SDHCIs, and
> > moves some of the standard configuration elements out to this common
> > area (e.g. 8-bit mode, and card detect configuration which is not
> > currently supported).
> >
> > The SD controller has a dedicated hardware interrupt that is shared
> > between the slots. The common register set exposes information on which
> > slot triggered the interrupt; early revisions of the patch introduced an
> > irqchip for the register, but reality is it doesn't behave as an
> > irqchip, and the result fits awkwardly into the irqchip APIs. Instead
> > I've taken the simple approach of using the IRQ as a shared IRQ with
> > some minor performance impact for the second slot.
> >
> > Ryan was the original author of the patch - I've taken his work and
> > massaged it to drop the irqchip support and rework the devicetree
> > integration. The driver has been smoke tested under qemu against a
> > minimal SD controller model and lightly tested on an ast2500-evb.
> >
> > Signed-off-by: Ryan Chen <ryanchen.aspeed@gmail.com>
> > Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
>
> One minor comment otherwise:
>
> Acked-by: Adrian Hunter <adrian.hunter@intel.com>
>
> >
> > ---
> > v3: No change
> > v2:
> > * Add AST2600 compatible
> > * Drop SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN
> > * Ensure slot number is valid
> > * Fix build with CONFIG_MODULES
> > * Fix module license string
> > * Non-PCI devices won't die
> > * Rename aspeed_sdc_configure_8bit_mode()
> > * Rename aspeed_sdhci_pdata
> > * Switch to sdhci_enable_clk()
> > * Use PTR_ERR() on the right `struct platform_device *`
> > ---
> > drivers/mmc/host/Kconfig | 12 ++
> > drivers/mmc/host/Makefile | 1 +
> > drivers/mmc/host/sdhci-of-aspeed.c | 328 +++++++++++++++++++++++++++++
> > 3 files changed, 341 insertions(+)
> > create mode 100644 drivers/mmc/host/sdhci-of-aspeed.c
> >
> > diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> > index 14d89a108edd..0f8a230de2f3 100644
> > --- a/drivers/mmc/host/Kconfig
> > +++ b/drivers/mmc/host/Kconfig
> > @@ -154,6 +154,18 @@ config MMC_SDHCI_OF_ARASAN
> >
> > If unsure, say N.
> >
> > +config MMC_SDHCI_OF_ASPEED
> > + tristate "SDHCI OF support for the ASPEED SDHCI controller"
> > + depends on MMC_SDHCI_PLTFM
> > + depends on OF
> > + help
> > + This selects the ASPEED Secure Digital Host Controller Interface.
> > +
> > + If you have a controller with this interface, say Y or M here. You
> > + also need to enable an appropriate bus interface.
> > +
> > + If unsure, say N.
> > +
> > config MMC_SDHCI_OF_AT91
> > tristate "SDHCI OF support for the Atmel SDMMC controller"
> > depends on MMC_SDHCI_PLTFM
> > diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
> > index 73578718f119..390ee162fe71 100644
> > --- a/drivers/mmc/host/Makefile
> > +++ b/drivers/mmc/host/Makefile
> > @@ -84,6 +84,7 @@ obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc-imx.o
> > obj-$(CONFIG_MMC_SDHCI_DOVE) += sdhci-dove.o
> > obj-$(CONFIG_MMC_SDHCI_TEGRA) += sdhci-tegra.o
> > obj-$(CONFIG_MMC_SDHCI_OF_ARASAN) += sdhci-of-arasan.o
> > +obj-$(CONFIG_MMC_SDHCI_OF_ASPEED) += sdhci-of-aspeed.o
> > obj-$(CONFIG_MMC_SDHCI_OF_AT91) += sdhci-of-at91.o
> > obj-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o
> > obj-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o
> > diff --git a/drivers/mmc/host/sdhci-of-aspeed.c b/drivers/mmc/host/sdhci-of-aspeed.c
> > new file mode 100644
> > index 000000000000..d31785ec90d7
> > --- /dev/null
> > +++ b/drivers/mmc/host/sdhci-of-aspeed.c
> > @@ -0,0 +1,328 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/* Copyright (C) 2019 ASPEED Technology Inc. */
> > +/* Copyright (C) 2019 IBM Corp. */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/device.h>
> > +#include <linux/io.h>
> > +#include <linux/mmc/host.h>
> > +#include <linux/module.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/spinlock.h>
> > +
> > +#include "sdhci-pltfm.h"
> > +
> > +#define ASPEED_SDC_INFO 0x00
> > +#define ASPEED_SDC_S1MMC8 BIT(25)
> > +#define ASPEED_SDC_S0MMC8 BIT(24)
> > +
> > +struct aspeed_sdc {
> > + struct clk *clk;
> > + struct resource *res;
> > +
> > + spinlock_t lock;
> > + void __iomem *regs;
> > +};
> > +
> > +struct aspeed_sdhci {
> > + struct aspeed_sdc *parent;
> > + u32 width_mask;
> > +};
> > +
> > +static void aspeed_sdc_configure_8bit_mode(struct aspeed_sdc *sdc,
> > + struct aspeed_sdhci *sdhci,
> > + bool bus8)
> > +{
> > + u32 info;
> > +
> > + /* Set/clear 8 bit mode */
> > + spin_lock(&sdc->lock);
> > + info = readl(sdc->regs + ASPEED_SDC_INFO);
> > + if (bus8)
> > + info |= sdhci->width_mask;
> > + else
> > + info &= ~sdhci->width_mask;
> > + writel(info, sdc->regs + ASPEED_SDC_INFO);
> > + spin_unlock(&sdc->lock);
> > +}
> > +
> > +static void aspeed_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
> > +{
> > + int div;
> > + u16 clk;
> > +
> > + if (clock == host->clock)
> > + return;
> > +
> > + sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
> > +
> > + if (clock == 0)
> > + goto out;
> > +
> > + for (div = 1; div < 256; div *= 2) {
> > + if ((host->max_clk / div) <= clock)
> > + break;
> > + }
> > + div >>= 1;
> > +
> > + clk = div << SDHCI_DIVIDER_SHIFT;
> > +
> > + sdhci_enable_clk(host, clk);
> > +
> > +out:
> > + host->clock = clock;
> > +}
> > +
> > +static void aspeed_sdhci_set_bus_width(struct sdhci_host *host, int width)
> > +{
> > + struct sdhci_pltfm_host *pltfm_priv;
> > + struct aspeed_sdhci *aspeed_sdhci;
> > + struct aspeed_sdc *aspeed_sdc;
> > + u8 ctrl;
> > +
> > + pltfm_priv = sdhci_priv(host);
> > + aspeed_sdhci = sdhci_pltfm_priv(pltfm_priv);
> > + aspeed_sdc = aspeed_sdhci->parent;
> > +
> > + /* Set/clear 8-bit mode */
> > + aspeed_sdc_configure_8bit_mode(aspeed_sdc, aspeed_sdhci,
> > + width == MMC_BUS_WIDTH_8);
> > +
> > + /* Set/clear 1 or 4 bit mode */
> > + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
> > + if (width == MMC_BUS_WIDTH_4)
> > + ctrl |= SDHCI_CTRL_4BITBUS;
> > + else
> > + ctrl &= ~SDHCI_CTRL_4BITBUS;
> > + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
> > +}
> > +
> > +static const struct sdhci_ops aspeed_sdhci_ops = {
> > + .set_clock = aspeed_sdhci_set_clock,
> > + .get_max_clock = sdhci_pltfm_clk_get_max_clock,
> > + .set_bus_width = aspeed_sdhci_set_bus_width,
> > + .get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
> > + .reset = sdhci_reset,
> > + .set_uhs_signaling = sdhci_set_uhs_signaling,
> > +};
> > +
> > +static const struct sdhci_pltfm_data aspeed_sdhci_pdata = {
> > + .ops = &aspeed_sdhci_ops,
> > + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
> > +};
> > +
> > +static inline int aspeed_sdhci_calculate_slot(struct aspeed_sdhci *dev,
> > + struct resource *res)
> > +{
> > + resource_size_t delta;
> > +
> > + if (!res || resource_type(res) != IORESOURCE_MEM)
> > + return -EINVAL;
> > +
> > + if (res->start < dev->parent->res->start)
> > + return -EINVAL;
> > +
> > + delta = res->start - dev->parent->res->start;
> > + if (delta & (0x100 - 1))
> > + return -EINVAL;
> > +
> > + return (delta / 0x100) - 1;
> > +}
> > +
> > +static int aspeed_sdhci_probe(struct platform_device *pdev)
> > +{
> > + struct sdhci_pltfm_host *pltfm_host;
> > + struct aspeed_sdhci *dev;
> > + struct sdhci_host *host;
> > + struct resource *res;
> > + int slot;
> > + int ret;
> > +
> > + host = sdhci_pltfm_init(pdev, &aspeed_sdhci_pdata, sizeof(*dev));
> > + if (IS_ERR(host))
> > + return PTR_ERR(host);
> > +
> > + pltfm_host = sdhci_priv(host);
> > + dev = sdhci_pltfm_priv(pltfm_host);
> > + dev->parent = dev_get_drvdata(pdev->dev.parent);
> > +
> > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > + slot = aspeed_sdhci_calculate_slot(dev, res);
> > +
> > + if (slot < 0)
> > + return slot;
> > + else if (slot >= 2)
> > + return -EINVAL;
> > +
> > + dev_info(&pdev->dev, "Configuring for slot %d\n", slot);
> > + dev->width_mask = !slot ? ASPEED_SDC_S0MMC8 : ASPEED_SDC_S1MMC8;
> > +
> > + sdhci_get_of_property(pdev);
> > +
> > + pltfm_host->clk = devm_clk_get(&pdev->dev, NULL);
> > + if (IS_ERR(pltfm_host->clk))
> > + return PTR_ERR(pltfm_host->clk);
> > +
> > + ret = clk_prepare_enable(pltfm_host->clk);
> > + if (ret) {
> > + dev_err(&pdev->dev, "Unable to enable SDIO clock\n");
> > + goto err_pltfm_free;
> > + }
> > +
> > + ret = mmc_of_parse(host->mmc);
> > + if (ret)
> > + goto err_sdhci_add;
> > +
> > + ret = sdhci_add_host(host);
> > + if (ret)
> > + goto err_sdhci_add;
> > +
> > + return 0;
> > +
> > +err_sdhci_add:
> > + clk_disable_unprepare(pltfm_host->clk);
> > +err_pltfm_free:
> > + sdhci_pltfm_free(pdev);
> > + return ret;
> > +}
> > +
> > +static int aspeed_sdhci_remove(struct platform_device *pdev)
> > +{
> > + struct sdhci_pltfm_host *pltfm_host;
> > + struct sdhci_host *host;
> > + int dead = 0;
> > +
> > + host = platform_get_drvdata(pdev);
> > + pltfm_host = sdhci_priv(host);
> > +
> > + sdhci_remove_host(host, dead);
> > +
> > + clk_disable_unprepare(pltfm_host->clk);
> > +
> > + sdhci_pltfm_free(pdev);
> > +
> > + return 0;
> > +}
> > +
> > +static const struct of_device_id aspeed_sdhci_of_match[] = {
> > + { .compatible = "aspeed,ast2400-sdhci", },
> > + { .compatible = "aspeed,ast2500-sdhci", },
> > + { .compatible = "aspeed,ast2600-sdhci", },
> > + { }
> > +};
> > +
> > +static struct platform_driver aspeed_sdhci_driver = {
> > + .driver = {
> > + .name = "sdhci-aspeed",
> > + .of_match_table = aspeed_sdhci_of_match,
> > + },
> > + .probe = aspeed_sdhci_probe,
> > + .remove = aspeed_sdhci_remove,
> > +};
> > +
> > +static int aspeed_sdc_probe(struct platform_device *pdev)
> > +
> > +{
> > + struct device_node *parent, *child;
> > + struct aspeed_sdc *sdc;
> > + int ret;
> > +
> > + sdc = devm_kzalloc(&pdev->dev, sizeof(*sdc), GFP_KERNEL);
> > + if (!sdc)
> > + return -ENOMEM;
> > +
> > + spin_lock_init(&sdc->lock);
> > +
> > + sdc->clk = devm_clk_get(&pdev->dev, NULL);
> > + if (IS_ERR(sdc->clk))
> > + return PTR_ERR(sdc->clk);
> > +
> > + ret = clk_prepare_enable(sdc->clk);
> > + if (ret) {
> > + dev_err(&pdev->dev, "Unable to enable SDCLK\n");
> > + return ret;
> > + }
> > +
> > + sdc->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > + sdc->regs = devm_ioremap_resource(&pdev->dev, sdc->res);
> > + if (IS_ERR(sdc->regs)) {
> > + ret = PTR_ERR(sdc->regs);
> > + goto err_clk;
> > + }
> > +
> > + dev_set_drvdata(&pdev->dev, sdc);
> > +
> > + parent = pdev->dev.of_node;
> > + for_each_available_child_of_node(parent, child) {
> > + struct platform_device *cpdev;
> > +
> > + cpdev = of_platform_device_create(child, NULL, &pdev->dev);
> > + if (IS_ERR(cpdev)) {
> > + of_node_put(child);
> > + ret = PTR_ERR(cpdev);
> > + goto err_clk;
> > + }
> > + }
> > +
> > + return 0;
> > +
> > +err_clk:
> > + clk_disable_unprepare(sdc->clk);
> > + return ret;
> > +}
> > +
> > +static int aspeed_sdc_remove(struct platform_device *pdev)
> > +{
> > + struct aspeed_sdc *sdc = dev_get_drvdata(&pdev->dev);
> > +
> > + clk_disable_unprepare(sdc->clk);
> > +
> > + return 0;
> > +}
> > +
> > +static const struct of_device_id aspeed_sdc_of_match[] = {
> > + { .compatible = "aspeed,ast2400-sd-controller", },
> > + { .compatible = "aspeed,ast2500-sd-controller", },
> > + { .compatible = "aspeed,ast2600-sd-controller", },
> > + { }
> > +};
> > +
> > +MODULE_DEVICE_TABLE(of, aspeed_sdc_of_match);
> > +
> > +static struct platform_driver aspeed_sdc_driver = {
> > + .driver = {
> > + .name = "sd-controller-aspeed",
> > + .pm = &sdhci_pltfm_pmops,
> > + .of_match_table = aspeed_sdc_of_match,
> > + },
> > + .probe = aspeed_sdc_probe,
> > + .remove = aspeed_sdc_remove,
> > +};
> > +
> > +static int __init aspeed_sdc_init(void)
> > +{
> > + int rc;
> > +
> > + rc = platform_driver_register(&aspeed_sdhci_driver);
> > + if (rc < 0)
> > + return rc;
> > +
> > + return platform_driver_register(&aspeed_sdc_driver);
>
> Shouldn't aspeed_sdhci_driver be unregistered here if there was an error.
Yeah, fair point. I'll send a v5 to fix that.
Thanks for the feedback.
Andrew
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] coresight: tmc-etr: Fix updating buffer in not-snapshot mode.
From: Yabin Cui @ 2019-08-05 23:37 UTC (permalink / raw)
To: Mathieu Poirier, Suzuki K Poulose, Alexander Shishkin
Cc: Yabin Cui, linux-kernel, linux-arm-kernel
TMC etr always copies all available data to perf aux buffer, which
may exceed the available space in perf aux buffer. It isn't suitable
for not-snapshot mode, because:
1) It may overwrite previously written data.
2) It may make the perf_event_mmap_page->aux_head report having more
or less data than the reality.
Signed-off-by: Yabin Cui <yabinc@google.com>
---
drivers/hwtracing/coresight/coresight-tmc-etr.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index 17006705287a..697e68d492af 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1410,9 +1410,10 @@ static void tmc_free_etr_buffer(void *config)
* tmc_etr_sync_perf_buffer: Copy the actual trace data from the hardware
* buffer to the perf ring buffer.
*/
-static void tmc_etr_sync_perf_buffer(struct etr_perf_buffer *etr_perf)
+static void tmc_etr_sync_perf_buffer(struct etr_perf_buffer *etr_perf,
+ unsigned long to_copy)
{
- long bytes, to_copy;
+ long bytes;
long pg_idx, pg_offset, src_offset;
unsigned long head = etr_perf->head;
char **dst_pages, *src_buf;
@@ -1423,7 +1424,6 @@ static void tmc_etr_sync_perf_buffer(struct etr_perf_buffer *etr_perf)
pg_offset = head & (PAGE_SIZE - 1);
dst_pages = (char **)etr_perf->pages;
src_offset = etr_buf->offset;
- to_copy = etr_buf->len;
while (to_copy > 0) {
/*
@@ -1501,7 +1501,11 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
spin_unlock_irqrestore(&drvdata->spinlock, flags);
size = etr_buf->len;
- tmc_etr_sync_perf_buffer(etr_perf);
+ if (!etr_perf->snapshot && size > handle->size) {
+ size = handle->size;
+ lost = true;
+ }
+ tmc_etr_sync_perf_buffer(etr_perf, size);
/*
* In snapshot mode we simply increment the head by the number of byte
--
2.22.0.770.g0f2c4a37fd-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 22/22] media: imx: TODO: Remove issues regarding media link creation
From: Steve Longerbeam @ 2019-08-05 23:35 UTC (permalink / raw)
To: linux-media
Cc: open list:STAGING SUBSYSTEM, Fabio Estevam,
Pengutronix Kernel Team, Greg Kroah-Hartman, Sascha Hauer,
open list, NXP Linux Team, Philipp Zabel, Steve Longerbeam,
Mauro Carvalho Chehab, Shawn Guo,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190805233505.21167-1-slongerbeam@gmail.com>
Remove the TODO items regarding media link creation, these issues are
resolved after exporting media link creation to individual entity bound
callbacks and the use of media_create_fwnode_links(),
media_create_fwnode_pad_links(), and media_entity_get_fwnode_pad().
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
drivers/staging/media/imx/TODO | 29 -----------------------------
1 file changed, 29 deletions(-)
diff --git a/drivers/staging/media/imx/TODO b/drivers/staging/media/imx/TODO
index 6f29b5ca5324..a371cdedcdb0 100644
--- a/drivers/staging/media/imx/TODO
+++ b/drivers/staging/media/imx/TODO
@@ -17,35 +17,6 @@
decided whether this feature is useful enough to make it generally
available by exporting to v4l2-core.
-- After all async subdevices have been bound, v4l2_fwnode_parse_link()
- is used to form the media links between the devices discovered in
- the OF graph.
-
- While this approach allows support for arbitrary OF graphs, there
- are some assumptions for this to work:
-
- 1. If a port owned by a device in the graph has endpoint nodes, the
- port is treated as a media pad.
-
- This presents problems for devices that don't make this port = pad
- assumption. Examples are SMIAPP compatible cameras which define only
- a single output port node, but which define multiple pads owned
- by multiple subdevices (pixel-array, binner, scaler). Or video
- decoders (entity function MEDIA_ENT_F_ATV_DECODER), which also define
- only a single output port node, but define multiple pads for video,
- VBI, and audio out.
-
- A workaround at present is to set the port reg properties to
- correspond to the media pad index that the port represents. A
- possible long-term solution is to implement a subdev API that
- maps a port id to a media pad index.
-
- 2. Every endpoint of a port owned by a device in the graph is treated
- as a media link.
-
- Which means a port must not contain mixed-use endpoints, they
- must all refer to media links between V4L2 subdevices.
-
- i.MX7: all of the above, since it uses the imx media core
- i.MX7: use Frame Interval Monitor
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 21/22] media: imx: Use media_create_fwnode_links for external links
From: Steve Longerbeam @ 2019-08-05 23:35 UTC (permalink / raw)
To: linux-media
Cc: open list:STAGING SUBSYSTEM, Fabio Estevam,
Pengutronix Kernel Team, Greg Kroah-Hartman, Sascha Hauer,
open list, NXP Linux Team, Philipp Zabel, Steve Longerbeam,
Mauro Carvalho Chehab, Shawn Guo,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190805233505.21167-1-slongerbeam@gmail.com>
The entities external to the i.MX6 IPU and i.MX7 now create the links
to their fwnode-endpoint connected entities in their notifier bound
callbacks.
This should mean that there is no longer a need for the imx-media driver
to create these external fwnode-endpoint based links. But the v4l2-async
framework does not allow multiple subdevice notifiers to contain a
duplicate subdevice in their asd_list. Only the first subdev notifier that
discovers and adds that one subdevice to its asd_list will receive a bound
callback for it. Other subdevices that also have firmware endpoint
connections to this duplicate subdevice will not have it in their asd_list,
and thus will never receive a bound callback for it.
Until there is a solution to that problem, imx_media_create_links() is
still needed to create media links for subdevices that never received a
bound callback.
But media_create_fwnode_links() can now be used to do that work, so
imx_media_create_of_links() and imx_media_create_csi_of_links() are
removed.
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
.../staging/media/imx/imx-media-dev-common.c | 49 ++++----
drivers/staging/media/imx/imx-media-of.c | 113 ------------------
drivers/staging/media/imx/imx-media.h | 4 -
3 files changed, 27 insertions(+), 139 deletions(-)
diff --git a/drivers/staging/media/imx/imx-media-dev-common.c b/drivers/staging/media/imx/imx-media-dev-common.c
index 66b505f7e8df..4dbe983af030 100644
--- a/drivers/staging/media/imx/imx-media-dev-common.c
+++ b/drivers/staging/media/imx/imx-media-dev-common.c
@@ -36,31 +36,36 @@ static int imx_media_subdev_bound(struct v4l2_async_notifier *notifier,
static int imx_media_create_links(struct v4l2_async_notifier *notifier)
{
struct imx_media_dev *imxmd = notifier2dev(notifier);
- struct v4l2_subdev *sd;
+ struct fwnode_handle *sda_fwnode, *sdb_fwnode;
+ struct v4l2_subdev *sda, *sdb;
+
+ list_for_each_entry(sda, &imxmd->v4l2_dev.subdevs, list) {
+ /* links have already been created for the IPU subdevs */
+ if (is_ipu_internal_subdev(sda))
+ continue;
+
+ sda_fwnode = (sda->grp_id & IMX_MEDIA_GRP_ID_IPU_CSI) ?
+ dev_fwnode(sda->dev->parent) :
+ dev_fwnode(sda->dev);
+
+ list_for_each_entry(sdb, &imxmd->v4l2_dev.subdevs, list) {
+ if (sda == sdb)
+ continue;
+ if (is_ipu_internal_subdev(sdb))
+ continue;
+
+ sdb_fwnode = (sdb->grp_id & IMX_MEDIA_GRP_ID_IPU_CSI) ?
+ dev_fwnode(sdb->dev->parent) :
+ dev_fwnode(sdb->dev);
- list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) {
- switch (sd->grp_id) {
- case IMX_MEDIA_GRP_ID_IPU_VDIC:
- case IMX_MEDIA_GRP_ID_IPU_IC_PRP:
- case IMX_MEDIA_GRP_ID_IPU_IC_PRPENC:
- case IMX_MEDIA_GRP_ID_IPU_IC_PRPVF:
- /*
- * links have already been created for the
- * sync-registered subdevs.
- */
- break;
- case IMX_MEDIA_GRP_ID_IPU_CSI0:
- case IMX_MEDIA_GRP_ID_IPU_CSI1:
- case IMX_MEDIA_GRP_ID_CSI:
- imx_media_create_csi_of_links(imxmd, sd);
- break;
- default:
/*
- * if this subdev has fwnode links, create media
- * links for them.
+ * if there are fwnode endpoint connections between
+ * these subdevs, create media links for them.
*/
- imx_media_create_of_links(imxmd, sd);
- break;
+ __media_create_fwnode_links(&sda->entity,
+ sda_fwnode,
+ &sdb->entity,
+ sdb_fwnode, 0);
}
}
diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c
index 736c954a8ff5..82e13e972e23 100644
--- a/drivers/staging/media/imx/imx-media-of.c
+++ b/drivers/staging/media/imx/imx-media-of.c
@@ -74,116 +74,3 @@ int imx_media_add_of_subdevs(struct imx_media_dev *imxmd,
return ret;
}
EXPORT_SYMBOL_GPL(imx_media_add_of_subdevs);
-
-/*
- * Create a single media link to/from sd using a fwnode link.
- *
- * NOTE: this function assumes an OF port node is equivalent to
- * a media pad (port id equal to media pad index), and that an
- * OF endpoint node is equivalent to a media link.
- */
-static int create_of_link(struct imx_media_dev *imxmd,
- struct v4l2_subdev *sd,
- struct fwnode_link *link)
-{
- struct v4l2_subdev *remote, *src, *sink;
- int src_pad, sink_pad;
-
- if (link->local.port >= sd->entity.num_pads)
- return -EINVAL;
-
- remote = imx_media_find_subdev_by_fwnode(imxmd,
- link->remote_port_parent);
- if (!remote)
- return 0;
-
- if (sd->entity.pads[link->local.port].flags & MEDIA_PAD_FL_SINK) {
- src = remote;
- src_pad = link->remote.port;
- sink = sd;
- sink_pad = link->local.port;
- } else {
- src = sd;
- src_pad = link->local.port;
- sink = remote;
- sink_pad = link->remote.port;
- }
-
- /* make sure link doesn't already exist before creating */
- if (media_entity_find_link(&src->entity.pads[src_pad],
- &sink->entity.pads[sink_pad]))
- return 0;
-
- v4l2_info(sd->v4l2_dev, "%s:%d -> %s:%d\n",
- src->name, src_pad, sink->name, sink_pad);
-
- return media_create_pad_link(&src->entity, src_pad,
- &sink->entity, sink_pad, 0);
-}
-
-/*
- * Create media links to/from sd using its device-tree endpoints.
- */
-int imx_media_create_of_links(struct imx_media_dev *imxmd,
- struct v4l2_subdev *sd)
-{
- struct fwnode_handle *endpoint;
- struct fwnode_link link;
- int ret;
-
- fwnode_graph_for_each_endpoint(dev_fwnode(sd->dev), endpoint) {
- ret = fwnode_graph_parse_link(endpoint, &link);
- if (ret)
- continue;
-
- ret = create_of_link(imxmd, sd, &link);
- fwnode_graph_put_link(&link);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(imx_media_create_of_links);
-
-/*
- * Create media links to the given CSI subdevice's sink pads,
- * using its device-tree endpoints.
- */
-int imx_media_create_csi_of_links(struct imx_media_dev *imxmd,
- struct v4l2_subdev *csi)
-{
- struct fwnode_handle *csi_np = dev_fwnode(csi->dev);
- struct fwnode_handle *csi_ep;
-
- fwnode_for_each_child_node(csi_np, csi_ep) {
- struct fwnode_handle *fwnode;
- struct fwnode_link link;
- int ret;
-
- memset(&link, 0, sizeof(link));
-
- link.local_port_parent = csi_np;
- link.local.port = CSI_SINK_PAD;
-
- fwnode = fwnode_graph_get_remote_endpoint(csi_ep);
- if (!fwnode)
- continue;
-
- fwnode = fwnode_get_parent(fwnode);
- fwnode_property_read_u32(fwnode, "reg", &link.remote.port);
- fwnode = fwnode_get_next_parent(fwnode);
- if (is_of_node(fwnode) &&
- of_node_name_eq(to_of_node(fwnode), "ports"))
- fwnode = fwnode_get_next_parent(fwnode);
- link.remote_port_parent = fwnode;
-
- ret = create_of_link(imxmd, csi, &link);
- fwnode_handle_put(link.remote_port_parent);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(imx_media_create_csi_of_links);
diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h
index c42a2cafb8fb..7bdeecd29248 100644
--- a/drivers/staging/media/imx/imx-media.h
+++ b/drivers/staging/media/imx/imx-media.h
@@ -238,10 +238,6 @@ void imx_media_unregister_ipu_internal_subdevs(struct imx_media_dev *imxmd);
/* imx-media-of.c */
int imx_media_add_of_subdevs(struct imx_media_dev *dev,
struct device_node *np);
-int imx_media_create_of_links(struct imx_media_dev *imxmd,
- struct v4l2_subdev *sd);
-int imx_media_create_csi_of_links(struct imx_media_dev *imxmd,
- struct v4l2_subdev *csi);
int imx_media_of_add_csi(struct imx_media_dev *imxmd,
struct device_node *csi_np);
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 20/22] media: imx: Add is_ipu_internal_subdev()
From: Steve Longerbeam @ 2019-08-05 23:35 UTC (permalink / raw)
To: linux-media
Cc: open list:STAGING SUBSYSTEM, Fabio Estevam,
Pengutronix Kernel Team, Greg Kroah-Hartman, Sascha Hauer,
open list, NXP Linux Team, Philipp Zabel, Steve Longerbeam,
Mauro Carvalho Chehab, Shawn Guo,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190805233505.21167-1-slongerbeam@gmail.com>
Add a convenience inline function that returns true if the given
subdevice is one of the i.MX5/6 IPU-internal subdevices.
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
drivers/staging/media/imx/imx-media.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h
index d75b3c80101a..c42a2cafb8fb 100644
--- a/drivers/staging/media/imx/imx-media.h
+++ b/drivers/staging/media/imx/imx-media.h
@@ -282,4 +282,12 @@ void imx_media_capture_device_error(struct imx_media_video_dev *vdev);
#define IMX_MEDIA_GRP_ID_IPU_IC_PRPENC BIT(14)
#define IMX_MEDIA_GRP_ID_IPU_IC_PRPVF BIT(15)
+static inline bool is_ipu_internal_subdev(struct v4l2_subdev *sd)
+{
+ return sd->grp_id == IMX_MEDIA_GRP_ID_IPU_VDIC ||
+ sd->grp_id == IMX_MEDIA_GRP_ID_IPU_IC_PRP ||
+ sd->grp_id == IMX_MEDIA_GRP_ID_IPU_IC_PRPENC ||
+ sd->grp_id == IMX_MEDIA_GRP_ID_IPU_IC_PRPVF;
+}
+
#endif
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 19/22] media: imx: csi: Lookup endpoint fwnode with media_entity_get_fwnode_pad
From: Steve Longerbeam @ 2019-08-05 23:35 UTC (permalink / raw)
To: linux-media
Cc: open list:STAGING SUBSYSTEM, Fabio Estevam,
Pengutronix Kernel Team, Greg Kroah-Hartman, Sascha Hauer,
open list, Rui Miguel Silva, NXP Linux Team, Philipp Zabel,
Steve Longerbeam, Mauro Carvalho Chehab, Shawn Guo,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190805233505.21167-1-slongerbeam@gmail.com>
Fix the 1:1 port-id:pad-index assumption for the upstream subdevice
connected to a CSI via one of the subdevice's pads, by searching the
upstream subdevice's endpoints for one that maps to the pad's index,
using media_entity_get_fwnode_pad(). This is carried out by a new
reverse mapping function imx_media_get_pad_fwnode().
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
drivers/staging/media/imx/imx-media-csi.c | 22 ++++----------
drivers/staging/media/imx/imx-media-utils.c | 33 +++++++++++++++++++++
drivers/staging/media/imx/imx-media.h | 1 +
drivers/staging/media/imx/imx7-media-csi.c | 25 +++++-----------
4 files changed, 47 insertions(+), 34 deletions(-)
diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index 37b10cbf3c1a..38e70082ff2d 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -164,7 +164,7 @@ static inline bool requires_passthrough(struct v4l2_fwnode_endpoint *ep,
static int csi_get_upstream_endpoint(struct csi_priv *priv,
struct v4l2_fwnode_endpoint *ep)
{
- struct device_node *endpoint, *port;
+ struct fwnode_handle *endpoint;
struct media_entity *src;
struct v4l2_subdev *sd;
struct media_pad *pad;
@@ -203,23 +203,13 @@ static int csi_get_upstream_endpoint(struct csi_priv *priv,
if (!pad)
return -ENODEV;
- sd = media_entity_to_v4l2_subdev(pad->entity);
+ endpoint = imx_media_get_pad_fwnode(pad);
+ if (IS_ERR(endpoint))
+ return PTR_ERR(endpoint);
- /*
- * NOTE: this assumes an OF-graph port id is the same as a
- * media pad index.
- */
- port = of_graph_get_port_by_id(sd->dev->of_node, pad->index);
- if (!port)
- return -ENODEV;
-
- endpoint = of_get_next_child(port, NULL);
- of_node_put(port);
- if (!endpoint)
- return -ENODEV;
+ v4l2_fwnode_endpoint_parse(endpoint, ep);
- v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), ep);
- of_node_put(endpoint);
+ fwnode_handle_put(endpoint);
return 0;
}
diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c
index 4cc6a7462ae2..2e4f27c214c4 100644
--- a/drivers/staging/media/imx/imx-media-utils.c
+++ b/drivers/staging/media/imx/imx-media-utils.c
@@ -908,6 +908,39 @@ imx_media_pipeline_video_device(struct media_entity *start_entity,
}
EXPORT_SYMBOL_GPL(imx_media_pipeline_video_device);
+/*
+ * Find a fwnode endpoint that maps to the given subdevice's pad.
+ * If there are multiple endpoints that map to the pad, only the
+ * first endpoint encountered is returned.
+ *
+ * On success the refcount of the returned fwnode endpoint is
+ * incremented.
+ */
+struct fwnode_handle *imx_media_get_pad_fwnode(struct media_pad *pad)
+{
+ struct fwnode_handle *endpoint;
+ struct v4l2_subdev *sd;
+
+ if (!is_media_entity_v4l2_subdev(pad->entity))
+ return ERR_PTR(-ENODEV);
+
+ sd = media_entity_to_v4l2_subdev(pad->entity);
+
+ fwnode_graph_for_each_endpoint(dev_fwnode(sd->dev), endpoint) {
+ int pad_idx = media_entity_get_fwnode_pad(&sd->entity,
+ endpoint,
+ pad->flags);
+ if (pad_idx < 0)
+ continue;
+
+ if (pad_idx == pad->index)
+ return endpoint;
+ }
+
+ return ERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL_GPL(imx_media_get_pad_fwnode);
+
/*
* Turn current pipeline streaming on/off starting from entity.
*/
diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h
index 4d124a86b358..d75b3c80101a 100644
--- a/drivers/staging/media/imx/imx-media.h
+++ b/drivers/staging/media/imx/imx-media.h
@@ -195,6 +195,7 @@ imx_media_pipeline_subdev(struct media_entity *start_entity, u32 grp_id,
struct video_device *
imx_media_pipeline_video_device(struct media_entity *start_entity,
enum v4l2_buf_type buftype, bool upstream);
+struct fwnode_handle *imx_media_get_pad_fwnode(struct media_pad *pad);
struct imx_media_dma_buf {
void *virt;
diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
index f71ac485f780..50826e637cb5 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -438,9 +438,8 @@ static int imx7_csi_get_upstream_endpoint(struct imx7_csi *csi,
struct v4l2_fwnode_endpoint *ep,
bool skip_mux)
{
- struct device_node *endpoint, *port;
+ struct fwnode_handle *endpoint;
struct media_entity *src;
- struct v4l2_subdev *sd;
struct media_pad *pad;
if (!csi->src_sd)
@@ -462,29 +461,19 @@ static int imx7_csi_get_upstream_endpoint(struct imx7_csi *csi,
if (!pad)
return -ENODEV;
- sd = media_entity_to_v4l2_subdev(pad->entity);
-
/* To get bus type we may need to skip video mux */
if (skip_mux && src->function == MEDIA_ENT_F_VID_MUX) {
- src = &sd->entity;
+ src = pad->entity;
goto skip_video_mux;
}
- /*
- * NOTE: this assumes an OF-graph port id is the same as a
- * media pad index.
- */
- port = of_graph_get_port_by_id(sd->dev->of_node, pad->index);
- if (!port)
- return -ENODEV;
+ endpoint = imx_media_get_pad_fwnode(pad);
+ if (IS_ERR(endpoint))
+ return PTR_ERR(endpoint);
- endpoint = of_get_next_child(port, NULL);
- of_node_put(port);
- if (!endpoint)
- return -ENODEV;
+ v4l2_fwnode_endpoint_parse(endpoint, ep);
- v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), ep);
- of_node_put(endpoint);
+ fwnode_handle_put(endpoint);
return 0;
}
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 18/22] media: imx: csi: Create media links in bound notifier
From: Steve Longerbeam @ 2019-08-05 23:35 UTC (permalink / raw)
To: linux-media
Cc: open list:STAGING SUBSYSTEM, Fabio Estevam,
Pengutronix Kernel Team, Greg Kroah-Hartman, Sascha Hauer,
open list, NXP Linux Team, Philipp Zabel, Steve Longerbeam,
Mauro Carvalho Chehab, Shawn Guo,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190805233505.21167-1-slongerbeam@gmail.com>
Implement a notifier bound op to register media links from the remote
sub-device's source pad(s) to the CSI sink pad.
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
drivers/staging/media/imx/imx-media-csi.c | 24 +++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index b39d79e63ac2..37b10cbf3c1a 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -120,6 +120,11 @@ static inline struct csi_priv *sd_to_dev(struct v4l2_subdev *sdev)
return container_of(sdev, struct csi_priv, sd);
}
+static inline struct csi_priv *notifier_to_dev(struct v4l2_async_notifier *n)
+{
+ return container_of(n, struct csi_priv, notifier);
+}
+
static inline bool is_parallel_bus(struct v4l2_fwnode_endpoint *ep)
{
return ep->bus_type != V4L2_MBUS_CSI2_DPHY;
@@ -1895,6 +1900,23 @@ static int imx_csi_parse_endpoint(struct device *dev,
return fwnode_device_is_available(asd->match.fwnode) ? 0 : -ENOTCONN;
}
+static int imx_csi_notify_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *sd,
+ struct v4l2_async_subdev *asd)
+{
+ struct csi_priv *priv = notifier_to_dev(notifier);
+ struct media_pad *sink = &priv->sd.entity.pads[CSI_SINK_PAD];
+
+ return media_create_fwnode_pad_links(sink,
+ dev_fwnode(priv->dev->parent),
+ &sd->entity,
+ dev_fwnode(sd->dev), 0);
+}
+
+static const struct v4l2_async_notifier_operations csi_notify_ops = {
+ .bound = imx_csi_notify_bound,
+};
+
static int imx_csi_async_register(struct csi_priv *priv)
{
struct fwnode_handle *fwnode;
@@ -1903,6 +1925,8 @@ static int imx_csi_async_register(struct csi_priv *priv)
v4l2_async_notifier_init(&priv->notifier);
+ priv->notifier.ops = &csi_notify_ops;
+
fwnode = dev_fwnode(priv->dev);
/* get this CSI's port id */
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 17/22] media: imx: csi: Embed notifier in struct csi_priv
From: Steve Longerbeam @ 2019-08-05 23:35 UTC (permalink / raw)
To: linux-media
Cc: open list:STAGING SUBSYSTEM, Fabio Estevam,
Pengutronix Kernel Team, Greg Kroah-Hartman, Sascha Hauer,
open list, NXP Linux Team, Philipp Zabel, Steve Longerbeam,
Mauro Carvalho Chehab, Shawn Guo,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190805233505.21167-1-slongerbeam@gmail.com>
Embed the notifier in 'struct csi_priv', instead of dynamically allocating
it, to make it possible to retrieve csi_priv in a notifier callback op.
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
drivers/staging/media/imx/imx-media-csi.c | 25 +++++++++--------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index e193f66fa230..b39d79e63ac2 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -58,6 +58,8 @@ struct csi_priv {
struct ipu_soc *ipu;
struct v4l2_subdev sd;
struct media_pad pad[CSI_NUM_PADS];
+ struct v4l2_async_notifier notifier;
+
/* the video device at IDMAC output pad */
struct imx_media_video_dev *vdev;
struct imx_media_fim *fim;
@@ -1895,31 +1897,28 @@ static int imx_csi_parse_endpoint(struct device *dev,
static int imx_csi_async_register(struct csi_priv *priv)
{
- struct v4l2_async_notifier *notifier;
struct fwnode_handle *fwnode;
unsigned int port;
int ret;
- notifier = kzalloc(sizeof(*notifier), GFP_KERNEL);
- if (!notifier)
- return -ENOMEM;
-
- v4l2_async_notifier_init(notifier);
+ v4l2_async_notifier_init(&priv->notifier);
fwnode = dev_fwnode(priv->dev);
/* get this CSI's port id */
ret = fwnode_property_read_u32(fwnode, "reg", &port);
if (ret < 0)
- goto out_free;
+ return ret;
ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
- priv->dev->parent, notifier, sizeof(struct v4l2_async_subdev),
+ priv->dev->parent, &priv->notifier,
+ sizeof(struct v4l2_async_subdev),
port, imx_csi_parse_endpoint);
if (ret < 0)
goto out_cleanup;
- ret = v4l2_async_subdev_notifier_register(&priv->sd, notifier);
+ ret = v4l2_async_subdev_notifier_register(&priv->sd,
+ &priv->notifier);
if (ret < 0)
goto out_cleanup;
@@ -1927,16 +1926,12 @@ static int imx_csi_async_register(struct csi_priv *priv)
if (ret < 0)
goto out_unregister;
- priv->sd.subdev_notifier = notifier;
-
return 0;
out_unregister:
- v4l2_async_notifier_unregister(notifier);
+ v4l2_async_notifier_unregister(&priv->notifier);
out_cleanup:
- v4l2_async_notifier_cleanup(notifier);
-out_free:
- kfree(notifier);
+ v4l2_async_notifier_cleanup(&priv->notifier);
return ret;
}
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 16/22] media: imx: csi: Implement get_fwnode_pad
From: Steve Longerbeam @ 2019-08-05 23:34 UTC (permalink / raw)
To: linux-media
Cc: open list:STAGING SUBSYSTEM, Fabio Estevam,
Pengutronix Kernel Team, Greg Kroah-Hartman, Sascha Hauer,
open list, NXP Linux Team, Philipp Zabel, Steve Longerbeam,
Mauro Carvalho Chehab, Shawn Guo,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190805233505.21167-1-slongerbeam@gmail.com>
The CSI does not have a 1:1 relationship between fwnode port numbers and
pad indexes. In fact the CSI fwnode device is itself a port which is the
sink, containing only a single fwnode endpoint. Implement media_entity
operation get_fwnode_pad to first verify the given endpoint is the CSI's
sink endpoint, and if so return the CSI sink pad index.
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
drivers/staging/media/imx/imx-media-csi.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index 367e39f5b382..e193f66fa230 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -1824,9 +1824,32 @@ static void csi_unregistered(struct v4l2_subdev *sd)
ipu_csi_put(priv->csi);
}
+/*
+ * The CSI has only one fwnode endpoint, at the sink pad. Verify the
+ * endpoint belongs to us, and return CSI_SINK_PAD.
+ */
+static int csi_get_fwnode_pad(struct media_entity *entity,
+ struct fwnode_endpoint *endpoint)
+{
+ struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
+ struct csi_priv *priv = v4l2_get_subdevdata(sd);
+ struct fwnode_handle *csi_port = dev_fwnode(priv->dev);
+ struct fwnode_handle *csi_ep;
+ int ret;
+
+ csi_ep = fwnode_get_next_child_node(csi_port, NULL);
+
+ ret = endpoint->local_fwnode == csi_ep ? CSI_SINK_PAD : -ENXIO;
+
+ fwnode_handle_put(csi_ep);
+
+ return ret;
+}
+
static const struct media_entity_operations csi_entity_ops = {
.link_setup = csi_link_setup,
.link_validate = v4l2_subdev_link_validate,
+ .get_fwnode_pad = csi_get_fwnode_pad,
};
static const struct v4l2_subdev_core_ops csi_core_ops = {
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 15/22] media: imx7-media-csi: Create media links in bound notifier
From: Steve Longerbeam @ 2019-08-05 23:34 UTC (permalink / raw)
To: linux-media
Cc: open list:STAGING SUBSYSTEM, Fabio Estevam,
Pengutronix Kernel Team, Greg Kroah-Hartman, Sascha Hauer,
open list, Rui Miguel Silva, NXP Linux Team, Philipp Zabel,
Steve Longerbeam, Mauro Carvalho Chehab, Shawn Guo,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190805233505.21167-1-slongerbeam@gmail.com>
Implement a notifier bound op to register media links from the remote
sub-device's source pad(s) to the CSI sink pad.
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
drivers/staging/media/imx/imx7-media-csi.c | 24 ++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
index a1c96c52a606..f71ac485f780 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -196,6 +196,11 @@ struct imx7_csi {
struct completion last_eof_completion;
};
+static inline struct imx7_csi *notifier_to_dev(struct v4l2_async_notifier *n)
+{
+ return container_of(n, struct imx7_csi, notifier);
+}
+
static u32 imx7_csi_reg_read(struct imx7_csi *csi, unsigned int offset)
{
return readl(csi->regbase + offset);
@@ -1173,6 +1178,23 @@ static int imx7_csi_parse_endpoint(struct device *dev,
return fwnode_device_is_available(asd->match.fwnode) ? 0 : -EINVAL;
}
+static int imx7_csi_notify_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *sd,
+ struct v4l2_async_subdev *asd)
+{
+ struct imx7_csi *csi = notifier_to_dev(notifier);
+ struct media_pad *sink = &csi->sd.entity.pads[IMX7_CSI_PAD_SINK];
+
+ return media_create_fwnode_pad_links(sink,
+ dev_fwnode(csi->sd.dev),
+ &sd->entity,
+ dev_fwnode(sd->dev), 0);
+}
+
+static const struct v4l2_async_notifier_operations imx7_csi_notify_ops = {
+ .bound = imx7_csi_notify_bound,
+};
+
static int imx7_csi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1253,6 +1275,8 @@ static int imx7_csi_probe(struct platform_device *pdev)
v4l2_async_notifier_init(&csi->notifier);
+ csi->notifier.ops = &imx7_csi_notify_ops;
+
ret = v4l2_async_register_fwnode_subdev(&csi->sd, &csi->notifier,
sizeof(struct v4l2_async_subdev),
NULL, 0,
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 14/22] media: imx7-mipi-csis: Create media links in bound notifier
From: Steve Longerbeam @ 2019-08-05 23:34 UTC (permalink / raw)
To: linux-media
Cc: open list:STAGING SUBSYSTEM, Fabio Estevam,
Pengutronix Kernel Team, Greg Kroah-Hartman, Sascha Hauer,
open list, Rui Miguel Silva, NXP Linux Team, Philipp Zabel,
Steve Longerbeam, Mauro Carvalho Chehab, Shawn Guo,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190805233505.21167-1-slongerbeam@gmail.com>
Implement a notifier bound op to register media links from the remote
sub-device's source pad(s) to the mipi csi-2 receiver sink pad.
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
drivers/staging/media/imx/imx7-mipi-csis.c | 25 ++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c
index f71d9183cad2..e03b2317a1ac 100644
--- a/drivers/staging/media/imx/imx7-mipi-csis.c
+++ b/drivers/staging/media/imx/imx7-mipi-csis.c
@@ -259,6 +259,12 @@ struct csi_state {
bool sink_linked;
};
+static inline struct csi_state *
+notifier_to_csis_state(struct v4l2_async_notifier *n)
+{
+ return container_of(n, struct csi_state, notifier);
+}
+
struct csis_pix_format {
unsigned int pix_width_alignment;
u32 code;
@@ -863,6 +869,23 @@ static int mipi_csis_parse_endpoint(struct device *dev,
return 0;
}
+static int mipi_csis_notify_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *sd,
+ struct v4l2_async_subdev *asd)
+{
+ struct csi_state *state = notifier_to_csis_state(notifier);
+ struct media_pad *sink = &state->mipi_sd.entity.pads[CSIS_PAD_SINK];
+
+ return media_create_fwnode_pad_links(sink,
+ dev_fwnode(state->mipi_sd.dev),
+ &sd->entity,
+ dev_fwnode(sd->dev), 0);
+}
+
+static const struct v4l2_async_notifier_operations mipi_csis_notify_ops = {
+ .bound = mipi_csis_notify_bound,
+};
+
static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd,
struct platform_device *pdev,
const struct v4l2_subdev_ops *ops)
@@ -895,6 +918,8 @@ static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd,
v4l2_async_notifier_init(&state->notifier);
+ state->notifier.ops = &mipi_csis_notify_ops;
+
ret = v4l2_async_register_fwnode_subdev(mipi_sd, &state->notifier,
sizeof(struct v4l2_async_subdev),
&sink_port, 1,
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 13/22] media: imx: mipi csi-2: Create media links in bound notifier
From: Steve Longerbeam @ 2019-08-05 23:34 UTC (permalink / raw)
To: linux-media
Cc: open list:STAGING SUBSYSTEM, Fabio Estevam,
Pengutronix Kernel Team, Greg Kroah-Hartman, Sascha Hauer,
open list, NXP Linux Team, Philipp Zabel, Steve Longerbeam,
Mauro Carvalho Chehab, Shawn Guo,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190805233505.21167-1-slongerbeam@gmail.com>
Implement a notifier bound op to register media links from the remote
sub-device's source pad(s) to the mipi csi-2 receiver sink pad.
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
drivers/staging/media/imx/imx6-mipi-csi2.c | 24 ++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 408ee2765e77..5b2258156781 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -91,6 +91,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);
+}
+
/*
* The required sequence of MIPI CSI-2 startup as specified in the i.MX6
* reference manual is as follows:
@@ -573,6 +578,23 @@ static int csi2_parse_endpoint(struct device *dev,
return 0;
}
+static int csi2_notify_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *sd,
+ struct v4l2_async_subdev *asd)
+{
+ struct csi2_dev *csi2 = notifier_to_dev(notifier);
+ struct media_pad *sink = &csi2->sd.entity.pads[CSI2_SINK_PAD];
+
+ return media_create_fwnode_pad_links(sink,
+ dev_fwnode(csi2->dev),
+ &sd->entity,
+ dev_fwnode(sd->dev), 0);
+}
+
+static const struct v4l2_async_notifier_operations csi2_notify_ops = {
+ .bound = csi2_notify_bound,
+};
+
static int csi2_probe(struct platform_device *pdev)
{
unsigned int sink_port = 0;
@@ -646,6 +668,8 @@ static int csi2_probe(struct platform_device *pdev)
v4l2_async_notifier_init(&csi2->notifier);
+ csi2->notifier.ops = &csi2_notify_ops;
+
ret = v4l2_async_register_fwnode_subdev(
&csi2->sd, &csi2->notifier, sizeof(struct v4l2_async_subdev),
&sink_port, 1, csi2_parse_endpoint);
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 11/22] media: v4l2-fwnode: Pass notifier to v4l2_async_register_fwnode_subdev()
From: Steve Longerbeam @ 2019-08-05 23:34 UTC (permalink / raw)
To: linux-media
Cc: open list:STAGING SUBSYSTEM, Fabio Estevam,
Pengutronix Kernel Team, Greg Kroah-Hartman, Sascha Hauer,
open list, Sakari Ailus, Rui Miguel Silva, Jacopo Mondi,
NXP Linux Team, Philipp Zabel, Steve Longerbeam, Hans Verkuil,
Mauro Carvalho Chehab, Shawn Guo,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190805233505.21167-1-slongerbeam@gmail.com>
Instead of allocating a notifier in v4l2_async_register_fwnode_subdev(),
have the caller provide one. This allows the caller to implement
notifier ops (bind, unbind).
The caller is now responsible for first initializing its notifier with a
call to v4l2_async_notifier_init().
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
drivers/media/platform/video-mux.c | 6 +++++-
drivers/media/v4l2-core/v4l2-fwnode.c | 11 +----------
drivers/staging/media/imx/imx6-mipi-csi2.c | 5 ++++-
drivers/staging/media/imx/imx7-media-csi.c | 5 ++++-
drivers/staging/media/imx/imx7-mipi-csis.c | 5 ++++-
include/media/v4l2-fwnode.h | 12 ++++++++----
6 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c
index ddd0e338f9e4..ca1cef783646 100644
--- a/drivers/media/platform/video-mux.c
+++ b/drivers/media/platform/video-mux.c
@@ -21,6 +21,7 @@
struct video_mux {
struct v4l2_subdev subdev;
+ struct v4l2_async_notifier notifier;
struct media_pad *pads;
struct v4l2_mbus_framefmt *format_mbus;
struct mux_control *mux;
@@ -354,8 +355,11 @@ static int video_mux_async_register(struct video_mux *vmux,
for (i = 0; i < num_input_pads; i++)
ports[i] = i;
+ v4l2_async_notifier_init(&vmux->notifier);
+
ret = v4l2_async_register_fwnode_subdev(
- &vmux->subdev, sizeof(struct v4l2_async_subdev),
+ &vmux->subdev, &vmux->notifier,
+ sizeof(struct v4l2_async_subdev),
ports, num_input_pads, video_mux_parse_endpoint);
kfree(ports);
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
index 5d4ce4aa3fdc..8f5b3fdea061 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -1124,12 +1124,12 @@ int v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd)
EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor_common);
int v4l2_async_register_fwnode_subdev(struct v4l2_subdev *sd,
+ struct v4l2_async_notifier *notifier,
size_t asd_struct_size,
unsigned int *ports,
unsigned int num_ports,
parse_endpoint_func parse_endpoint)
{
- struct v4l2_async_notifier *notifier;
struct device *dev = sd->dev;
struct fwnode_handle *fwnode;
int ret;
@@ -1141,12 +1141,6 @@ int v4l2_async_register_fwnode_subdev(struct v4l2_subdev *sd,
if (!fwnode_device_is_available(fwnode))
return -ENODEV;
- notifier = kzalloc(sizeof(*notifier), GFP_KERNEL);
- if (!notifier)
- return -ENOMEM;
-
- v4l2_async_notifier_init(notifier);
-
if (!ports) {
ret = v4l2_async_notifier_parse_fwnode_endpoints(dev, notifier,
asd_struct_size,
@@ -1171,15 +1165,12 @@ int v4l2_async_register_fwnode_subdev(struct v4l2_subdev *sd,
if (ret < 0)
goto out_unregister;
- sd->subdev_notifier = notifier;
-
return 0;
out_unregister:
v4l2_async_notifier_unregister(notifier);
out_cleanup:
v4l2_async_notifier_cleanup(notifier);
- kfree(notifier);
return ret;
}
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index f29e28df36ed..408ee2765e77 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -35,6 +35,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;
@@ -643,8 +644,10 @@ static int csi2_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, &csi2->sd);
+ v4l2_async_notifier_init(&csi2->notifier);
+
ret = v4l2_async_register_fwnode_subdev(
- &csi2->sd, sizeof(struct v4l2_async_subdev),
+ &csi2->sd, &csi2->notifier, sizeof(struct v4l2_async_subdev),
&sink_port, 1, csi2_parse_endpoint);
if (ret)
goto dphy_off;
diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
index 500b4c08d967..a1c96c52a606 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -155,6 +155,7 @@
struct imx7_csi {
struct device *dev;
struct v4l2_subdev sd;
+ struct v4l2_async_notifier notifier;
struct imx_media_video_dev *vdev;
struct imx_media_dev *imxmd;
struct media_pad pad[IMX7_CSI_PADS_NUM];
@@ -1250,7 +1251,9 @@ static int imx7_csi_probe(struct platform_device *pdev)
v4l2_ctrl_handler_init(&csi->ctrl_hdlr, 0);
csi->sd.ctrl_handler = &csi->ctrl_hdlr;
- ret = v4l2_async_register_fwnode_subdev(&csi->sd,
+ v4l2_async_notifier_init(&csi->notifier);
+
+ ret = v4l2_async_register_fwnode_subdev(&csi->sd, &csi->notifier,
sizeof(struct v4l2_async_subdev),
NULL, 0,
imx7_csi_parse_endpoint);
diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c
index d1cdf011c8f1..f71d9183cad2 100644
--- a/drivers/staging/media/imx/imx7-mipi-csis.c
+++ b/drivers/staging/media/imx/imx7-mipi-csis.c
@@ -223,6 +223,7 @@ struct csi_state {
struct device *dev;
struct media_pad pads[CSIS_PADS_NUM];
struct v4l2_subdev mipi_sd;
+ struct v4l2_async_notifier notifier;
struct v4l2_subdev *src_sd;
u8 index;
@@ -892,7 +893,9 @@ static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd,
v4l2_set_subdevdata(mipi_sd, &pdev->dev);
- ret = v4l2_async_register_fwnode_subdev(mipi_sd,
+ v4l2_async_notifier_init(&state->notifier);
+
+ ret = v4l2_async_register_fwnode_subdev(mipi_sd, &state->notifier,
sizeof(struct v4l2_async_subdev),
&sink_port, 1,
mipi_csis_parse_endpoint);
diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
index f81f8bf34526..27a7b78149c2 100644
--- a/include/media/v4l2-fwnode.h
+++ b/include/media/v4l2-fwnode.h
@@ -331,6 +331,7 @@ int v4l2_async_notifier_parse_fwnode_sensor_common(struct device *dev,
* and parses fwnode endpoints
*
* @sd: pointer to struct &v4l2_subdev
+ * @notifier: the sub-device's notifier.
* @asd_struct_size: size of the driver's async sub-device struct, including
* sizeof(struct v4l2_async_subdev). The &struct
* v4l2_async_subdev shall be the first member of
@@ -343,13 +344,15 @@ int v4l2_async_notifier_parse_fwnode_sensor_common(struct device *dev,
* endpoint. Optional.
*
* This function is just like v4l2_async_register_subdev() with the
- * exception that calling it will also allocate a notifier for the
- * sub-device, parse the sub-device's firmware node endpoints using
- * v4l2_async_notifier_parse_fwnode_endpoints() or
+ * exception that calling it will also parse the sub-device's firmware
+ * node endpoints using v4l2_async_notifier_parse_fwnode_endpoints() or
* v4l2_async_notifier_parse_fwnode_endpoints_by_port(), and
- * registers the sub-device notifier. The sub-device is similarly
+ * registers the sub-device's notifier. The sub-device is similarly
* unregistered by calling v4l2_async_unregister_subdev().
*
+ * The caller must first initialize the notifier with a call to
+ * v4l2_async_notifier_init().
+ *
* While registered, the subdev module is marked as in-use.
*
* An error is returned if the module is no longer loaded on any attempts
@@ -357,6 +360,7 @@ int v4l2_async_notifier_parse_fwnode_sensor_common(struct device *dev,
*/
int
v4l2_async_register_fwnode_subdev(struct v4l2_subdev *sd,
+ struct v4l2_async_notifier *notifier,
size_t asd_struct_size,
unsigned int *ports,
unsigned int num_ports,
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 09/22] media: sun6i: Fix fwnode media link creation
From: Steve Longerbeam @ 2019-08-05 23:34 UTC (permalink / raw)
To: linux-media
Cc: Maxime Ripard, open list, Chen-Yu Tsai, Yong Deng,
Steve Longerbeam, Mauro Carvalho Chehab,
moderated list:ARM/Allwinner sunXi SoC support
In-Reply-To: <20190805233505.21167-1-slongerbeam@gmail.com>
sun6i_csi_link_entity() passes the bound subdev's sd->fwnode to
media_entity_get_fwnode_pad(). This is likely not an endpoint
fwnode as required by media_entity_get_fwnode_pad(), for most
subdevices it is the port parent of endpoint fwnode(s). This has only
worked before because no entities have implemented the .get_fwnode_pad()
op yet, and the default behavior of media_entity_get_fwnode_pad()
was to ignore the passed fwnode and return the first pad that matches
the given direction flags.
Fix this by replacing the calls to media_entity_get_fwnode_pad() and
media_create_pad_link() with a call to media_create_fwnode_pad_links().
Fixes: 5cc7522d89655 ("media: sun6i: Add support for Allwinner CSI V3s")
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
.../platform/sunxi/sun6i-csi/sun6i_csi.c | 36 +++----------------
1 file changed, 5 insertions(+), 31 deletions(-)
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
index 6e0e894154f4..9cf726b5c25a 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
@@ -630,37 +630,11 @@ static int sun6i_csi_link_entity(struct sun6i_csi *csi,
struct media_entity *entity,
struct fwnode_handle *fwnode)
{
- struct media_entity *sink;
- struct media_pad *sink_pad;
- int src_pad_index;
- int ret;
-
- ret = media_entity_get_fwnode_pad(entity, fwnode, MEDIA_PAD_FL_SOURCE);
- if (ret < 0) {
- dev_err(csi->dev, "%s: no source pad in external entity %s\n",
- __func__, entity->name);
- return -EINVAL;
- }
-
- src_pad_index = ret;
-
- sink = &csi->video.vdev.entity;
- sink_pad = &csi->video.pad;
-
- dev_dbg(csi->dev, "creating %s:%u -> %s:%u link\n",
- entity->name, src_pad_index, sink->name, sink_pad->index);
- ret = media_create_pad_link(entity, src_pad_index, sink,
- sink_pad->index,
- MEDIA_LNK_FL_ENABLED |
- MEDIA_LNK_FL_IMMUTABLE);
- if (ret < 0) {
- dev_err(csi->dev, "failed to create %s:%u -> %s:%u link\n",
- entity->name, src_pad_index,
- sink->name, sink_pad->index);
- return ret;
- }
-
- return 0;
+ return media_create_fwnode_pad_links(&csi->video.pad,
+ dev_fwnode(csi->dev),
+ entity, fwnode,
+ MEDIA_LNK_FL_ENABLED |
+ MEDIA_LNK_FL_IMMUTABLE);
}
static int sun6i_subdev_notify_complete(struct v4l2_async_notifier *notifier)
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 04/22] media: Move v4l2_fwnode_parse_link from v4l2 to driver base
From: Steve Longerbeam @ 2019-08-05 23:34 UTC (permalink / raw)
To: linux-media
Cc: Heikki Krogerus, Rafael J. Wysocki, Laurent Pinchart, Shawn Guo,
Fabio Estevam, open list:STAGING SUBSYSTEM, Mauro Carvalho Chehab,
Michal Simek, open list:ACPI, NXP Linux Team, Steve Longerbeam,
Philipp Zabel, Len Brown, Sakari Ailus, Sascha Hauer,
Thomas Gleixner, Andy Shevchenko,
moderated list:ARM/ZYNQ ARCHITECTURE, Hyun Kwon,
Greg Kroah-Hartman, open list, Jacopo Mondi,
Pengutronix Kernel Team, Hans Verkuil, Enrico Weigelt
In-Reply-To: <20190805233505.21167-1-slongerbeam@gmail.com>
There is nothing v4l2-specific about v4l2_fwnode_{parse|put}_link().
Make these functions more generally available by moving them to driver
base, with the appropriate name changes to the functions and struct.
In the process embed a 'struct fwnode_endpoint' in 'struct fwnode_link'
for both sides of the link, and make use of fwnode_graph_parse_endpoint()
to fully parse both endpoints. Rename members local_node and
remote_node to more descriptive local_port_parent and
remote_port_parent.
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
drivers/base/property.c | 63 +++++++++++++++++++
drivers/media/platform/xilinx/xilinx-vipp.c | 69 +++++++++++----------
drivers/media/v4l2-core/v4l2-fwnode.c | 39 ------------
drivers/staging/media/imx/imx-media-of.c | 49 +++++++--------
include/linux/fwnode.h | 14 +++++
include/linux/property.h | 5 ++
include/media/v4l2-fwnode.h | 44 -------------
7 files changed, 141 insertions(+), 142 deletions(-)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 81bd01ed4042..dd82cd150d84 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -1100,6 +1100,69 @@ int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
}
EXPORT_SYMBOL(fwnode_graph_parse_endpoint);
+/**
+ * fwnode_graph_parse_link() - parse a link between two endpoints
+ * @local_endpoint: the endpoint's fwnode at the local end of the link
+ * @link: pointer to the fwnode link data structure
+ *
+ * Fill the link structure with the parsed local and remote endpoint info
+ * and the local and remote port parent nodes.
+ *
+ * A reference is taken to both the local and remote port parent nodes,
+ * the caller must use fwnode_graph_put_link() to drop the references
+ * when done with the link.
+ *
+ * Return: 0 on success, or -ENOLINK if the remote endpoint fwnode
+ * can't be found.
+ */
+int fwnode_graph_parse_link(struct fwnode_handle *local_endpoint,
+ struct fwnode_link *link)
+{
+ struct fwnode_handle *remote_endpoint;
+ int ret;
+
+ memset(link, 0, sizeof(*link));
+
+ ret = fwnode_graph_parse_endpoint(local_endpoint, &link->local);
+ if (ret < 0)
+ return ret;
+
+ remote_endpoint = fwnode_graph_get_remote_endpoint(local_endpoint);
+ if (!remote_endpoint)
+ return -ENOLINK;
+
+ ret = fwnode_graph_parse_endpoint(remote_endpoint, &link->remote);
+ if (ret < 0) {
+ fwnode_handle_put(remote_endpoint);
+ return ret;
+ }
+
+ link->local_port_parent =
+ fwnode_graph_get_port_parent(local_endpoint);
+ link->remote_port_parent =
+ fwnode_graph_get_port_parent(remote_endpoint);
+
+ fwnode_handle_put(remote_endpoint);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fwnode_graph_parse_link);
+
+/**
+ * fwnode_graph_put_link() - drop references to port parent nodes in a link
+ * @link: pointer to the fwnode link data structure
+ *
+ * Drop references to the local and remote port parent nodes in the link.
+ * This function must be called on every link parsed with
+ * fwnode_graph_parse_link().
+ */
+void fwnode_graph_put_link(struct fwnode_link *link)
+{
+ fwnode_handle_put(link->local_port_parent);
+ fwnode_handle_put(link->remote_port_parent);
+}
+EXPORT_SYMBOL_GPL(fwnode_graph_put_link);
+
const void *device_get_match_data(struct device *dev)
{
return fwnode_call_ptr_op(dev_fwnode(dev), device_get_match_data, dev);
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index cc2856efea59..9c0dfc694478 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -74,7 +74,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
struct media_pad *local_pad;
struct media_pad *remote_pad;
struct xvip_graph_entity *ent;
- struct v4l2_fwnode_link link;
+ struct fwnode_link link;
struct fwnode_handle *ep = NULL;
int ret = 0;
@@ -89,7 +89,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
dev_dbg(xdev->dev, "processing endpoint %p\n", ep);
- ret = v4l2_fwnode_parse_link(ep, &link);
+ ret = fwnode_graph_parse_link(ep, &link);
if (ret < 0) {
dev_err(xdev->dev, "failed to parse link for %p\n",
ep);
@@ -99,54 +99,55 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
/* Skip sink ports, they will be processed from the other end of
* the link.
*/
- if (link.local_port >= local->num_pads) {
+ if (link.local.port >= local->num_pads) {
dev_err(xdev->dev, "invalid port number %u for %p\n",
- link.local_port, link.local_node);
- v4l2_fwnode_put_link(&link);
+ link.local.port, link.local_port_parent);
+ fwnode_graph_put_link(&link);
ret = -EINVAL;
break;
}
- local_pad = &local->pads[link.local_port];
+ local_pad = &local->pads[link.local.port];
if (local_pad->flags & MEDIA_PAD_FL_SINK) {
dev_dbg(xdev->dev, "skipping sink port %p:%u\n",
- link.local_node, link.local_port);
- v4l2_fwnode_put_link(&link);
+ link.local_port_parent, link.local.port);
+ fwnode_graph_put_link(&link);
continue;
}
/* Skip DMA engines, they will be processed separately. */
- if (link.remote_node == of_fwnode_handle(xdev->dev->of_node)) {
+ if (link.remote_port_parent ==
+ of_fwnode_handle(xdev->dev->of_node)) {
dev_dbg(xdev->dev, "skipping DMA port %p:%u\n",
- link.local_node, link.local_port);
- v4l2_fwnode_put_link(&link);
+ link.local_port_parent, link.local.port);
+ fwnode_graph_put_link(&link);
continue;
}
/* Find the remote entity. */
- ent = xvip_graph_find_entity(xdev, link.remote_node);
+ ent = xvip_graph_find_entity(xdev, link.remote_port_parent);
if (ent == NULL) {
dev_err(xdev->dev, "no entity found for %p\n",
- link.remote_node);
- v4l2_fwnode_put_link(&link);
+ link.remote_port_parent);
+ fwnode_graph_put_link(&link);
ret = -ENODEV;
break;
}
remote = ent->entity;
- if (link.remote_port >= remote->num_pads) {
+ if (link.remote.port >= remote->num_pads) {
dev_err(xdev->dev, "invalid port number %u on %p\n",
- link.remote_port, link.remote_node);
- v4l2_fwnode_put_link(&link);
+ link.remote.port, link.remote_port_parent);
+ fwnode_graph_put_link(&link);
ret = -EINVAL;
break;
}
- remote_pad = &remote->pads[link.remote_port];
+ remote_pad = &remote->pads[link.remote.port];
- v4l2_fwnode_put_link(&link);
+ fwnode_graph_put_link(&link);
/* Create the media link. */
dev_dbg(xdev->dev, "creating %s:%u -> %s:%u link\n",
@@ -191,7 +192,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
struct media_pad *source_pad;
struct media_pad *sink_pad;
struct xvip_graph_entity *ent;
- struct v4l2_fwnode_link link;
+ struct fwnode_link link;
struct device_node *ep = NULL;
struct xvip_dma *dma;
int ret = 0;
@@ -206,7 +207,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
dev_dbg(xdev->dev, "processing endpoint %pOF\n", ep);
- ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link);
+ ret = fwnode_graph_parse_link(of_fwnode_handle(ep), &link);
if (ret < 0) {
dev_err(xdev->dev, "failed to parse link for %pOF\n",
ep);
@@ -214,11 +215,11 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
}
/* Find the DMA engine. */
- dma = xvip_graph_find_dma(xdev, link.local_port);
+ dma = xvip_graph_find_dma(xdev, link.local.port);
if (dma == NULL) {
dev_err(xdev->dev, "no DMA engine found for port %u\n",
- link.local_port);
- v4l2_fwnode_put_link(&link);
+ link.local.port);
+ fwnode_graph_put_link(&link);
ret = -EINVAL;
break;
}
@@ -227,20 +228,20 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
dma->video.name);
/* Find the remote entity. */
- ent = xvip_graph_find_entity(xdev, link.remote_node);
+ ent = xvip_graph_find_entity(xdev, link.remote_port_parent);
if (ent == NULL) {
dev_err(xdev->dev, "no entity found for %pOF\n",
- to_of_node(link.remote_node));
- v4l2_fwnode_put_link(&link);
+ to_of_node(link.remote_port_parent));
+ fwnode_graph_put_link(&link);
ret = -ENODEV;
break;
}
- if (link.remote_port >= ent->entity->num_pads) {
+ if (link.remote.port >= ent->entity->num_pads) {
dev_err(xdev->dev, "invalid port number %u on %pOF\n",
- link.remote_port,
- to_of_node(link.remote_node));
- v4l2_fwnode_put_link(&link);
+ link.remote.port,
+ to_of_node(link.remote_port_parent));
+ fwnode_graph_put_link(&link);
ret = -EINVAL;
break;
}
@@ -249,15 +250,15 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
source = &dma->video.entity;
source_pad = &dma->pad;
sink = ent->entity;
- sink_pad = &sink->pads[link.remote_port];
+ sink_pad = &sink->pads[link.remote.port];
} else {
source = ent->entity;
- source_pad = &source->pads[link.remote_port];
+ source_pad = &source->pads[link.remote.port];
sink = &dma->video.entity;
sink_pad = &dma->pad;
}
- v4l2_fwnode_put_link(&link);
+ fwnode_graph_put_link(&link);
/* Create the media link. */
dev_dbg(xdev->dev, "creating %s:%u -> %s:%u link\n",
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
index 3bd1888787eb..5d4ce4aa3fdc 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -556,45 +556,6 @@ int v4l2_fwnode_endpoint_alloc_parse(struct fwnode_handle *fwnode,
}
EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_alloc_parse);
-int v4l2_fwnode_parse_link(struct fwnode_handle *__fwnode,
- struct v4l2_fwnode_link *link)
-{
- const char *port_prop = is_of_node(__fwnode) ? "reg" : "port";
- struct fwnode_handle *fwnode;
-
- memset(link, 0, sizeof(*link));
-
- fwnode = fwnode_get_parent(__fwnode);
- fwnode_property_read_u32(fwnode, port_prop, &link->local_port);
- fwnode = fwnode_get_next_parent(fwnode);
- if (is_of_node(fwnode) && of_node_name_eq(to_of_node(fwnode), "ports"))
- fwnode = fwnode_get_next_parent(fwnode);
- link->local_node = fwnode;
-
- fwnode = fwnode_graph_get_remote_endpoint(__fwnode);
- if (!fwnode) {
- fwnode_handle_put(fwnode);
- return -ENOLINK;
- }
-
- fwnode = fwnode_get_parent(fwnode);
- fwnode_property_read_u32(fwnode, port_prop, &link->remote_port);
- fwnode = fwnode_get_next_parent(fwnode);
- if (is_of_node(fwnode) && of_node_name_eq(to_of_node(fwnode), "ports"))
- fwnode = fwnode_get_next_parent(fwnode);
- link->remote_node = fwnode;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(v4l2_fwnode_parse_link);
-
-void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link)
-{
- fwnode_handle_put(link->local_node);
- fwnode_handle_put(link->remote_node);
-}
-EXPORT_SYMBOL_GPL(v4l2_fwnode_put_link);
-
static int
v4l2_async_notifier_fwnode_parse_endpoint(struct device *dev,
struct v4l2_async_notifier *notifier,
diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c
index 2d3efd2a6dde..736c954a8ff5 100644
--- a/drivers/staging/media/imx/imx-media-of.c
+++ b/drivers/staging/media/imx/imx-media-of.c
@@ -84,28 +84,29 @@ EXPORT_SYMBOL_GPL(imx_media_add_of_subdevs);
*/
static int create_of_link(struct imx_media_dev *imxmd,
struct v4l2_subdev *sd,
- struct v4l2_fwnode_link *link)
+ struct fwnode_link *link)
{
struct v4l2_subdev *remote, *src, *sink;
int src_pad, sink_pad;
- if (link->local_port >= sd->entity.num_pads)
+ if (link->local.port >= sd->entity.num_pads)
return -EINVAL;
- remote = imx_media_find_subdev_by_fwnode(imxmd, link->remote_node);
+ remote = imx_media_find_subdev_by_fwnode(imxmd,
+ link->remote_port_parent);
if (!remote)
return 0;
- if (sd->entity.pads[link->local_port].flags & MEDIA_PAD_FL_SINK) {
+ if (sd->entity.pads[link->local.port].flags & MEDIA_PAD_FL_SINK) {
src = remote;
- src_pad = link->remote_port;
+ src_pad = link->remote.port;
sink = sd;
- sink_pad = link->local_port;
+ sink_pad = link->local.port;
} else {
src = sd;
- src_pad = link->local_port;
+ src_pad = link->local.port;
sink = remote;
- sink_pad = link->remote_port;
+ sink_pad = link->remote.port;
}
/* make sure link doesn't already exist before creating */
@@ -126,17 +127,17 @@ static int create_of_link(struct imx_media_dev *imxmd,
int imx_media_create_of_links(struct imx_media_dev *imxmd,
struct v4l2_subdev *sd)
{
- struct v4l2_fwnode_link link;
- struct device_node *ep;
+ struct fwnode_handle *endpoint;
+ struct fwnode_link link;
int ret;
- for_each_endpoint_of_node(sd->dev->of_node, ep) {
- ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link);
+ fwnode_graph_for_each_endpoint(dev_fwnode(sd->dev), endpoint) {
+ ret = fwnode_graph_parse_link(endpoint, &link);
if (ret)
continue;
ret = create_of_link(imxmd, sd, &link);
- v4l2_fwnode_put_link(&link);
+ fwnode_graph_put_link(&link);
if (ret)
return ret;
}
@@ -152,35 +153,33 @@ EXPORT_SYMBOL_GPL(imx_media_create_of_links);
int imx_media_create_csi_of_links(struct imx_media_dev *imxmd,
struct v4l2_subdev *csi)
{
- struct device_node *csi_np = csi->dev->of_node;
- struct device_node *ep;
+ struct fwnode_handle *csi_np = dev_fwnode(csi->dev);
+ struct fwnode_handle *csi_ep;
- for_each_child_of_node(csi_np, ep) {
- struct fwnode_handle *fwnode, *csi_ep;
- struct v4l2_fwnode_link link;
+ fwnode_for_each_child_node(csi_np, csi_ep) {
+ struct fwnode_handle *fwnode;
+ struct fwnode_link link;
int ret;
memset(&link, 0, sizeof(link));
- link.local_node = of_fwnode_handle(csi_np);
- link.local_port = CSI_SINK_PAD;
-
- csi_ep = of_fwnode_handle(ep);
+ link.local_port_parent = csi_np;
+ link.local.port = CSI_SINK_PAD;
fwnode = fwnode_graph_get_remote_endpoint(csi_ep);
if (!fwnode)
continue;
fwnode = fwnode_get_parent(fwnode);
- fwnode_property_read_u32(fwnode, "reg", &link.remote_port);
+ fwnode_property_read_u32(fwnode, "reg", &link.remote.port);
fwnode = fwnode_get_next_parent(fwnode);
if (is_of_node(fwnode) &&
of_node_name_eq(to_of_node(fwnode), "ports"))
fwnode = fwnode_get_next_parent(fwnode);
- link.remote_node = fwnode;
+ link.remote_port_parent = fwnode;
ret = create_of_link(imxmd, csi, &link);
- fwnode_handle_put(link.remote_node);
+ fwnode_handle_put(link.remote_port_parent);
if (ret)
return ret;
}
diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
index a11c8c56c78b..c2063ae2affe 100644
--- a/include/linux/fwnode.h
+++ b/include/linux/fwnode.h
@@ -31,6 +31,20 @@ struct fwnode_endpoint {
const struct fwnode_handle *local_fwnode;
};
+/**
+ * struct fwnode_link - a link between two fwnode graph endpoints
+ * @local: parsed local endpoint of the link
+ * @local_port_parent: port parent fwnode of local endpoint
+ * @remote: parsed remote endpoint of the link
+ * @remote_port_parent: port parent fwnode of the remote endpoint
+ */
+struct fwnode_link {
+ struct fwnode_endpoint local;
+ struct fwnode_handle *local_port_parent;
+ struct fwnode_endpoint remote;
+ struct fwnode_handle *remote_port_parent;
+};
+
#define NR_FWNODE_REFERENCE_ARGS 8
/**
diff --git a/include/linux/property.h b/include/linux/property.h
index 5a910ad79591..3923906fc314 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -374,6 +374,11 @@ fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode,
int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
struct fwnode_endpoint *endpoint);
+int fwnode_graph_parse_link(struct fwnode_handle *fwnode,
+ struct fwnode_link *link);
+
+void fwnode_graph_put_link(struct fwnode_link *link);
+
/* -------------------------------------------------------------------------- */
/* Software fwnode support - when HW description is incomplete or missing */
diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
index f6a7bcd13197..f81f8bf34526 100644
--- a/include/media/v4l2-fwnode.h
+++ b/include/media/v4l2-fwnode.h
@@ -109,20 +109,6 @@ struct v4l2_fwnode_endpoint {
unsigned int nr_of_link_frequencies;
};
-/**
- * struct v4l2_fwnode_link - a link between two endpoints
- * @local_node: pointer to device_node of this endpoint
- * @local_port: identifier of the port this endpoint belongs to
- * @remote_node: pointer to device_node of the remote endpoint
- * @remote_port: identifier of the port the remote endpoint belongs to
- */
-struct v4l2_fwnode_link {
- struct fwnode_handle *local_node;
- unsigned int local_port;
- struct fwnode_handle *remote_node;
- unsigned int remote_port;
-};
-
/**
* v4l2_fwnode_endpoint_parse() - parse all fwnode node properties
* @fwnode: pointer to the endpoint's fwnode handle
@@ -203,36 +189,6 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep);
int v4l2_fwnode_endpoint_alloc_parse(struct fwnode_handle *fwnode,
struct v4l2_fwnode_endpoint *vep);
-/**
- * v4l2_fwnode_parse_link() - parse a link between two endpoints
- * @fwnode: pointer to the endpoint's fwnode at the local end of the link
- * @link: pointer to the V4L2 fwnode link data structure
- *
- * Fill the link structure with the local and remote nodes and port numbers.
- * The local_node and remote_node fields are set to point to the local and
- * remote port's parent nodes respectively (the port parent node being the
- * parent node of the port node if that node isn't a 'ports' node, or the
- * grand-parent node of the port node otherwise).
- *
- * A reference is taken to both the local and remote nodes, the caller must use
- * v4l2_fwnode_put_link() to drop the references when done with the
- * link.
- *
- * Return: 0 on success, or -ENOLINK if the remote endpoint fwnode can't be
- * found.
- */
-int v4l2_fwnode_parse_link(struct fwnode_handle *fwnode,
- struct v4l2_fwnode_link *link);
-
-/**
- * v4l2_fwnode_put_link() - drop references to nodes in a link
- * @link: pointer to the V4L2 fwnode link data structure
- *
- * Drop references to the local and remote nodes in the link. This function
- * must be called on every link parsed with v4l2_fwnode_parse_link().
- */
-void v4l2_fwnode_put_link(struct v4l2_fwnode_link *link);
-
/**
* typedef parse_endpoint_func - Driver's callback function to be called on
* each V4L2 fwnode endpoint.
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH 2/6] dt-bindings: arm: amlogic: add bindings for G12B based S922X SoC
From: Rob Herring @ 2019-08-05 22:26 UTC (permalink / raw)
To: Kevin Hilman
Cc: devicetree, Neil Armstrong, Christian Hewitt,
linux-kernel@vger.kernel.org, linux-amlogic,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <CAL_JsqL_L2qHe334sB57hR_coRhawKiqXYjKAQDJt_DHfBamBQ@mail.gmail.com>
On Mon, Aug 5, 2019 at 4:21 PM Rob Herring <robh@kernel.org> wrote:
>
> On Mon, Aug 5, 2019 at 3:46 PM Kevin Hilman <khilman@baylibre.com> wrote:
> >
> > Neil Armstrong <narmstrong@baylibre.com> writes:
> >
> > > Add a specific compatible for the Amlogic G12B family based S922X SoC
> > > to differentiate with the A311D SoC from the same family.
> > >
> > > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> > > ---
> > > Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
> > > 1 file changed, 1 insertion(+)
> > >
> > > diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
> > > index 325c6fd3566d..3c3bc806cd23 100644
> > > --- a/Documentation/devicetree/bindings/arm/amlogic.yaml
> > > +++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
> > > @@ -139,6 +139,7 @@ properties:
> > > items:
> > > - enum:
> > > - hardkernel,odroid-n2
> > > + - const: amlogic,s922x
> > > - const: amlogic,g12b
> >
> > nit: in previous binding docs, we were trying to keep these sorted
> > alphabetically. I'll reorder the new "s922x" after "g12b" when
> > applying.
>
> No, this is not documentation ordering. It's the order compatible
> strings must be in.
BTW, you probably should run:
make DT_SCHEMA_FILES=Documentation/devicetree/bindings/arm/amlogic.yaml
dtbs_check
on your tree regularly. This will catch any errors like this and
undocumented boards (but not undocumented SoCs, still too many for me
to get that in place).
Rob
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/6] dt-bindings: arm: amlogic: add bindings for G12B based S922X SoC
From: Rob Herring @ 2019-08-05 22:21 UTC (permalink / raw)
To: Kevin Hilman
Cc: devicetree, Neil Armstrong, Christian Hewitt,
linux-kernel@vger.kernel.org, linux-amlogic,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <7hblx3gua3.fsf@baylibre.com>
On Mon, Aug 5, 2019 at 3:46 PM Kevin Hilman <khilman@baylibre.com> wrote:
>
> Neil Armstrong <narmstrong@baylibre.com> writes:
>
> > Add a specific compatible for the Amlogic G12B family based S922X SoC
> > to differentiate with the A311D SoC from the same family.
> >
> > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> > ---
> > Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
> > index 325c6fd3566d..3c3bc806cd23 100644
> > --- a/Documentation/devicetree/bindings/arm/amlogic.yaml
> > +++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
> > @@ -139,6 +139,7 @@ properties:
> > items:
> > - enum:
> > - hardkernel,odroid-n2
> > + - const: amlogic,s922x
> > - const: amlogic,g12b
>
> nit: in previous binding docs, we were trying to keep these sorted
> alphabetically. I'll reorder the new "s922x" after "g12b" when
> applying.
No, this is not documentation ordering. It's the order compatible
strings must be in.
Rob
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] dt-bindings: net: meson-dwmac: convert to yaml
From: Rob Herring @ 2019-08-05 22:09 UTC (permalink / raw)
To: Neil Armstrong
Cc: devicetree, Martin Blumenstingl, netdev,
linux-kernel@vger.kernel.org, linux-amlogic,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190805122558.5130-1-narmstrong@baylibre.com>
On Mon, Aug 5, 2019 at 6:26 AM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> Now that we have the DT validation in place, let's convert the device tree
> bindings for the Synopsys DWMAC Glue for Amlogic SoCs over to a YAML schemas.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
> Rob,
>
> I keep getting :
> .../devicetree/bindings/net/amlogic,meson-dwmac.example.dt.yaml: ethernet@c9410000: reg: [[3376480256, 65536], [3364046144, 8]] is too long
Because snps,dwmac.yaml has:
reg:
maxItems: 1
The schemas are applied separately and all have to be valid. You'll
need to change snps,dwmac.yaml to:
reg:
minItems: 1
maxItems: 2
The schema error messages leave something to be desired. I wish the
error messages said which schema is throwing the error.
> for the example DT
>
> and for the board DT :
> ../amlogic/meson-gxl-s905x-libretech-cc.dt.yaml: ethernet@c9410000: reg: [[0, 3376480256, 0, 65536, 0, 3364046144, 0, 4]] is too short
> ../amlogic/meson-gxl-s905x-nexbox-a95x.dt.yaml: soc: ethernet@c9410000:reg:0: [0, 3376480256, 0, 65536, 0, 3364046144, 0, 4] is too long
>
> and I don't know how to get rid of it.
The first issue is the same as the above. The 2nd issue is the use of
<> in dts files becomes stricter with the schema. Each entry in an
array needs to be bracketed:
reg = <0x0 0xc9410000 0x0 0x10000>,
<0x0 0xc8834540 0x0 0x4>;
Rob
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFCv2 0/9] dt-bindings: first tentative of conversion to yaml format
From: Rob Herring @ 2019-08-05 21:51 UTC (permalink / raw)
To: Neil Armstrong
Cc: Philipp Zabel, devicetree, LINUX-WATCHDOG, Jassi Brar, linux-spi,
open list:HARDWARE RANDOM NUMBER GENERATOR CORE,
open list:SERIAL DRIVERS, linux-amlogic, Kishon Vijay Abraham I,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190805120320.32282-1-narmstrong@baylibre.com>
On Mon, Aug 5, 2019 at 6:03 AM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> This is a first tentative to convert some of the simplest Amlogic
> dt-bindings to the yaml format.
>
> All have been tested using :
> $ make ARCH=arm64 dtbs_check
>
> Issues with the amlogic arm64 DTs has already been identified thanks
> to the validation scripts. The DT fixes will be pushed once these yaml
> bindings are acked.
>
> Changes since rfc v1:
> - Fixed bindings according to Rob's comments
> - Added commit log
> - renamed yaml files using amlogic prefix
>
> Neil Armstrong (9):
> dt-bindings: mailbox: meson-mhu: convert to yaml
> dt-bindings: rng: amlogic,meson-rng: convert to yaml
> dt-bindings: spi: meson: convert to yaml
> dt-bindings: reset: amlogic,meson-reset: convert to yaml
> dt-bindings: arm: amlogic: amlogic,meson-gx-ao-secure: convert to yaml
> dt-bindings: phy: meson-g12a-usb2-phy: convert to yaml
> dt-bindings: phy: meson-g12a-usb3-pcie-phy: convert to yaml
> dt-bindings: serial: meson-uart: convert to yaml
> dt-bindings: watchdog: meson-gxbb-wdt: convert to yaml
For the series,
Reviewed-by: Rob Herring <robh@kernel.org>
What's your merge plan? Do you want me to take the whole series?
Rob
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 1/6] soc: amlogic: meson-gx-socinfo: add A311D id
From: Kevin Hilman @ 2019-08-05 21:47 UTC (permalink / raw)
To: Neil Armstrong
Cc: linux-amlogic, Christian Hewitt, linux-kernel, linux-arm-kernel,
Neil Armstrong
In-Reply-To: <20190731124000.22072-2-narmstrong@baylibre.com>
Neil Armstrong <narmstrong@baylibre.com> writes:
> From: Christian Hewitt <christianshewitt@gmail.com>
>
> Add the SoC ID for the A311D Amlogic SoC.
>
> Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Queued for v5.4,
Thanks,
Kevin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/6] dt-bindings: arm: amlogic: add bindings for G12B based S922X SoC
From: Kevin Hilman @ 2019-08-05 21:46 UTC (permalink / raw)
To: Neil Armstrong, devicetree
Cc: linux-amlogic, christianshewitt, linux-kernel, linux-arm-kernel,
Neil Armstrong
In-Reply-To: <20190731124000.22072-3-narmstrong@baylibre.com>
Neil Armstrong <narmstrong@baylibre.com> writes:
> Add a specific compatible for the Amlogic G12B family based S922X SoC
> to differentiate with the A311D SoC from the same family.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
> Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
> index 325c6fd3566d..3c3bc806cd23 100644
> --- a/Documentation/devicetree/bindings/arm/amlogic.yaml
> +++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
> @@ -139,6 +139,7 @@ properties:
> items:
> - enum:
> - hardkernel,odroid-n2
> + - const: amlogic,s922x
> - const: amlogic,g12b
nit: in previous binding docs, we were trying to keep these sorted
alphabetically. I'll reorder the new "s922x" after "g12b" when
applying.
Thanks,
Kevin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFCv2 3/9] dt-bindings: spi: meson: convert to yaml
From: Rob Herring @ 2019-08-05 21:45 UTC (permalink / raw)
To: Neil Armstrong
Cc: linux-amlogic, devicetree,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
linux-spi
In-Reply-To: <20190805120320.32282-4-narmstrong@baylibre.com>
On Mon, Aug 5, 2019 at 6:03 AM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> Now that we have the DT validation in place, let's convert the device tree
> bindings for the Amlogic SPI controllers over to two separate YAML schemas.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
> .../bindings/spi/amlogic,meson-gx-spicc.yaml | 67 +++++++++++++++++++
> .../bindings/spi/amlogic,meson6-spifc.yaml | 53 +++++++++++++++
> .../devicetree/bindings/spi/spi-meson.txt | 55 ---------------
> 3 files changed, 120 insertions(+), 55 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml
> create mode 100644 Documentation/devicetree/bindings/spi/amlogic,meson6-spifc.yaml
> delete mode 100644 Documentation/devicetree/bindings/spi/spi-meson.txt
>
> diff --git a/Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml b/Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml
> new file mode 100644
> index 000000000000..49b617c98ae7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml
> @@ -0,0 +1,67 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright 2019 BayLibre, SAS
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/spi/amlogic,meson-gx-spicc.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Amlogic Meson SPI Communication Controller
> +
> +maintainers:
> + - Neil Armstrong <narmstrong@baylibre.com>
> +
> +allOf:
> + - $ref: "spi-controller.yaml#"
> +
> +description: |
> + The Meson SPICC is a generic SPI controller for general purpose Full-Duplex
> + communications with dedicated 16 words RX/TX PIO FIFOs.
> +
> +properties:
> + compatible:
> + enum:
> + - amlogic,meson-gx-spicc # SPICC controller on Amlogic GX and compatible SoCs
> + - amlogic,meson-axg-spicc # SPICC controller on Amlogic AXG and compatible SoCs
> +
> + interrupts:
> + maxItems: 1
> +
> + reg:
> + maxItems: 1
> +
> + resets:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
> +
> + clock-names:
> + description: input clock for the baud rate generator
> + items:
> + - const: core
> +
> +required:
> + - compatible
> + - reg
> + - interrupts
> + - clocks
> + - clock-names
> +
> +examples:
> + - |
> + spi@c1108d80 {
> + compatible = "amlogic,meson-gx-spicc";
> + reg = <0xc1108d80 0x80>;
> + interrupts = <112>;
> + clocks = <&clk81>;
> + clock-names = "core";
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + ethernet-switch@0 {
> + compatible = "micrel,ks8995m";
> + spi-max-frequency = <1000000>;
> + reg = <0>;
> + };
> + };
> +
> diff --git a/Documentation/devicetree/bindings/spi/amlogic,meson6-spifc.yaml b/Documentation/devicetree/bindings/spi/amlogic,meson6-spifc.yaml
> new file mode 100644
> index 000000000000..67dcedc81a5e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spi/amlogic,meson6-spifc.yaml
> @@ -0,0 +1,53 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright 2019 BayLibre, SAS
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/spi/amlogic,meson6-spifc.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Amlogic Meson SPI Flash Controller
> +
> +maintainers:
> + - Neil Armstrong <narmstrong@baylibre.com>
> +
> +allOf:
> + - $ref: "spi-controller.yaml#"
> +
> +description: |
> + The Meson SPIFC is a controller optimized for communication with SPI
> + NOR memories, without DMA support and a 64-byte unified transmit /
> + receive buffer.
> +
> +properties:
> + compatible:
> + enum:
> + - amlogic,meson6-spifc # SPI Flash Controller on Meson6 and compatible SoCs
> + - amlogic,meson-gxbb-spifc # SPI Flash Controller on GXBB and compatible SoCs
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> +
> +examples:
> + - |
> + spi@c1108c80 {
> + compatible = "amlogic,meson6-spifc";
> + reg = <0xc1108c80 0x80>;
> + clocks = <&clk81>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + flash: m25p80@0 {
flash@0
I need to write a schema for this or I'll never stop giving this comment...
Otherwise,
Reviewed-by: Rob Herring <robh@kernel.org>
> + compatible = "spansion,m25p80", "jedec,spi-nor";
> + reg = <0>;
> + spi-max-frequency = <40000000>;
> + };
> + };
> +
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 0/4] Rework secure-monitor driver
From: Kevin Hilman @ 2019-08-05 21:34 UTC (permalink / raw)
To: Carlo Caione, srinivas.kandagatla
Cc: devicetree, narmstrong, Carlo Caione, robh+dt, linux-amlogic,
tglx, linux-arm-kernel, jbrunet
In-Reply-To: <20190731082339.20163-1-ccaione@baylibre.com>
Srinivas,
Carlo Caione <ccaione@baylibre.com> writes:
> The secure-monitor driver is currently in really bad shape, not my
> proudest piece of code (thanks Jerome for pointing that out ;). I tried
> to rework it a bit to make it a bit more tolerable.
>
> I needed to change a bit the APIs and consequently adapt the only user
> we have, that is the nvmem/efuses driver. To not break bisectability I
> added one single commit to change both the drivers.
With your ack on the nvmem bindings and nvmem part of patch 4/4, I can
take the series take the rest of this series through my tree for Amlogic
SoCs.
Kevin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 0/2] ARM: dts: meson8b: persistent MAC address for Odroid-C1
From: Kevin Hilman @ 2019-08-05 21:23 UTC (permalink / raw)
To: Martin Blumenstingl, linux-amlogic
Cc: Martin Blumenstingl, linux-kernel, linux-arm-kernel, ottuzzi
In-Reply-To: <20190727194647.15355-1-martin.blumenstingl@googlemail.com>
Martin Blumenstingl <martin.blumenstingl@googlemail.com> writes:
> This series makes Odroid-C1 use the MAC address which is programmed into
> the eFuse.
Queued for v5.4.
> build-time dependencies:
> patches are based on top of "ARM: dts: meson8b: add VDDEE / mali-supply"
> from [0]
>
> runtime dependencies (without these a random MAC address is assigned,
> just like before these patches):
> - "nvmem: meson-mx-efuse: allow reading data smaller than word_size"
> from [1]
> - "net: stmmac: manage errors returned by of_get_mac_address()" from [2]
Looks like the nvmem patch isn't queued yet, but AFAICT queuing these
will have no adverse affect.
Kevin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox