Message ID | 20200922114317.2935897-1-gch981213@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | spi: spi-mtk-nor: fix timeout calculation overflow | expand |
On Tue, Sep 22, 2020 at 7:43 PM Chuanhong Guo <gch981213@gmail.com> wrote: > > CLK_TO_US macro is used to calculate potential transfer time for various > timeout handling. However it overflows on transfer bigger than 512 bytes > because it first did (len * 8 * 1000000). > This controller typically operates at 45MHz. This patch did 2 things: > 1. calculate clock / 1000000 first > 2. add a 4M transfer size cap so that the final timeout in DMA reading > doesn't overflow > > Fixes: 881d1ee9fe81f ("spi: add support for mediatek spi-nor controller") > Cc: <stable@vger.kernel.org> > Signed-off-by: Chuanhong Guo <gch981213@gmail.com> > --- > drivers/spi/spi-mtk-nor.c | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c > index 6e6ca2b8e6c82..619313db42c0e 100644 > --- a/drivers/spi/spi-mtk-nor.c > +++ b/drivers/spi/spi-mtk-nor.c > @@ -89,7 +89,7 @@ > // Buffered page program can do one 128-byte transfer > #define MTK_NOR_PP_SIZE 128 > > -#define CLK_TO_US(sp, clkcnt) ((clkcnt) * 1000000 / sp->spi_freq) > +#define CLK_TO_US(sp, clkcnt) DIV_ROUND_UP(clkcnt, sp->spi_freq / 1000000) > > struct mtk_nor { > struct spi_controller *ctlr; > @@ -177,6 +177,10 @@ static int mtk_nor_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) > if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) { > if ((op->data.dir == SPI_MEM_DATA_IN) && > mtk_nor_match_read(op)) { > + // limit size to prevent timeout calculation overflow > + if (op->data.nbytes > 0x2000000) > + op->data.nbytes = 0x2000000; > + Sorry, wrong patch. This cap should be 4M not 32M. I'll send a v2 immediately.
diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c index 6e6ca2b8e6c82..619313db42c0e 100644 --- a/drivers/spi/spi-mtk-nor.c +++ b/drivers/spi/spi-mtk-nor.c @@ -89,7 +89,7 @@ // Buffered page program can do one 128-byte transfer #define MTK_NOR_PP_SIZE 128 -#define CLK_TO_US(sp, clkcnt) ((clkcnt) * 1000000 / sp->spi_freq) +#define CLK_TO_US(sp, clkcnt) DIV_ROUND_UP(clkcnt, sp->spi_freq / 1000000) struct mtk_nor { struct spi_controller *ctlr; @@ -177,6 +177,10 @@ static int mtk_nor_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) { if ((op->data.dir == SPI_MEM_DATA_IN) && mtk_nor_match_read(op)) { + // limit size to prevent timeout calculation overflow + if (op->data.nbytes > 0x2000000) + op->data.nbytes = 0x2000000; + if ((op->addr.val & MTK_NOR_DMA_ALIGN_MASK) || (op->data.nbytes < MTK_NOR_DMA_ALIGN)) op->data.nbytes = 1;
CLK_TO_US macro is used to calculate potential transfer time for various timeout handling. However it overflows on transfer bigger than 512 bytes because it first did (len * 8 * 1000000). This controller typically operates at 45MHz. This patch did 2 things: 1. calculate clock / 1000000 first 2. add a 4M transfer size cap so that the final timeout in DMA reading doesn't overflow Fixes: 881d1ee9fe81f ("spi: add support for mediatek spi-nor controller") Cc: <stable@vger.kernel.org> Signed-off-by: Chuanhong Guo <gch981213@gmail.com> --- drivers/spi/spi-mtk-nor.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)