Hello,
I found a bug in the drivers/mux/adgs1408.c driver that causes MUX_IDLE_AS_IS mode does not work at all.
Specifically, the comparison "if (idle_state < mux->states)" in the switch statement fails due to Usual arithmetic conversions if idle_state is set to a negative value, such as MUX_IDLE_AS_IS (-1). Refer to The C standard (ISO/IEC 9899:2011), section 6.3.1.8 Usual arithmetic conversions https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf#page=52.
To fix this issue, I suggest adding an explicit type cast to the comparison.
Here's the modified code:
diff --git a/drivers/mux/adgs1408.c b/drivers/mux/adgs1408.c
index 22ed051eb1a4..c59e0bed80d1 100644
--- a/drivers/mux/adgs1408.c
+++ b/drivers/mux/adgs1408.c
@@ -89,7 +89,9 @@ static int adgs1408_probe(struct spi_device *spi)
case MUX_IDLE_AS_IS:
case 0 ... 7:
/* adgs1409 supports only 4 states */
- if (idle_state < mux->states) {
+ /* the idle_state will be implicitly converted to an unsigned int in
+ the comparison, which will fail the comparison if without (int) */
+ if (idle_state < (int)mux->states) {
mux->idle_state = idle_state;
break;
}
--
With this fix, adgs1408 can work with MUX_IDLE_AS_IS in our development board.
Please let me know if you have any questions or concerns about this patch.
Thank you for your attention to this issue.
Best regards,
Ping Li
From e96bb5ab8b5c7e1dcda4ffeffc64d6b120579baf Mon Sep 17 00:00:00 2001
From: "Ping.Li" <Ping.Li@xxxxxxxxxx>
Date: Wed, 26 Apr 2023 13:52:53 +0930
Subject: [PATCH] Fix comparison of signed and unsigned integers in adgs1408.c
Signed-off-by: Ping.Li <Ping.Li@xxxxxxxxxx>
---
drivers/mux/adgs1408.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/mux/adgs1408.c b/drivers/mux/adgs1408.c
index 22ed051eb1a4..c59e0bed80d1 100644
--- a/drivers/mux/adgs1408.c
+++ b/drivers/mux/adgs1408.c
@@ -89,7 +89,9 @@ static int adgs1408_probe(struct spi_device *spi)
case MUX_IDLE_AS_IS:
case 0 ... 7:
/* adgs1409 supports only 4 states */
- if (idle_state < mux->states) {
+ /* the idle_state will be implicitly converted to an unsigned int in
+ the comparison, which will fail the comparison if without (int) */
+ if (idle_state < (int)mux->states) {
mux->idle_state = idle_state;
break;
}
--
2.25.1