Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: mediatek: Fix package division error

Commit 7e963fb2a33ce ("spi: mediatek: add ipm design support
for MT7986") makes a mistake on package dividing operation
(one change is missing), need to fix it.

Background:
Ipm design is expanding the HW capability of dma (adjust package
length from 1KB to 64KB), and using "dev_comp->ipm_support" flag
to indicate it.

Issue description:
Ipm support patch (said above) is missing to handle remainder at
package dividing operation.
One case, a transmission length is 65KB, is will divide to 1K
(package length) * 65(package loop) in non-ipm desgin case, and
will divide to 64K(package length) * 1(package loop) + 1K(remainder)
in ipm design case. And the 1K remainder will be lost with the
current SW flow, and the transmission will be failure.
So, it should be fixed.

Solution:
Add "ipm_design" flag in function "mtk_spi_get_mult_delta()" to
indicate HW capability, and modify the parameters corespondingly.

fixes: 7e963fb2a33ce ("spi: mediatek: add ipm design support for MT7986")
Signed-off-by: zhichao.liu <zhichao.liu@mediatek.com>
Link: https://lore.kernel.org/r/20221021091653.18297-1-zhichao.liu@mediatek.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

zhichao.liu and committed by
Mark Brown
cf82d0ec ae4b3c12

+13 -10
+13 -10
drivers/spi/spi-mt65xx.c
··· 551 551 writel(cmd, mdata->base + SPI_CMD_REG); 552 552 } 553 553 554 - static int mtk_spi_get_mult_delta(u32 xfer_len) 554 + static int mtk_spi_get_mult_delta(struct mtk_spi *mdata, u32 xfer_len) 555 555 { 556 - u32 mult_delta; 556 + u32 mult_delta = 0; 557 557 558 - if (xfer_len > MTK_SPI_PACKET_SIZE) 559 - mult_delta = xfer_len % MTK_SPI_PACKET_SIZE; 560 - else 561 - mult_delta = 0; 558 + if (mdata->dev_comp->ipm_design) { 559 + if (xfer_len > MTK_SPI_IPM_PACKET_SIZE) 560 + mult_delta = xfer_len % MTK_SPI_IPM_PACKET_SIZE; 561 + } else { 562 + if (xfer_len > MTK_SPI_PACKET_SIZE) 563 + mult_delta = xfer_len % MTK_SPI_PACKET_SIZE; 564 + } 562 565 563 566 return mult_delta; 564 567 } ··· 573 570 574 571 if (mdata->tx_sgl_len && mdata->rx_sgl_len) { 575 572 if (mdata->tx_sgl_len > mdata->rx_sgl_len) { 576 - mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len); 573 + mult_delta = mtk_spi_get_mult_delta(mdata, mdata->rx_sgl_len); 577 574 mdata->xfer_len = mdata->rx_sgl_len - mult_delta; 578 575 mdata->rx_sgl_len = mult_delta; 579 576 mdata->tx_sgl_len -= mdata->xfer_len; 580 577 } else { 581 - mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len); 578 + mult_delta = mtk_spi_get_mult_delta(mdata, mdata->tx_sgl_len); 582 579 mdata->xfer_len = mdata->tx_sgl_len - mult_delta; 583 580 mdata->tx_sgl_len = mult_delta; 584 581 mdata->rx_sgl_len -= mdata->xfer_len; 585 582 } 586 583 } else if (mdata->tx_sgl_len) { 587 - mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len); 584 + mult_delta = mtk_spi_get_mult_delta(mdata, mdata->tx_sgl_len); 588 585 mdata->xfer_len = mdata->tx_sgl_len - mult_delta; 589 586 mdata->tx_sgl_len = mult_delta; 590 587 } else if (mdata->rx_sgl_len) { 591 - mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len); 588 + mult_delta = mtk_spi_get_mult_delta(mdata, mdata->rx_sgl_len); 592 589 mdata->xfer_len = mdata->rx_sgl_len - mult_delta; 593 590 mdata->rx_sgl_len = mult_delta; 594 591 }