public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
* [bug report] media: stm32: dcmi: addition of DMA-MDMA chaining support
@ 2026-04-10 18:04 Dan Carpenter
  0 siblings, 0 replies; only message in thread
From: Dan Carpenter @ 2026-04-10 18:04 UTC (permalink / raw)
  To: Alain Volmat; +Cc: linux-media

Hello Alain Volmat,

Commit 87ebce19aa03 ("media: stm32: dcmi: addition of DMA-MDMA
chaining support") from Jan 6, 2026 (linux-next), leads to the
following Smatch static checker warning:

	drivers/media/platform/st/stm32/stm32-dcmi.c:2053 dcmi_probe()
	warn: missing error code here? 'of_gen_pool_get()' failed. 'ret' = '0'

drivers/media/platform/st/stm32/stm32-dcmi.c
    1954 static int dcmi_probe(struct platform_device *pdev)
    1955 {
    1956         struct device_node *np = pdev->dev.of_node;
    1957         struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
    1958         struct stm32_dcmi *dcmi;
    1959         struct vb2_queue *q;
    1960         struct dma_chan *chan, *mdma_chan;
    1961         struct dma_slave_caps caps;
    1962         struct dma_slave_config dma_config, mdma_config;
    1963         struct clk *mclk;
    1964         int ret = 0;
    1965 
    1966         dcmi = devm_kzalloc(&pdev->dev, sizeof(struct stm32_dcmi), GFP_KERNEL);
    1967         if (!dcmi)
    1968                 return -ENOMEM;
    1969 
    1970         dcmi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
    1971         if (IS_ERR(dcmi->rstc))
    1972                 return dev_err_probe(&pdev->dev, PTR_ERR(dcmi->rstc),
    1973                                      "Could not get reset control\n");
    1974 
    1975         /* Get bus characteristics from devicetree */
    1976         np = of_graph_get_endpoint_by_regs(np, 0, -1);
    1977         if (!np) {
    1978                 dev_err(&pdev->dev, "Could not find the endpoint\n");
    1979                 return -ENODEV;
    1980         }
    1981 
    1982         ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &ep);
    1983         of_node_put(np);
    1984         if (ret) {
    1985                 dev_err(&pdev->dev, "Could not parse the endpoint\n");
    1986                 return ret;
    1987         }
    1988 
    1989         if (ep.bus_type == V4L2_MBUS_CSI2_DPHY) {
    1990                 dev_err(&pdev->dev, "CSI bus not supported\n");
    1991                 return -ENODEV;
    1992         }
    1993 
    1994         if (ep.bus_type == V4L2_MBUS_BT656 &&
    1995             ep.bus.parallel.bus_width != 8) {
    1996                 dev_err(&pdev->dev, "BT656 bus conflicts with %u bits bus width (8 bits required)\n",
    1997                         ep.bus.parallel.bus_width);
    1998                 return -ENODEV;
    1999         }
    2000 
    2001         dcmi->bus.flags = ep.bus.parallel.flags;
    2002         dcmi->bus.bus_width = ep.bus.parallel.bus_width;
    2003         dcmi->bus.data_shift = ep.bus.parallel.data_shift;
    2004         dcmi->bus_type = ep.bus_type;
    2005 
    2006         dcmi->irq = platform_get_irq(pdev, 0);
    2007         if (dcmi->irq < 0)
    2008                 return dcmi->irq;
    2009 
    2010         dcmi->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &dcmi->res);
    2011         if (IS_ERR(dcmi->regs))
    2012                 return PTR_ERR(dcmi->regs);
    2013 
    2014         mclk = devm_clk_get(&pdev->dev, "mclk");
    2015         if (IS_ERR(mclk))
    2016                 return dev_err_probe(&pdev->dev, PTR_ERR(mclk),
    2017                                      "Unable to get mclk\n");
    2018 
    2019         chan = dma_request_chan(&pdev->dev, "tx");
    2020         if (IS_ERR(chan))
    2021                 return dev_err_probe(&pdev->dev, PTR_ERR(chan),
    2022                                      "Failed to request DMA channel\n");
    2023 
    2024         mdma_chan = dma_request_chan(&pdev->dev, "mdma_tx");
    2025         if (IS_ERR(mdma_chan)) {
    2026                 ret = PTR_ERR(mdma_chan);
    2027                 if (ret != -ENODEV)
    2028                         return dev_err_probe(&pdev->dev, ret, "Failed to request MDMA channel\n");
    2029                 mdma_chan = NULL;
    2030         }
    2031 
    2032         /* Configure the DMA channel */
    2033         memset(&dma_config, 0, sizeof(dma_config));
    2034 
    2035         dma_config.src_addr = (dma_addr_t)dcmi->res->start + DCMI_DR;
    2036         dma_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
    2037         if (mdma_chan)
    2038                 dma_config.peripheral_size = 1; /* Indicates chaining */
    2039 
    2040         /* Configure DMA channel */
    2041         ret = dmaengine_slave_config(chan, &dma_config);
    2042         if (ret < 0) {
    2043                 dev_err(dcmi->dev, "%s: DMA channel config failed (%d)\n",
    2044                         __func__, ret);
    2045                 goto err_dma_slave_config;
    2046         }
    2047 
    2048         /* If we want MDMA, we also need a sram pool */
    2049         if (mdma_chan) {
    2050                 dcmi->sram_pool = of_gen_pool_get(pdev->dev.of_node, "sram", 0);
    2051                 if (!dcmi->sram_pool) {
    2052                         dev_info(&pdev->dev, "No SRAM pool, can't use MDMA chaining\n");
--> 2053                         goto err_dma_slave_config;

ret = -ENOMEM?

    2054                 }
    2055 
    2056                 dev_info(&pdev->dev, "SRAM pool: %zu KiB for DMA/MDMA chaining\n",
    2057                          gen_pool_size(dcmi->sram_pool) / 1024);
    2058 
    2059                 dcmi->sram_buf_size = gen_pool_size(dcmi->sram_pool);
    2060                 dcmi->sram_buf = gen_pool_dma_zalloc(dcmi->sram_pool, dcmi->sram_buf_size,
    2061                                                      &dcmi->sram_dma_buf);
    2062                 if (!dcmi->sram_buf) {
    2063                         dev_err(dcmi->dev, "Failed to allocate from SRAM\n");
    2064                         goto err_dma_slave_config;

ret = -ENOMEM?

    2065                 }
    2066 
    2067                 /* Configure the MDMA Channel */
    2068                 memset(&mdma_config, 0, sizeof(mdma_config));
    2069                 mdma_config.direction = DMA_DEV_TO_MEM;
    2070                 mdma_config.src_addr = dcmi->sram_dma_buf;
    2071                 mdma_config.peripheral_size = dma_config.peripheral_size;
    2072                 mdma_config.peripheral_config = dma_config.peripheral_config;
    2073                 ret = dmaengine_slave_config(mdma_chan, &mdma_config);
    2074                 if (ret < 0) {
    2075                         dev_err(dcmi->dev, "%s: MDMA channel config failed (%d)\n",
    2076                                 __func__, ret);
    2077                         goto err_mdma_slave_config;
    2078                 }
    2079         }
    2080 
    2081         dcmi->dma_max_burst = UINT_MAX;
    2082         /* In case of using DMA-MDMA chaining we consider the maximum infini */
    2083         if (!mdma_chan) {
    2084                 ret = dma_get_slave_caps(chan, &caps);
    2085                 if (!ret && caps.max_sg_burst)
    2086                         dcmi->dma_max_burst = caps.max_sg_burst * DMA_SLAVE_BUSWIDTH_4_BYTES;
    2087         }
    2088 
    2089         spin_lock_init(&dcmi->irqlock);
    2090         mutex_init(&dcmi->lock);
    2091         init_completion(&dcmi->complete);
    2092         INIT_LIST_HEAD(&dcmi->buffers);
    2093 
    2094         dcmi->dev = &pdev->dev;
    2095         dcmi->mclk = mclk;
    2096         dcmi->state = STOPPED;
    2097         dcmi->dma_chan = chan;
    2098         dcmi->mdma_chan = mdma_chan;
    2099 
    2100         q = &dcmi->queue;
    2101 
    2102         dcmi->v4l2_dev.mdev = &dcmi->mdev;
    2103 
    2104         /* Initialize media device */
    2105         strscpy(dcmi->mdev.model, DRV_NAME, sizeof(dcmi->mdev.model));
    2106         dcmi->mdev.dev = &pdev->dev;
    2107         media_device_init(&dcmi->mdev);
    2108 
    2109         /* Initialize the top-level structure */
    2110         ret = v4l2_device_register(&pdev->dev, &dcmi->v4l2_dev);
    2111         if (ret)
    2112                 goto err_media_device_cleanup;
    2113 
    2114         dcmi->vdev = video_device_alloc();
    2115         if (!dcmi->vdev) {
    2116                 ret = -ENOMEM;
    2117                 goto err_device_unregister;
    2118         }
    2119 
    2120         /* Video node */
    2121         dcmi->vdev->fops = &dcmi_fops;
    2122         dcmi->vdev->v4l2_dev = &dcmi->v4l2_dev;
    2123         dcmi->vdev->queue = &dcmi->queue;
    2124         strscpy(dcmi->vdev->name, KBUILD_MODNAME, sizeof(dcmi->vdev->name));
    2125         dcmi->vdev->release = video_device_release;
    2126         dcmi->vdev->ioctl_ops = &dcmi_ioctl_ops;
    2127         dcmi->vdev->lock = &dcmi->lock;
    2128         dcmi->vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
    2129                                   V4L2_CAP_READWRITE;
    2130         video_set_drvdata(dcmi->vdev, dcmi);
    2131 
    2132         /* Media entity pads */
    2133         dcmi->vid_cap_pad.flags = MEDIA_PAD_FL_SINK;
    2134         ret = media_entity_pads_init(&dcmi->vdev->entity,
    2135                                      1, &dcmi->vid_cap_pad);
    2136         if (ret) {
    2137                 dev_err(dcmi->dev, "Failed to init media entity pad\n");
    2138                 goto err_device_release;
    2139         }
    2140         dcmi->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
    2141 
    2142         ret = video_register_device(dcmi->vdev, VFL_TYPE_VIDEO, -1);
    2143         if (ret) {
    2144                 dev_err(dcmi->dev, "Failed to register video device\n");
    2145                 goto err_media_entity_cleanup;
    2146         }
    2147 
    2148         dev_dbg(dcmi->dev, "Device registered as %s\n",
    2149                 video_device_node_name(dcmi->vdev));
    2150 
    2151         /* Buffer queue */
    2152         q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    2153         q->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF;
    2154         q->lock = &dcmi->lock;
    2155         q->drv_priv = dcmi;
    2156         q->buf_struct_size = sizeof(struct dcmi_buf);
    2157         q->ops = &dcmi_video_qops;
    2158         q->mem_ops = &vb2_dma_contig_memops;
    2159         q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
    2160         q->min_queued_buffers = 2;
    2161         q->allow_cache_hints = 1;
    2162         q->dev = &pdev->dev;
    2163 
    2164         ret = vb2_queue_init(q);
    2165         if (ret < 0) {
    2166                 dev_err(&pdev->dev, "Failed to initialize vb2 queue\n");
    2167                 goto err_media_entity_cleanup;
    2168         }
    2169 
    2170         ret = dcmi_graph_init(dcmi);
    2171         if (ret < 0)
    2172                 goto err_media_entity_cleanup;
    2173 
    2174         /* Reset device */
    2175         ret = reset_control_assert(dcmi->rstc);
    2176         if (ret) {
    2177                 dev_err(&pdev->dev, "Failed to assert the reset line\n");
    2178                 goto err_cleanup;
    2179         }
    2180 
    2181         usleep_range(3000, 5000);
    2182 
    2183         ret = reset_control_deassert(dcmi->rstc);
    2184         if (ret) {
    2185                 dev_err(&pdev->dev, "Failed to deassert the reset line\n");
    2186                 goto err_cleanup;
    2187         }
    2188 
    2189         dev_info(&pdev->dev, "Probe done\n");
    2190 
    2191         platform_set_drvdata(pdev, dcmi);
    2192 
    2193         pm_runtime_enable(&pdev->dev);
    2194 
    2195         return 0;
    2196 
    2197 err_cleanup:
    2198         v4l2_async_nf_cleanup(&dcmi->notifier);
    2199 err_media_entity_cleanup:
    2200         media_entity_cleanup(&dcmi->vdev->entity);
    2201 err_device_release:
    2202         video_device_release(dcmi->vdev);
    2203 err_device_unregister:
    2204         v4l2_device_unregister(&dcmi->v4l2_dev);
    2205 err_media_device_cleanup:
    2206         media_device_cleanup(&dcmi->mdev);
    2207 err_mdma_slave_config:
    2208         if (dcmi->mdma_chan)
    2209                 gen_pool_free(dcmi->sram_pool, (unsigned long)dcmi->sram_buf, dcmi->sram_buf_size);
    2210 err_dma_slave_config:
    2211         dma_release_channel(dcmi->dma_chan);
    2212         if (dcmi->mdma_chan)
    2213                 dma_release_channel(mdma_chan);
    2214 
    2215         return ret;
    2216 }

This email is a free service from the Smatch-CI project [smatch.sf.net].

regards,
dan carpenter

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-04-10 18:04 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-10 18:04 [bug report] media: stm32: dcmi: addition of DMA-MDMA chaining support Dan Carpenter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox