]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
spi: spi-mem: add spi_mem_dtr_supports_op()
authorPratyush Yadav <p.yadav@ti.com>
Fri, 25 Jun 2021 19:17:06 +0000 (00:47 +0530)
committerJagan Teki <jagan@amarulasolutions.com>
Mon, 28 Jun 2021 06:26:06 +0000 (11:56 +0530)
spi_mem_default_supports_op() rejects DTR ops by default to ensure that
the controller drivers that haven't been updated with DTR support
continue to reject them. It also makes sure that controllers that don't
support DTR mode at all (which is most of them at the moment) also
reject them.

This means that controller drivers that want to support DTR mode can't
use spi_mem_default_supports_op(). Driver authors have to roll their own
supports_op() function and mimic the buswidth checks. Or even worse,
driver authors might skip it completely or get it wrong.

Add spi_mem_dtr_supports_op(). It provides a basic sanity check for DTR
ops and performs the buswidth requirement check. Move the logic for
checking buswidth in spi_mem_default_supports_op() to a separate
function so the logic is not repeated twice.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
Acked-by: Jagan Teki <jagan@amarulasolutions.com>
drivers/spi/spi-mem.c
include/spi-mem.h

index 541cd0e5a775d85a46aed7bcc6c81bdf168a2c44..9c1ede1b61cfab232e297083754d2f9df6fcb81a 100644 (file)
@@ -145,8 +145,8 @@ static int spi_check_buswidth_req(struct spi_slave *slave, u8 buswidth, bool tx)
        return -ENOTSUPP;
 }
 
-bool spi_mem_default_supports_op(struct spi_slave *slave,
-                                const struct spi_mem_op *op)
+static bool spi_mem_check_buswidth(struct spi_slave *slave,
+                                  const struct spi_mem_op *op)
 {
        if (spi_check_buswidth_req(slave, op->cmd.buswidth, true))
                return false;
@@ -164,13 +164,39 @@ bool spi_mem_default_supports_op(struct spi_slave *slave,
                                   op->data.dir == SPI_MEM_DATA_OUT))
                return false;
 
+       return true;
+}
+
+bool spi_mem_dtr_supports_op(struct spi_slave *slave,
+                            const struct spi_mem_op *op)
+{
+       if (op->cmd.buswidth == 8 && op->cmd.nbytes % 2)
+               return false;
+
+       if (op->addr.nbytes && op->addr.buswidth == 8 && op->addr.nbytes % 2)
+               return false;
+
+       if (op->dummy.nbytes && op->dummy.buswidth == 8 && op->dummy.nbytes % 2)
+               return false;
+
+       if (op->data.dir != SPI_MEM_NO_DATA &&
+           op->dummy.buswidth == 8 && op->data.nbytes % 2)
+               return false;
+
+       return spi_mem_check_buswidth(slave, op);
+}
+EXPORT_SYMBOL_GPL(spi_mem_dtr_supports_op);
+
+bool spi_mem_default_supports_op(struct spi_slave *slave,
+                                const struct spi_mem_op *op)
+{
        if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr)
                return false;
 
        if (op->cmd.nbytes != 1)
                return false;
 
-       return true;
+       return spi_mem_check_buswidth(slave, op);
 }
 EXPORT_SYMBOL_GPL(spi_mem_default_supports_op);
 
index de3c11c8e24a35342576e367096e510a00083652..32ffdc2e0f963c239e3e6a70c5ba1880823ad78a 100644 (file)
@@ -249,6 +249,8 @@ spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr,
 int spi_mem_adjust_op_size(struct spi_slave *slave, struct spi_mem_op *op);
 
 bool spi_mem_supports_op(struct spi_slave *slave, const struct spi_mem_op *op);
+bool spi_mem_dtr_supports_op(struct spi_slave *slave,
+                            const struct spi_mem_op *op);
 
 bool spi_mem_default_supports_op(struct spi_slave *slave,
                                 const struct spi_mem_op *op);