From: Dan Carpenter <dan.carpenter@linaro.org>
To: Sunny Luo <sunny.luo@amlogic.com>
Cc: linux-amlogic@lists.infradead.org, linux-spi@vger.kernel.org
Subject: [bug report] spi: Add Amlogic SPISG driver
Date: Mon, 4 Aug 2025 11:14:00 +0300 [thread overview]
Message-ID: <aJBryDMreHB9dI_i@stanley.mountain> (raw)
Hello Sunny Luo,
Commit cef9991e04ae ("spi: Add Amlogic SPISG driver") from Jul 18,
2025 (linux-next), leads to the following Smatch static checker
warning:
drivers/spi/spi-amlogic-spisg.c:314 aml_spisg_setup_transfer()
error: we previously assumed 'exdesc' could be null (see line 261)
drivers/spi/spi-amlogic-spisg.c
248 static int aml_spisg_setup_transfer(struct spisg_device *spisg,
249 struct spi_transfer *xfer,
250 struct spisg_descriptor *desc,
251 struct spisg_descriptor_extra *exdesc)
252 {
253 int block_size, blocks;
254 struct device *dev = &spisg->pdev->dev;
255 struct spisg_sg_link *ccsg;
256 int ccsg_len;
257 dma_addr_t paddr;
258 int ret;
259
260 memset(desc, 0, sizeof(*desc));
261 if (exdesc)
^^^^^^
Checked for NULL
262 memset(exdesc, 0, sizeof(*exdesc));
263 aml_spisg_set_speed(spisg, xfer->speed_hz);
264 xfer->effective_speed_hz = spisg->effective_speed_hz;
265
266 desc->cfg_start = spisg->cfg_start;
267 desc->cfg_bus = spisg->cfg_bus;
268
269 block_size = xfer->bits_per_word >> 3;
270 blocks = xfer->len / block_size;
271
272 desc->cfg_start |= FIELD_PREP(CFG_EOC, 0);
273 desc->cfg_bus |= FIELD_PREP(CFG_KEEP_SS, !xfer->cs_change);
274 desc->cfg_bus |= FIELD_PREP(CFG_NULL_CTL, 0);
275
276 if (xfer->tx_buf || xfer->tx_dma) {
277 desc->cfg_bus |= FIELD_PREP(CFG_LANE, nbits_to_lane[xfer->tx_nbits]);
278 desc->cfg_start |= FIELD_PREP(CFG_OP_MODE, SPISG_OP_MODE_WRITE);
279 }
280 if (xfer->rx_buf || xfer->rx_dma) {
281 desc->cfg_bus |= FIELD_PREP(CFG_LANE, nbits_to_lane[xfer->rx_nbits]);
282 desc->cfg_start |= FIELD_PREP(CFG_OP_MODE, SPISG_OP_MODE_READ);
283 }
284
285 if (FIELD_GET(CFG_OP_MODE, desc->cfg_start) == SPISG_OP_MODE_READ_STS) {
286 desc->cfg_start |= FIELD_PREP(CFG_BLOCK_SIZE, blocks) |
287 FIELD_PREP(CFG_BLOCK_NUM, 1);
288 } else {
289 blocks = min_t(int, blocks, SPISG_BLOCK_MAX);
290 desc->cfg_start |= FIELD_PREP(CFG_BLOCK_SIZE, block_size & 0x7) |
291 FIELD_PREP(CFG_BLOCK_NUM, blocks);
292 }
293
294 if (xfer->tx_sg.nents && xfer->tx_sg.sgl) {
295 ccsg_len = xfer->tx_sg.nents * sizeof(struct spisg_sg_link);
296 ccsg = kzalloc(ccsg_len, GFP_KERNEL | GFP_DMA);
297 if (!ccsg) {
298 dev_err(dev, "alloc tx_ccsg failed\n");
299 return -ENOMEM;
300 }
301
302 aml_spisg_sg_xlate(&xfer->tx_sg, ccsg);
303 paddr = dma_map_single(dev, (void *)ccsg,
304 ccsg_len, DMA_TO_DEVICE);
305 ret = dma_mapping_error(dev, paddr);
306 if (ret) {
307 kfree(ccsg);
308 dev_err(dev, "tx ccsg map failed\n");
309 return ret;
310 }
311
312 desc->tx_paddr = paddr;
313 desc->cfg_start |= FIELD_PREP(CFG_TXD_MODE, SPISG_DATA_MODE_SG);
--> 314 exdesc->tx_ccsg = ccsg;
^^^^^^^^
Unchecked dereference
315 exdesc->tx_ccsg_len = ccsg_len;
316 dma_sync_sgtable_for_device(spisg->controller->cur_tx_dma_dev,
317 &xfer->tx_sg, DMA_TO_DEVICE);
318 } else if (xfer->tx_buf || xfer->tx_dma) {
319 paddr = xfer->tx_dma;
320 if (!paddr) {
321 paddr = dma_map_single(dev, (void *)xfer->tx_buf,
322 xfer->len, DMA_TO_DEVICE);
323 ret = dma_mapping_error(dev, paddr);
324 if (ret) {
325 dev_err(dev, "tx buf map failed\n");
326 return ret;
327 }
328 }
329 desc->tx_paddr = paddr;
330 desc->cfg_start |= FIELD_PREP(CFG_TXD_MODE, SPISG_DATA_MODE_MEM);
331 }
332
333 if (xfer->rx_sg.nents && xfer->rx_sg.sgl) {
334 ccsg_len = xfer->rx_sg.nents * sizeof(struct spisg_sg_link);
335 ccsg = kzalloc(ccsg_len, GFP_KERNEL | GFP_DMA);
336 if (!ccsg) {
337 dev_err(dev, "alloc rx_ccsg failed\n");
338 return -ENOMEM;
339 }
340
341 aml_spisg_sg_xlate(&xfer->rx_sg, ccsg);
342 paddr = dma_map_single(dev, (void *)ccsg,
343 ccsg_len, DMA_TO_DEVICE);
344 ret = dma_mapping_error(dev, paddr);
345 if (ret) {
346 kfree(ccsg);
347 dev_err(dev, "rx ccsg map failed\n");
348 return ret;
349 }
350
351 desc->rx_paddr = paddr;
352 desc->cfg_start |= FIELD_PREP(CFG_RXD_MODE, SPISG_DATA_MODE_SG);
353 exdesc->rx_ccsg = ccsg;
354 exdesc->rx_ccsg_len = ccsg_len;
355 dma_sync_sgtable_for_device(spisg->controller->cur_rx_dma_dev,
356 &xfer->rx_sg, DMA_FROM_DEVICE);
357 } else if (xfer->rx_buf || xfer->rx_dma) {
358 paddr = xfer->rx_dma;
359 if (!paddr) {
360 paddr = dma_map_single(dev, xfer->rx_buf,
361 xfer->len, DMA_FROM_DEVICE);
362 ret = dma_mapping_error(dev, paddr);
363 if (ret) {
364 dev_err(dev, "rx buf map failed\n");
365 return ret;
366 }
367 }
368
369 desc->rx_paddr = paddr;
370 desc->cfg_start |= FIELD_PREP(CFG_RXD_MODE, SPISG_DATA_MODE_MEM);
371 }
372
373 return 0;
374 }
regards,
dan carpenter
next reply other threads:[~2025-08-04 8:14 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-04 8:14 Dan Carpenter [this message]
-- strict thread matches above, loose matches on Subject: below --
2025-08-01 13:04 [bug report] spi: Add Amlogic SPISG driver Dan Carpenter
2025-08-01 13:02 Dan Carpenter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aJBryDMreHB9dI_i@stanley.mountain \
--to=dan.carpenter@linaro.org \
--cc=linux-amlogic@lists.infradead.org \
--cc=linux-spi@vger.kernel.org \
--cc=sunny.luo@amlogic.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).