diff mbox series

[2/2] spi: cadence-quadspi: Fix check condition for DTR ops

Message ID 20210713125743.1540-3-a-nandan@ti.com (mailing list archive)
State Superseded
Headers show
Series spi: cadence-quadspi: Fix DTR op checks and timeout in SPI NAND write operations | expand

Commit Message

Apurva Nandan July 13, 2021, 12:57 p.m. UTC
buswidth and dtr fields in spi_mem_op are only valid when the
corresponding spi_mem_op phase has a non-zero length. For example,
SPI NAND core doesn't set buswidth when using SPI_MEM_OP_NO_ADDR
phase.

Fix the dtr checks in set_protocol() and suppports_mem_op() to
ignore empty spi_mem_op phases, as checking for dtr field in
empty phase will result in false negatives.

Signed-off-by: Apurva Nandan <a-nandan@ti.com>
---
 drivers/spi/spi-cadence-quadspi.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

Comments

Mark Brown July 13, 2021, 6:39 p.m. UTC | #1
On Tue, Jul 13, 2021 at 12:57:42PM +0000, Apurva Nandan wrote:

> +	f_pdata->dtr = op->cmd.dtr &&
> +		       (op->addr.dtr || !op->addr.nbytes) &&
> +		       (op->data.dtr || !op->data.nbytes);

I'm not sure anyone reading this code is going to figure out what it's
doing without thinking about it, the combination of writing the bytes
check with a !, putting it after the check for .dtr and not having any
comments is a bit obscure.  Something like

	(op->addr.nbytes && op.addr.dtr)

might be a bit clearer, or a comment explicitly spelling it out.
Apurva Nandan July 14, 2021, 12:54 p.m. UTC | #2
On 14-Jul-21 12:09 AM, Mark Brown wrote:
> On Tue, Jul 13, 2021 at 12:57:42PM +0000, Apurva Nandan wrote:
> 
>> +	f_pdata->dtr = op->cmd.dtr &&
>> +		       (op->addr.dtr || !op->addr.nbytes) &&
>> +		       (op->data.dtr || !op->data.nbytes);
> 
> I'm not sure anyone reading this code is going to figure out what it's
> doing without thinking about it, the combination of writing the bytes
> check with a !, putting it after the check for .dtr and not having any
> comments is a bit obscure.  Something like
> 
> 	(op->addr.nbytes && op.addr.dtr)
> 
> might be a bit clearer, or a comment explicitly spelling it out.
> 

Okay, I will add a comment explaining it, as other logic (with &&) won't
deliver the behavior we expect.

The logic it implements is: for an op to be dtr, if any phase has
non-zero bytes, it must have dtr field set as true. So, it does p
implies q: p->q = (!p || q) i.e. if phase has non-zero bytes (p) then
check its dtr field (q). If all phases are empty, then follow what
op.cmd.dtr says.

Regards,
Apurva Nandan
diff mbox series

Patch

diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index a2e1f4ce8b3e..a884678e8dff 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -322,7 +322,9 @@  static int cqspi_set_protocol(struct cqspi_flash_pdata *f_pdata,
 	f_pdata->inst_width = CQSPI_INST_TYPE_SINGLE;
 	f_pdata->addr_width = CQSPI_INST_TYPE_SINGLE;
 	f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
-	f_pdata->dtr = op->data.dtr && op->cmd.dtr && op->addr.dtr;
+	f_pdata->dtr = op->cmd.dtr &&
+		       (op->addr.dtr || !op->addr.nbytes) &&
+		       (op->data.dtr || !op->data.nbytes);
 
 	switch (op->data.buswidth) {
 	case 0:
@@ -1225,8 +1227,12 @@  static bool cqspi_supports_mem_op(struct spi_mem *mem,
 {
 	bool all_true, all_false;
 
-	all_true = op->cmd.dtr && op->addr.dtr && op->dummy.dtr &&
-		   op->data.dtr;
+	/* op->dummy.dtr is checked when converting nbytes into ncycles.*/
+	all_true = op->cmd.dtr &&
+		   (op->addr.dtr || !op->addr.nbytes) &&
+		   (op->dummy.dtr || !op->dummy.nbytes) &&
+		   (op->data.dtr || !op->data.nbytes);
+
 	all_false = !op->cmd.dtr && !op->addr.dtr && !op->dummy.dtr &&
 		    !op->data.dtr;