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
_______________________________________________
linux-amlogic mailing list
linux-amlogic@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-amlogic
WARNING: multiple messages have this Message-ID (diff)
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:41 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-04 8:14 Dan Carpenter [this message]
2025-08-04 8:14 ` [bug report] spi: Add Amlogic SPISG driver Dan Carpenter
-- strict thread matches above, loose matches on Subject: below --
2025-08-01 13:04 Dan Carpenter
2025-08-01 13:04 ` Dan Carpenter
2025-08-01 13:02 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.