i2c: s3c24xx: fix read transfers in polling mode
authorMarek Szyprowski <m.szyprowski@samsung.com>
Wed, 8 Nov 2023 16:43:52 +0000 (17:43 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 Jan 2024 23:36:01 +0000 (15:36 -0800)
[ Upstream commit 0d9cf23ed55d7ba3ab26d617a3ae507863674c8f ]

To properly handle read transfers in polling mode, no waiting for the ACK
state is needed as it will never come. Just wait a bit to ensure start
state is on the bus and continue processing next bytes.

Fixes: 117053f77a5a ("i2c: s3c2410: Add polling mode support")
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: Chanho Park <chanho61.park@samsung.com>
Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
Signed-off-by: Wolfram Sang <wsa@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/i2c/busses/i2c-s3c2410.c

index 127eb38..fdd7a42 100644 (file)
@@ -216,8 +216,17 @@ static bool is_ack(struct s3c24xx_i2c *i2c)
        int tries;
 
        for (tries = 50; tries; --tries) {
-               if (readl(i2c->regs + S3C2410_IICCON)
-                       & S3C2410_IICCON_IRQPEND) {
+               unsigned long tmp = readl(i2c->regs + S3C2410_IICCON);
+
+               if (!(tmp & S3C2410_IICCON_ACKEN)) {
+                       /*
+                        * Wait a bit for the bus to stabilize,
+                        * delay estimated experimentally.
+                        */
+                       usleep_range(100, 200);
+                       return true;
+               }
+               if (tmp & S3C2410_IICCON_IRQPEND) {
                        if (!(readl(i2c->regs + S3C2410_IICSTAT)
                                & S3C2410_IICSTAT_LASTBIT))
                                return true;