spi: spi-mem: Adjust op len based on message/transfer size limitations
authorChuanhua Han <chuanhua.han@nxp.com>
Thu, 30 Aug 2018 08:43:24 +0000 (16:43 +0800)
committerMark Brown <broonie@kernel.org>
Mon, 10 Sep 2018 17:41:46 +0000 (18:41 +0100)
We need that to adjust the len of the 2nd transfer (called data in
spi-mem) if it's too long to fit in a SPI message or SPI transfer.

Fixes: c36ff266dc82 ("spi: Extend the core to ease integration of SPI memory controllers")
Cc: <stable@vger.kernel.org>
Signed-off-by: Chuanhua Han <chuanhua.han@nxp.com>
Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-mem.c

index e43842c7a31a90388b4eeb3be6ab9a420e30d28b..eb72dba71d832a47165b824c2f859fed00a33a4e 100644 (file)
@@ -346,10 +346,25 @@ EXPORT_SYMBOL_GPL(spi_mem_get_name);
 int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
 {
        struct spi_controller *ctlr = mem->spi->controller;
+       size_t len;
+
+       len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes;
 
        if (ctlr->mem_ops && ctlr->mem_ops->adjust_op_size)
                return ctlr->mem_ops->adjust_op_size(mem, op);
 
+       if (!ctlr->mem_ops || !ctlr->mem_ops->exec_op) {
+               if (len > spi_max_transfer_size(mem->spi))
+                       return -EINVAL;
+
+               op->data.nbytes = min3((size_t)op->data.nbytes,
+                                      spi_max_transfer_size(mem->spi),
+                                      spi_max_message_size(mem->spi) -
+                                      len);
+               if (!op->data.nbytes)
+                       return -EINVAL;
+       }
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size);