All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
@ 2021-04-08 14:55 ` Andy Shevchenko
  0 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 14:55 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray

The change in the series has been inspired by [1], which, I think,
can be improved. Here I present the view how it can be done.

The series marked as RFT since I have no hardware and I perform
compile test only.

The patches 1 and 2 can be (independently) applied for v5.13, but I'm not in
hurry with the series, due to above (lack of real testing). So I'm flexible in
a way how it can be proceed.

[1]: cover.1617380819.git.syednwaris@gmail.com

Andy Shevchenko (5):
  bitmap: Make bitmap_remap() and bitmap_bitremap() available to users
  gpio: xilinx: Correct kernel doc for xgpio_probe()
  gpio: xilinx: Introduce xgpio_read_chan() / xgpio_write_chan()
  gpio: xilinx: Switch to use bitmap APIs
  gpio: xilinx: No need to disable IRQs in the handler

 drivers/gpio/gpio-xilinx.c | 377 ++++++++++++++++++-------------------
 lib/bitmap.c               |   5 +-
 2 files changed, 190 insertions(+), 192 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
@ 2021-04-08 14:55 ` Andy Shevchenko
  0 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 14:55 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray

The change in the series has been inspired by [1], which, I think,
can be improved. Here I present the view how it can be done.

The series marked as RFT since I have no hardware and I perform
compile test only.

The patches 1 and 2 can be (independently) applied for v5.13, but I'm not in
hurry with the series, due to above (lack of real testing). So I'm flexible in
a way how it can be proceed.

[1]: cover.1617380819.git.syednwaris@gmail.com

Andy Shevchenko (5):
  bitmap: Make bitmap_remap() and bitmap_bitremap() available to users
  gpio: xilinx: Correct kernel doc for xgpio_probe()
  gpio: xilinx: Introduce xgpio_read_chan() / xgpio_write_chan()
  gpio: xilinx: Switch to use bitmap APIs
  gpio: xilinx: No need to disable IRQs in the handler

 drivers/gpio/gpio-xilinx.c | 377 ++++++++++++++++++-------------------
 lib/bitmap.c               |   5 +-
 2 files changed, 190 insertions(+), 192 deletions(-)

-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v1 1/5] bitmap: Make bitmap_remap() and bitmap_bitremap() available to users
  2021-04-08 14:55 ` Andy Shevchenko
@ 2021-04-08 14:55   ` Andy Shevchenko
  -1 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 14:55 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray

Currently the bitmap_remap() and bitmap_bitremap() are available
only for CONFIG_NUMA=y case, while some users may benefit out of it
and being independent to NUMA code. Make them available to users
by moving out of ifdeffery and exporting for modules.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 lib/bitmap.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/bitmap.c b/lib/bitmap.c
index 74ceb02f45e3..7b6b2a67a6a6 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -784,8 +784,6 @@ int bitmap_parse(const char *start, unsigned int buflen,
 }
 EXPORT_SYMBOL(bitmap_parse);
 
-
-#ifdef CONFIG_NUMA
 /**
  * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap
  *	@buf: pointer to a bitmap
@@ -894,6 +892,7 @@ void bitmap_remap(unsigned long *dst, const unsigned long *src,
 			set_bit(bitmap_ord_to_pos(new, n % w, nbits), dst);
 	}
 }
+EXPORT_SYMBOL(bitmap_remap);
 
 /**
  * bitmap_bitremap - Apply map defined by a pair of bitmaps to a single bit
@@ -931,7 +930,9 @@ int bitmap_bitremap(int oldbit, const unsigned long *old,
 	else
 		return bitmap_ord_to_pos(new, n % w, bits);
 }
+EXPORT_SYMBOL(bitmap_bitremap);
 
+#ifdef CONFIG_NUMA
 /**
  * bitmap_onto - translate one bitmap relative to another
  *	@dst: resulting translated bitmap
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v1 1/5] bitmap: Make bitmap_remap() and bitmap_bitremap() available to users
@ 2021-04-08 14:55   ` Andy Shevchenko
  0 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 14:55 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray

Currently the bitmap_remap() and bitmap_bitremap() are available
only for CONFIG_NUMA=y case, while some users may benefit out of it
and being independent to NUMA code. Make them available to users
by moving out of ifdeffery and exporting for modules.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 lib/bitmap.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/bitmap.c b/lib/bitmap.c
index 74ceb02f45e3..7b6b2a67a6a6 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -784,8 +784,6 @@ int bitmap_parse(const char *start, unsigned int buflen,
 }
 EXPORT_SYMBOL(bitmap_parse);
 
-
-#ifdef CONFIG_NUMA
 /**
  * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap
  *	@buf: pointer to a bitmap
@@ -894,6 +892,7 @@ void bitmap_remap(unsigned long *dst, const unsigned long *src,
 			set_bit(bitmap_ord_to_pos(new, n % w, nbits), dst);
 	}
 }
+EXPORT_SYMBOL(bitmap_remap);
 
 /**
  * bitmap_bitremap - Apply map defined by a pair of bitmaps to a single bit
@@ -931,7 +930,9 @@ int bitmap_bitremap(int oldbit, const unsigned long *old,
 	else
 		return bitmap_ord_to_pos(new, n % w, bits);
 }
+EXPORT_SYMBOL(bitmap_bitremap);
 
+#ifdef CONFIG_NUMA
 /**
  * bitmap_onto - translate one bitmap relative to another
  *	@dst: resulting translated bitmap
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v1 2/5] gpio: xilinx: Correct kernel doc for xgpio_probe()
  2021-04-08 14:55 ` Andy Shevchenko
@ 2021-04-08 14:55   ` Andy Shevchenko
  -1 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 14:55 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray

Kernel doc validator complains:

.../gpio-xilinx.c:556: warning: expecting prototype for xgpio_of_probe(). Prototype was for xgpio_probe() instead

Correct as suggested by changing the name of the function in the doc..

Fixes: 749564ffd52d ("gpio/xilinx: Convert the driver to platform device interface")
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/gpio/gpio-xilinx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index b411d3156e0b..136557e7dd3c 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -542,7 +542,7 @@ static void xgpio_irqhandler(struct irq_desc *desc)
 }
 
 /**
- * xgpio_of_probe - Probe method for the GPIO device.
+ * xgpio_probe - Probe method for the GPIO device.
  * @pdev: pointer to the platform device
  *
  * Return:
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v1 2/5] gpio: xilinx: Correct kernel doc for xgpio_probe()
@ 2021-04-08 14:55   ` Andy Shevchenko
  0 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 14:55 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray

Kernel doc validator complains:

.../gpio-xilinx.c:556: warning: expecting prototype for xgpio_of_probe(). Prototype was for xgpio_probe() instead

Correct as suggested by changing the name of the function in the doc..

Fixes: 749564ffd52d ("gpio/xilinx: Convert the driver to platform device interface")
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/gpio/gpio-xilinx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index b411d3156e0b..136557e7dd3c 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -542,7 +542,7 @@ static void xgpio_irqhandler(struct irq_desc *desc)
 }
 
 /**
- * xgpio_of_probe - Probe method for the GPIO device.
+ * xgpio_probe - Probe method for the GPIO device.
  * @pdev: pointer to the platform device
  *
  * Return:
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v1 3/5] gpio: xilinx: Introduce xgpio_read_chan() / xgpio_write_chan()
  2021-04-08 14:55 ` Andy Shevchenko
@ 2021-04-08 14:55   ` Andy Shevchenko
  -1 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 14:55 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray

With the new helpers, i.e. xgpio_read_chan() / xgpio_write_chan(),
the code is easier to read and maintain. No functional changes
intended.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/gpio/gpio-xilinx.c | 68 +++++++++++++++++++++-----------------
 1 file changed, 37 insertions(+), 31 deletions(-)

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index 136557e7dd3c..e6c78409ab3a 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -23,7 +23,8 @@
 #define XGPIO_DATA_OFFSET   (0x0)	/* Data register  */
 #define XGPIO_TRI_OFFSET    (0x4)	/* I/O direction register  */
 
-#define XGPIO_CHANNEL_OFFSET	0x8
+#define XGPIO_CHANNEL0_OFFSET	0x0
+#define XGPIO_CHANNEL1_OFFSET	0x8
 
 #define XGPIO_GIER_OFFSET	0x11c /* Global Interrupt Enable */
 #define XGPIO_GIER_IE		BIT(31)
@@ -79,12 +80,26 @@ static inline int xgpio_index(struct xgpio_instance *chip, int gpio)
 	return 0;
 }
 
-static inline int xgpio_regoffset(struct xgpio_instance *chip, int gpio)
+static inline int xgpio_regoffset(struct xgpio_instance *chip, int ch)
 {
-	if (xgpio_index(chip, gpio))
-		return XGPIO_CHANNEL_OFFSET;
+	switch (ch) {
+	case 0:
+		return XGPIO_CHANNEL0_OFFSET;
+	case 1:
+		return XGPIO_CHANNEL1_OFFSET;
+	default:
+		return -EINVAL;
+	}
+}
 
-	return 0;
+static inline u32 xgpio_read_chan(struct xgpio_instance *chip, int reg, int ch)
+{
+	return xgpio_readreg(chip->regs + reg + xgpio_regoffset(chip, ch));
+}
+
+static inline void xgpio_write_chan(struct xgpio_instance *chip, int reg, int ch, u32 v)
+{
+	xgpio_writereg(chip->regs + reg + xgpio_regoffset(chip, ch), v);
 }
 
 static inline int xgpio_offset(struct xgpio_instance *chip, int gpio)
@@ -109,12 +124,13 @@ static inline int xgpio_offset(struct xgpio_instance *chip, int gpio)
 static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
 {
 	struct xgpio_instance *chip = gpiochip_get_data(gc);
+	int index = xgpio_index(chip, gpio);
+	int offset = xgpio_offset(chip, gpio);
 	u32 val;
 
-	val = xgpio_readreg(chip->regs + XGPIO_DATA_OFFSET +
-			    xgpio_regoffset(chip, gpio));
+	val = xgpio_read_chan(chip, XGPIO_DATA_OFFSET, index);
 
-	return !!(val & BIT(xgpio_offset(chip, gpio)));
+	return !!(val & BIT(offset));
 }
 
 /**
@@ -141,8 +157,7 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 	else
 		chip->gpio_state[index] &= ~BIT(offset);
 
-	xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
-		       xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
+	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index, chip->gpio_state[index]);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 }
@@ -172,9 +187,8 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
 			break;
 		/* Once finished with an index write it out to the register */
 		if (index !=  xgpio_index(chip, i)) {
-			xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
-				       index * XGPIO_CHANNEL_OFFSET,
-				       chip->gpio_state[index]);
+			xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index,
+					 chip->gpio_state[index]);
 			spin_unlock_irqrestore(&chip->gpio_lock, flags);
 			index =  xgpio_index(chip, i);
 			spin_lock_irqsave(&chip->gpio_lock, flags);
@@ -188,8 +202,7 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
 		}
 	}
 
-	xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
-		       index * XGPIO_CHANNEL_OFFSET, chip->gpio_state[index]);
+	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index, chip->gpio_state[index]);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 }
@@ -214,8 +227,7 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 
 	/* Set the GPIO bit in shadow register and set direction as input */
 	chip->gpio_dir[index] |= BIT(offset);
-	xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET +
-		       xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
+	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, index, chip->gpio_dir[index]);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
@@ -248,13 +260,11 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 		chip->gpio_state[index] |= BIT(offset);
 	else
 		chip->gpio_state[index] &= ~BIT(offset);
-	xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
-			xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
+	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index, chip->gpio_state[index]);
 
 	/* Clear the GPIO bit in shadow register and set direction as output */
 	chip->gpio_dir[index] &= ~BIT(offset);
-	xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET +
-			xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
+	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, index, chip->gpio_dir[index]);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
@@ -267,16 +277,14 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
  */
 static void xgpio_save_regs(struct xgpio_instance *chip)
 {
-	xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET,	chip->gpio_state[0]);
-	xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET, chip->gpio_dir[0]);
+	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, 0, chip->gpio_state[0]);
+	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, 0, chip->gpio_dir[0]);
 
 	if (!chip->gpio_width[1])
 		return;
 
-	xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET + XGPIO_CHANNEL_OFFSET,
-		       chip->gpio_state[1]);
-	xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET + XGPIO_CHANNEL_OFFSET,
-		       chip->gpio_dir[1]);
+	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, 1, chip->gpio_state[1]);
+	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, 1, chip->gpio_dir[1]);
 }
 
 static int xgpio_request(struct gpio_chip *chip, unsigned int offset)
@@ -434,8 +442,7 @@ static void xgpio_irq_unmask(struct irq_data *irq_data)
 			xgpio_writereg(chip->regs + XGPIO_IPISR_OFFSET, val);
 
 		/* Update GPIO IRQ read data before enabling interrupt*/
-		val = xgpio_readreg(chip->regs + XGPIO_DATA_OFFSET +
-				    index * XGPIO_CHANNEL_OFFSET);
+		val = xgpio_read_chan(chip, XGPIO_DATA_OFFSET, index);
 		chip->gpio_last_irq_read[index] = val;
 
 		/* Enable per channel interrupt */
@@ -512,8 +519,7 @@ static void xgpio_irqhandler(struct irq_desc *desc)
 			unsigned int irq;
 
 			spin_lock_irqsave(&chip->gpio_lock, flags);
-			data = xgpio_readreg(chip->regs + XGPIO_DATA_OFFSET +
-					     index * XGPIO_CHANNEL_OFFSET);
+			data = xgpio_read_chan(chip, XGPIO_DATA_OFFSET, index);
 			rising_events = data &
 					~chip->gpio_last_irq_read[index] &
 					chip->irq_enable[index] &
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v1 3/5] gpio: xilinx: Introduce xgpio_read_chan() / xgpio_write_chan()
@ 2021-04-08 14:55   ` Andy Shevchenko
  0 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 14:55 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray

With the new helpers, i.e. xgpio_read_chan() / xgpio_write_chan(),
the code is easier to read and maintain. No functional changes
intended.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/gpio/gpio-xilinx.c | 68 +++++++++++++++++++++-----------------
 1 file changed, 37 insertions(+), 31 deletions(-)

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index 136557e7dd3c..e6c78409ab3a 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -23,7 +23,8 @@
 #define XGPIO_DATA_OFFSET   (0x0)	/* Data register  */
 #define XGPIO_TRI_OFFSET    (0x4)	/* I/O direction register  */
 
-#define XGPIO_CHANNEL_OFFSET	0x8
+#define XGPIO_CHANNEL0_OFFSET	0x0
+#define XGPIO_CHANNEL1_OFFSET	0x8
 
 #define XGPIO_GIER_OFFSET	0x11c /* Global Interrupt Enable */
 #define XGPIO_GIER_IE		BIT(31)
@@ -79,12 +80,26 @@ static inline int xgpio_index(struct xgpio_instance *chip, int gpio)
 	return 0;
 }
 
-static inline int xgpio_regoffset(struct xgpio_instance *chip, int gpio)
+static inline int xgpio_regoffset(struct xgpio_instance *chip, int ch)
 {
-	if (xgpio_index(chip, gpio))
-		return XGPIO_CHANNEL_OFFSET;
+	switch (ch) {
+	case 0:
+		return XGPIO_CHANNEL0_OFFSET;
+	case 1:
+		return XGPIO_CHANNEL1_OFFSET;
+	default:
+		return -EINVAL;
+	}
+}
 
-	return 0;
+static inline u32 xgpio_read_chan(struct xgpio_instance *chip, int reg, int ch)
+{
+	return xgpio_readreg(chip->regs + reg + xgpio_regoffset(chip, ch));
+}
+
+static inline void xgpio_write_chan(struct xgpio_instance *chip, int reg, int ch, u32 v)
+{
+	xgpio_writereg(chip->regs + reg + xgpio_regoffset(chip, ch), v);
 }
 
 static inline int xgpio_offset(struct xgpio_instance *chip, int gpio)
@@ -109,12 +124,13 @@ static inline int xgpio_offset(struct xgpio_instance *chip, int gpio)
 static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
 {
 	struct xgpio_instance *chip = gpiochip_get_data(gc);
+	int index = xgpio_index(chip, gpio);
+	int offset = xgpio_offset(chip, gpio);
 	u32 val;
 
-	val = xgpio_readreg(chip->regs + XGPIO_DATA_OFFSET +
-			    xgpio_regoffset(chip, gpio));
+	val = xgpio_read_chan(chip, XGPIO_DATA_OFFSET, index);
 
-	return !!(val & BIT(xgpio_offset(chip, gpio)));
+	return !!(val & BIT(offset));
 }
 
 /**
@@ -141,8 +157,7 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 	else
 		chip->gpio_state[index] &= ~BIT(offset);
 
-	xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
-		       xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
+	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index, chip->gpio_state[index]);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 }
@@ -172,9 +187,8 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
 			break;
 		/* Once finished with an index write it out to the register */
 		if (index !=  xgpio_index(chip, i)) {
-			xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
-				       index * XGPIO_CHANNEL_OFFSET,
-				       chip->gpio_state[index]);
+			xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index,
+					 chip->gpio_state[index]);
 			spin_unlock_irqrestore(&chip->gpio_lock, flags);
 			index =  xgpio_index(chip, i);
 			spin_lock_irqsave(&chip->gpio_lock, flags);
@@ -188,8 +202,7 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
 		}
 	}
 
-	xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
-		       index * XGPIO_CHANNEL_OFFSET, chip->gpio_state[index]);
+	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index, chip->gpio_state[index]);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 }
@@ -214,8 +227,7 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 
 	/* Set the GPIO bit in shadow register and set direction as input */
 	chip->gpio_dir[index] |= BIT(offset);
-	xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET +
-		       xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
+	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, index, chip->gpio_dir[index]);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
@@ -248,13 +260,11 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 		chip->gpio_state[index] |= BIT(offset);
 	else
 		chip->gpio_state[index] &= ~BIT(offset);
-	xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
-			xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
+	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index, chip->gpio_state[index]);
 
 	/* Clear the GPIO bit in shadow register and set direction as output */
 	chip->gpio_dir[index] &= ~BIT(offset);
-	xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET +
-			xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
+	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, index, chip->gpio_dir[index]);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
@@ -267,16 +277,14 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
  */
 static void xgpio_save_regs(struct xgpio_instance *chip)
 {
-	xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET,	chip->gpio_state[0]);
-	xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET, chip->gpio_dir[0]);
+	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, 0, chip->gpio_state[0]);
+	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, 0, chip->gpio_dir[0]);
 
 	if (!chip->gpio_width[1])
 		return;
 
-	xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET + XGPIO_CHANNEL_OFFSET,
-		       chip->gpio_state[1]);
-	xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET + XGPIO_CHANNEL_OFFSET,
-		       chip->gpio_dir[1]);
+	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, 1, chip->gpio_state[1]);
+	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, 1, chip->gpio_dir[1]);
 }
 
 static int xgpio_request(struct gpio_chip *chip, unsigned int offset)
@@ -434,8 +442,7 @@ static void xgpio_irq_unmask(struct irq_data *irq_data)
 			xgpio_writereg(chip->regs + XGPIO_IPISR_OFFSET, val);
 
 		/* Update GPIO IRQ read data before enabling interrupt*/
-		val = xgpio_readreg(chip->regs + XGPIO_DATA_OFFSET +
-				    index * XGPIO_CHANNEL_OFFSET);
+		val = xgpio_read_chan(chip, XGPIO_DATA_OFFSET, index);
 		chip->gpio_last_irq_read[index] = val;
 
 		/* Enable per channel interrupt */
@@ -512,8 +519,7 @@ static void xgpio_irqhandler(struct irq_desc *desc)
 			unsigned int irq;
 
 			spin_lock_irqsave(&chip->gpio_lock, flags);
-			data = xgpio_readreg(chip->regs + XGPIO_DATA_OFFSET +
-					     index * XGPIO_CHANNEL_OFFSET);
+			data = xgpio_read_chan(chip, XGPIO_DATA_OFFSET, index);
 			rising_events = data &
 					~chip->gpio_last_irq_read[index] &
 					chip->irq_enable[index] &
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v1 4/5] gpio: xilinx: Switch to use bitmap APIs
  2021-04-08 14:55 ` Andy Shevchenko
@ 2021-04-08 14:56   ` Andy Shevchenko
  -1 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 14:56 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray

It seems that Xilinx GPIO driver operates with bit arrays longer than 32 and
thus can leverage bitmap APIs for that. It makes code better to understand.

The ->probe() function is modified to try read properties for both channels
since is_dual check makes only sense for the amount of pins used for the second
channel. On top of that kzalloc() guarantees zero initial values for the fields
in the private data structure, hence drop unneeded conditionals and assignments.

The change is inspired by Syed Nayyar Waris' ideas about bitmap API extension.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/gpio/gpio-xilinx.c | 350 ++++++++++++++++++-------------------
 1 file changed, 171 insertions(+), 179 deletions(-)

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index e6c78409ab3a..98d90b4c4d2b 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -5,6 +5,7 @@
  * Copyright 2008 - 2013 Xilinx, Inc.
  */
 
+#include <linux/bitmap.h>
 #include <linux/bitops.h>
 #include <linux/clk.h>
 #include <linux/errno.h>
@@ -44,40 +45,56 @@
  * struct xgpio_instance - Stores information about GPIO device
  * @gc: GPIO chip
  * @regs: register block
- * @gpio_width: GPIO width for every channel
- * @gpio_state: GPIO write state shadow register
- * @gpio_last_irq_read: GPIO read state register from last interrupt
- * @gpio_dir: GPIO direction shadow register
+ * @hw_map: GPIO pin mapping on hardware side
+ * @sw_map: GPIO pin mapping on software side
+ * @state: GPIO write state shadow register
+ * @last_irq_read: GPIO read state register from last interrupt
+ * @dir: GPIO direction shadow register
  * @gpio_lock: Lock used for synchronization
  * @irq: IRQ used by GPIO device
  * @irqchip: IRQ chip
- * @irq_enable: GPIO IRQ enable/disable bitfield
- * @irq_rising_edge: GPIO IRQ rising edge enable/disable bitfield
- * @irq_falling_edge: GPIO IRQ falling edge enable/disable bitfield
+ * @enable: GPIO IRQ enable/disable bitfield
+ * @rising_edge: GPIO IRQ rising edge enable/disable bitfield
+ * @falling_edge: GPIO IRQ falling edge enable/disable bitfield
  * @clk: clock resource for this driver
  */
 struct xgpio_instance {
 	struct gpio_chip gc;
 	void __iomem *regs;
-	unsigned int gpio_width[2];
-	u32 gpio_state[2];
-	u32 gpio_last_irq_read[2];
-	u32 gpio_dir[2];
+	DECLARE_BITMAP(hw_map, 64);
+	DECLARE_BITMAP(sw_map, 64);
+	DECLARE_BITMAP(state, 64);
+	DECLARE_BITMAP(last_irq_read, 64);
+	DECLARE_BITMAP(dir, 64);
 	spinlock_t gpio_lock;	/* For serializing operations */
 	int irq;
 	struct irq_chip irqchip;
-	u32 irq_enable[2];
-	u32 irq_rising_edge[2];
-	u32 irq_falling_edge[2];
+	DECLARE_BITMAP(enable, 64);
+	DECLARE_BITMAP(rising_edge, 64);
+	DECLARE_BITMAP(falling_edge, 64);
 	struct clk *clk;
 };
 
-static inline int xgpio_index(struct xgpio_instance *chip, int gpio)
+static inline int xgpio_to_bit(struct xgpio_instance *chip, int gpio)
 {
-	if (gpio >= chip->gpio_width[0])
-		return 1;
+	return bitmap_bitremap(gpio, chip->sw_map, chip->hw_map, chip->gc.ngpio);
+}
 
-	return 0;
+static inline u32 xgpio_get_value32(const unsigned long *map, int bit)
+{
+	const size_t index = BIT_WORD(bit);
+	const unsigned long offset = (bit % BITS_PER_LONG) & BIT(5);
+
+	return (map[index] >> offset) & 0xFFFFFFFFul;
+}
+
+static inline void xgpio_set_value32(unsigned long *map, int bit, u32 v)
+{
+	const size_t index = BIT_WORD(bit);
+	const unsigned long offset = (bit % BITS_PER_LONG) & BIT(5);
+
+	map[index] &= ~(0xFFFFFFFFul << offset);
+	map[index] |= v << offset;
 }
 
 static inline int xgpio_regoffset(struct xgpio_instance *chip, int ch)
@@ -92,22 +109,32 @@ static inline int xgpio_regoffset(struct xgpio_instance *chip, int ch)
 	}
 }
 
-static inline u32 xgpio_read_chan(struct xgpio_instance *chip, int reg, int ch)
+static void xgpio_read_ch(struct xgpio_instance *chip, int reg, int bit, unsigned long *a)
 {
-	return xgpio_readreg(chip->regs + reg + xgpio_regoffset(chip, ch));
+	void __iomem *addr = chip->regs + reg + xgpio_regoffset(chip, bit / 32);
+	xgpio_set_value32(a, bit, xgpio_readreg(addr));
 }
 
-static inline void xgpio_write_chan(struct xgpio_instance *chip, int reg, int ch, u32 v)
+static void xgpio_write_ch(struct xgpio_instance *chip, int reg, int bit, unsigned long *a)
 {
-	xgpio_writereg(chip->regs + reg + xgpio_regoffset(chip, ch), v);
+	void __iomem *addr = chip->regs + reg + xgpio_regoffset(chip, bit / 32);
+	xgpio_writereg(addr, xgpio_get_value32(a, bit));
 }
 
-static inline int xgpio_offset(struct xgpio_instance *chip, int gpio)
+static void xgpio_read_ch_all(struct xgpio_instance *chip, int reg, unsigned long *a)
 {
-	if (xgpio_index(chip, gpio))
-		return gpio - chip->gpio_width[0];
+	int bit, lastbit = xgpio_to_bit(chip, chip->gc.ngpio - 1);
 
-	return gpio;
+	for (bit = 0; bit <= lastbit ; bit += 32)
+		xgpio_read_ch(chip, reg, bit, a);
+}
+
+static void xgpio_write_ch_all(struct xgpio_instance *chip, int reg, unsigned long *a)
+{
+	int bit, lastbit = xgpio_to_bit(chip, chip->gc.ngpio - 1);
+
+	for (bit = 0; bit <= lastbit ; bit += 32)
+		xgpio_write_ch(chip, reg, bit, a);
 }
 
 /**
@@ -124,13 +151,12 @@ static inline int xgpio_offset(struct xgpio_instance *chip, int gpio)
 static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
 {
 	struct xgpio_instance *chip = gpiochip_get_data(gc);
-	int index = xgpio_index(chip, gpio);
-	int offset = xgpio_offset(chip, gpio);
-	u32 val;
+	int bit = xgpio_to_bit(chip, gpio);
+	DECLARE_BITMAP(state, 64);
 
-	val = xgpio_read_chan(chip, XGPIO_DATA_OFFSET, index);
+	xgpio_read_ch(chip, XGPIO_DATA_OFFSET, bit, state);
 
-	return !!(val & BIT(offset));
+	return test_bit(bit, state);
 }
 
 /**
@@ -146,18 +172,14 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 {
 	unsigned long flags;
 	struct xgpio_instance *chip = gpiochip_get_data(gc);
-	int index =  xgpio_index(chip, gpio);
-	int offset =  xgpio_offset(chip, gpio);
+	int bit = xgpio_to_bit(chip, gpio);
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	/* Write to GPIO signal and set its direction to output */
-	if (val)
-		chip->gpio_state[index] |= BIT(offset);
-	else
-		chip->gpio_state[index] &= ~BIT(offset);
+	__assign_bit(bit, chip->state, val);
 
-	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index, chip->gpio_state[index]);
+	xgpio_write_ch(chip, XGPIO_DATA_OFFSET, bit, chip->state);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 }
@@ -174,35 +196,22 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
 			       unsigned long *bits)
 {
+	DECLARE_BITMAP(hw_mask, 64);
+	DECLARE_BITMAP(hw_bits, 64);
+	DECLARE_BITMAP(state, 64);
 	unsigned long flags;
 	struct xgpio_instance *chip = gpiochip_get_data(gc);
-	int index = xgpio_index(chip, 0);
-	int offset, i;
+
+	bitmap_remap(hw_mask, mask, chip->sw_map, chip->hw_map, 64);
+	bitmap_remap(hw_bits, bits, chip->sw_map, chip->hw_map, 64);
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
-	/* Write to GPIO signals */
-	for (i = 0; i < gc->ngpio; i++) {
-		if (*mask == 0)
-			break;
-		/* Once finished with an index write it out to the register */
-		if (index !=  xgpio_index(chip, i)) {
-			xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index,
-					 chip->gpio_state[index]);
-			spin_unlock_irqrestore(&chip->gpio_lock, flags);
-			index =  xgpio_index(chip, i);
-			spin_lock_irqsave(&chip->gpio_lock, flags);
-		}
-		if (__test_and_clear_bit(i, mask)) {
-			offset =  xgpio_offset(chip, i);
-			if (test_bit(i, bits))
-				chip->gpio_state[index] |= BIT(offset);
-			else
-				chip->gpio_state[index] &= ~BIT(offset);
-		}
-	}
+	bitmap_replace(state, chip->state, hw_bits, hw_mask, gc->ngpio);
 
-	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index, chip->gpio_state[index]);
+	xgpio_write_ch_all(chip, XGPIO_DATA_OFFSET, state);
+
+	bitmap_copy(chip->state, state, gc->ngpio);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 }
@@ -220,14 +229,13 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 {
 	unsigned long flags;
 	struct xgpio_instance *chip = gpiochip_get_data(gc);
-	int index =  xgpio_index(chip, gpio);
-	int offset =  xgpio_offset(chip, gpio);
+	int bit = xgpio_to_bit(chip, gpio);
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	/* Set the GPIO bit in shadow register and set direction as input */
-	chip->gpio_dir[index] |= BIT(offset);
-	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, index, chip->gpio_dir[index]);
+	__set_bit(bit, chip->dir);
+	xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
@@ -250,21 +258,17 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 {
 	unsigned long flags;
 	struct xgpio_instance *chip = gpiochip_get_data(gc);
-	int index =  xgpio_index(chip, gpio);
-	int offset =  xgpio_offset(chip, gpio);
+	int bit = xgpio_to_bit(chip, gpio);
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	/* Write state of GPIO signal */
-	if (val)
-		chip->gpio_state[index] |= BIT(offset);
-	else
-		chip->gpio_state[index] &= ~BIT(offset);
-	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index, chip->gpio_state[index]);
+	__assign_bit(bit, chip->state, val);
+	xgpio_write_ch(chip, XGPIO_DATA_OFFSET, bit, chip->state);
 
 	/* Clear the GPIO bit in shadow register and set direction as output */
-	chip->gpio_dir[index] &= ~BIT(offset);
-	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, index, chip->gpio_dir[index]);
+	__clear_bit(bit, chip->dir);
+	xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
@@ -277,14 +281,8 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
  */
 static void xgpio_save_regs(struct xgpio_instance *chip)
 {
-	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, 0, chip->gpio_state[0]);
-	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, 0, chip->gpio_dir[0]);
-
-	if (!chip->gpio_width[1])
-		return;
-
-	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, 1, chip->gpio_state[1]);
-	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, 1, chip->gpio_dir[1]);
+	xgpio_write_ch_all(chip, XGPIO_DATA_OFFSET, chip->state);
+	xgpio_write_ch_all(chip, XGPIO_TRI_OFFSET, chip->dir);
 }
 
 static int xgpio_request(struct gpio_chip *chip, unsigned int offset)
@@ -399,18 +397,17 @@ static void xgpio_irq_mask(struct irq_data *irq_data)
 	unsigned long flags;
 	struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
 	int irq_offset = irqd_to_hwirq(irq_data);
-	int index = xgpio_index(chip, irq_offset);
-	int offset = xgpio_offset(chip, irq_offset);
+	int bit = xgpio_to_bit(chip, irq_offset);
+	u32 mask = BIT(bit / 32), temp;
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
-	chip->irq_enable[index] &= ~BIT(offset);
+	__clear_bit(bit, chip->enable);
 
-	if (!chip->irq_enable[index]) {
+	if (xgpio_get_value32(chip->enable, bit) == 0) {
 		/* Disable per channel interrupt */
-		u32 temp = xgpio_readreg(chip->regs + XGPIO_IPIER_OFFSET);
-
-		temp &= ~BIT(index);
+		temp = xgpio_readreg(chip->regs + XGPIO_IPIER_OFFSET);
+		temp &= ~mask;
 		xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, temp);
 	}
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
@@ -425,29 +422,26 @@ static void xgpio_irq_unmask(struct irq_data *irq_data)
 	unsigned long flags;
 	struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
 	int irq_offset = irqd_to_hwirq(irq_data);
-	int index = xgpio_index(chip, irq_offset);
-	int offset = xgpio_offset(chip, irq_offset);
-	u32 old_enable = chip->irq_enable[index];
+	int bit = xgpio_to_bit(chip, irq_offset);
+	u32 old_enable = xgpio_get_value32(chip->enable, bit);
+	u32 mask = BIT(bit / 32), val;
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
-	chip->irq_enable[index] |= BIT(offset);
+	__set_bit(bit, chip->enable);
 
-	if (!old_enable) {
+	if (old_enable == 0) {
 		/* Clear any existing per-channel interrupts */
-		u32 val = xgpio_readreg(chip->regs + XGPIO_IPISR_OFFSET) &
-			BIT(index);
-
-		if (val)
-			xgpio_writereg(chip->regs + XGPIO_IPISR_OFFSET, val);
+		val = xgpio_readreg(chip->regs + XGPIO_IPISR_OFFSET);
+		val &= mask;
+		xgpio_writereg(chip->regs + XGPIO_IPISR_OFFSET, val);
 
 		/* Update GPIO IRQ read data before enabling interrupt*/
-		val = xgpio_read_chan(chip, XGPIO_DATA_OFFSET, index);
-		chip->gpio_last_irq_read[index] = val;
+		xgpio_read_ch(chip, XGPIO_DATA_OFFSET, bit, chip->last_irq_read);
 
 		/* Enable per channel interrupt */
 		val = xgpio_readreg(chip->regs + XGPIO_IPIER_OFFSET);
-		val |= BIT(index);
+		val |= mask;
 		xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, val);
 	}
 
@@ -466,8 +460,7 @@ static int xgpio_set_irq_type(struct irq_data *irq_data, unsigned int type)
 {
 	struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
 	int irq_offset = irqd_to_hwirq(irq_data);
-	int index = xgpio_index(chip, irq_offset);
-	int offset = xgpio_offset(chip, irq_offset);
+	int bit = xgpio_to_bit(chip, irq_offset);
 
 	/*
 	 * The Xilinx GPIO hardware provides a single interrupt status
@@ -477,16 +470,16 @@ static int xgpio_set_irq_type(struct irq_data *irq_data, unsigned int type)
 	 */
 	switch (type & IRQ_TYPE_SENSE_MASK) {
 	case IRQ_TYPE_EDGE_BOTH:
-		chip->irq_rising_edge[index] |= BIT(offset);
-		chip->irq_falling_edge[index] |= BIT(offset);
+		__set_bit(bit, chip->rising_edge);
+		__set_bit(bit, chip->falling_edge);
 		break;
 	case IRQ_TYPE_EDGE_RISING:
-		chip->irq_rising_edge[index] |= BIT(offset);
-		chip->irq_falling_edge[index] &= ~BIT(offset);
+		__set_bit(bit, chip->rising_edge);
+		__clear_bit(bit, chip->falling_edge);
 		break;
 	case IRQ_TYPE_EDGE_FALLING:
-		chip->irq_rising_edge[index] &= ~BIT(offset);
-		chip->irq_falling_edge[index] |= BIT(offset);
+		__clear_bit(bit, chip->rising_edge);
+		__set_bit(bit, chip->falling_edge);
 		break;
 	default:
 		return -EINVAL;
@@ -503,46 +496,43 @@ static int xgpio_set_irq_type(struct irq_data *irq_data, unsigned int type)
 static void xgpio_irqhandler(struct irq_desc *desc)
 {
 	struct xgpio_instance *chip = irq_desc_get_handler_data(desc);
+	struct gpio_chip *gc = &chip->gc;
 	struct irq_chip *irqchip = irq_desc_get_chip(desc);
-	u32 num_channels = chip->gpio_width[1] ? 2 : 1;
-	u32 offset = 0, index;
-	u32 status = xgpio_readreg(chip->regs + XGPIO_IPISR_OFFSET);
+	DECLARE_BITMAP(rising, 64);
+	DECLARE_BITMAP(falling, 64);
+	DECLARE_BITMAP(all, 64);
+	u32 status;
+	u32 bit;
+	unsigned long flags;
 
+	status = xgpio_readreg(chip->regs + XGPIO_IPISR_OFFSET);
 	xgpio_writereg(chip->regs + XGPIO_IPISR_OFFSET, status);
 
 	chained_irq_enter(irqchip, desc);
-	for (index = 0; index < num_channels; index++) {
-		if ((status & BIT(index))) {
-			unsigned long rising_events, falling_events, all_events;
-			unsigned long flags;
-			u32 data, bit;
-			unsigned int irq;
-
-			spin_lock_irqsave(&chip->gpio_lock, flags);
-			data = xgpio_read_chan(chip, XGPIO_DATA_OFFSET, index);
-			rising_events = data &
-					~chip->gpio_last_irq_read[index] &
-					chip->irq_enable[index] &
-					chip->irq_rising_edge[index];
-			falling_events = ~data &
-					 chip->gpio_last_irq_read[index] &
-					 chip->irq_enable[index] &
-					 chip->irq_falling_edge[index];
-			dev_dbg(chip->gc.parent,
-				"IRQ chan %u rising 0x%lx falling 0x%lx\n",
-				index, rising_events, falling_events);
-			all_events = rising_events | falling_events;
-			chip->gpio_last_irq_read[index] = data;
-			spin_unlock_irqrestore(&chip->gpio_lock, flags);
-
-			for_each_set_bit(bit, &all_events, 32) {
-				irq = irq_find_mapping(chip->gc.irq.domain,
-						       offset + bit);
-				generic_handle_irq(irq);
-			}
-		}
-		offset += chip->gpio_width[index];
-	}
+
+	spin_lock_irqsave(&chip->gpio_lock, flags);
+
+	xgpio_read_ch_all(chip, XGPIO_DATA_OFFSET, all);
+
+	bitmap_complement(rising, chip->last_irq_read, 64);
+	bitmap_and(rising, rising, all, 64);
+	bitmap_and(rising, rising, chip->enable, 64);
+	bitmap_and(rising, rising, chip->rising_edge, 64);
+
+	bitmap_complement(falling, all, 64);
+	bitmap_and(falling, falling, chip->last_irq_read, 64);
+	bitmap_and(falling, falling, chip->enable, 64);
+	bitmap_and(falling, falling, chip->falling_edge, 64);
+
+	bitmap_copy(chip->last_irq_read, all, 64);
+	bitmap_or(all, rising, falling, 64);
+
+	spin_unlock_irqrestore(&chip->gpio_lock, flags);
+
+	dev_dbg(gc->parent, "IRQ rising %*pb falling %*pb\n", 64, rising, 64, falling);
+
+	for_each_set_bit(bit, all, 64)
+		generic_handle_irq(irq_find_mapping(gc->irq.domain, bit));
 
 	chained_irq_exit(irqchip, desc);
 }
@@ -562,6 +552,9 @@ static int xgpio_probe(struct platform_device *pdev)
 	struct device_node *np = pdev->dev.of_node;
 	u32 is_dual = 0;
 	u32 cells = 2;
+	u32 width[2];
+	u32 state[2];
+	u32 dir[2];
 	struct gpio_irq_chip *girq;
 	u32 temp;
 
@@ -571,13 +564,25 @@ static int xgpio_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, chip);
 
+	/* First, check if the device is dual-channel */
+	of_property_read_u32(np, "xlnx,is-dual", &is_dual);
+
+	/* Setup defaults */
+	memset32(width, 0, ARRAY_SIZE(width));
+	memset32(state, 0, ARRAY_SIZE(state));
+	memset32(dir, 0xFFFFFFFF, ARRAY_SIZE(dir));
+
 	/* Update GPIO state shadow register with default value */
-	if (of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state[0]))
-		chip->gpio_state[0] = 0x0;
+	of_property_read_u32(np, "xlnx,dout-default", &state[0]);
+	of_property_read_u32(np, "xlnx,dout-default-2", &state[1]);
+
+	bitmap_from_arr32(chip->state, state, 64);
 
 	/* Update GPIO direction shadow register with default value */
-	if (of_property_read_u32(np, "xlnx,tri-default", &chip->gpio_dir[0]))
-		chip->gpio_dir[0] = 0xFFFFFFFF;
+	of_property_read_u32(np, "xlnx,tri-default", &dir[0]);
+	of_property_read_u32(np, "xlnx,tri-default-2", &dir[1]);
+
+	bitmap_from_arr32(chip->dir, dir, 64);
 
 	/* Update cells with gpio-cells value */
 	if (of_property_read_u32(np, "#gpio-cells", &cells))
@@ -592,42 +597,29 @@ static int xgpio_probe(struct platform_device *pdev)
 	 * Check device node and parent device node for device width
 	 * and assume default width of 32
 	 */
-	if (of_property_read_u32(np, "xlnx,gpio-width", &chip->gpio_width[0]))
-		chip->gpio_width[0] = 32;
+	if (of_property_read_u32(np, "xlnx,gpio-width", &width[0]))
+		width[0] = 32;
 
-	if (chip->gpio_width[0] > 32)
+	if (width[0] > 32)
 		return -EINVAL;
 
-	spin_lock_init(&chip->gpio_lock);
+	if (is_dual && of_property_read_u32(np, "xlnx,gpio2-width", &width[1]))
+		width[1] = 32;
 
-	if (of_property_read_u32(np, "xlnx,is-dual", &is_dual))
-		is_dual = 0;
-
-	if (is_dual) {
-		/* Update GPIO state shadow register with default value */
-		if (of_property_read_u32(np, "xlnx,dout-default-2",
-					 &chip->gpio_state[1]))
-			chip->gpio_state[1] = 0x0;
-
-		/* Update GPIO direction shadow register with default value */
-		if (of_property_read_u32(np, "xlnx,tri-default-2",
-					 &chip->gpio_dir[1]))
-			chip->gpio_dir[1] = 0xFFFFFFFF;
-
-		/*
-		 * Check device node and parent device node for device width
-		 * and assume default width of 32
-		 */
-		if (of_property_read_u32(np, "xlnx,gpio2-width",
-					 &chip->gpio_width[1]))
-			chip->gpio_width[1] = 32;
-
-		if (chip->gpio_width[1] > 32)
-			return -EINVAL;
-	}
+	if (width[1] > 32)
+		return -EINVAL;
+
+	/* Setup software pin mapping */
+	bitmap_set(chip->sw_map, 0, width[0] + width[1]);
+
+	/* Setup hardware pin mapping */
+	bitmap_set(chip->hw_map,  0, width[0]);
+	bitmap_set(chip->hw_map, 32, width[1]);
+
+	spin_lock_init(&chip->gpio_lock);
 
 	chip->gc.base = -1;
-	chip->gc.ngpio = chip->gpio_width[0] + chip->gpio_width[1];
+	chip->gc.ngpio = bitmap_weight(chip->hw_map, 64);
 	chip->gc.parent = &pdev->dev;
 	chip->gc.direction_input = xgpio_dir_in;
 	chip->gc.direction_output = xgpio_dir_out;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v1 4/5] gpio: xilinx: Switch to use bitmap APIs
@ 2021-04-08 14:56   ` Andy Shevchenko
  0 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 14:56 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray

It seems that Xilinx GPIO driver operates with bit arrays longer than 32 and
thus can leverage bitmap APIs for that. It makes code better to understand.

The ->probe() function is modified to try read properties for both channels
since is_dual check makes only sense for the amount of pins used for the second
channel. On top of that kzalloc() guarantees zero initial values for the fields
in the private data structure, hence drop unneeded conditionals and assignments.

The change is inspired by Syed Nayyar Waris' ideas about bitmap API extension.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/gpio/gpio-xilinx.c | 350 ++++++++++++++++++-------------------
 1 file changed, 171 insertions(+), 179 deletions(-)

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index e6c78409ab3a..98d90b4c4d2b 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -5,6 +5,7 @@
  * Copyright 2008 - 2013 Xilinx, Inc.
  */
 
+#include <linux/bitmap.h>
 #include <linux/bitops.h>
 #include <linux/clk.h>
 #include <linux/errno.h>
@@ -44,40 +45,56 @@
  * struct xgpio_instance - Stores information about GPIO device
  * @gc: GPIO chip
  * @regs: register block
- * @gpio_width: GPIO width for every channel
- * @gpio_state: GPIO write state shadow register
- * @gpio_last_irq_read: GPIO read state register from last interrupt
- * @gpio_dir: GPIO direction shadow register
+ * @hw_map: GPIO pin mapping on hardware side
+ * @sw_map: GPIO pin mapping on software side
+ * @state: GPIO write state shadow register
+ * @last_irq_read: GPIO read state register from last interrupt
+ * @dir: GPIO direction shadow register
  * @gpio_lock: Lock used for synchronization
  * @irq: IRQ used by GPIO device
  * @irqchip: IRQ chip
- * @irq_enable: GPIO IRQ enable/disable bitfield
- * @irq_rising_edge: GPIO IRQ rising edge enable/disable bitfield
- * @irq_falling_edge: GPIO IRQ falling edge enable/disable bitfield
+ * @enable: GPIO IRQ enable/disable bitfield
+ * @rising_edge: GPIO IRQ rising edge enable/disable bitfield
+ * @falling_edge: GPIO IRQ falling edge enable/disable bitfield
  * @clk: clock resource for this driver
  */
 struct xgpio_instance {
 	struct gpio_chip gc;
 	void __iomem *regs;
-	unsigned int gpio_width[2];
-	u32 gpio_state[2];
-	u32 gpio_last_irq_read[2];
-	u32 gpio_dir[2];
+	DECLARE_BITMAP(hw_map, 64);
+	DECLARE_BITMAP(sw_map, 64);
+	DECLARE_BITMAP(state, 64);
+	DECLARE_BITMAP(last_irq_read, 64);
+	DECLARE_BITMAP(dir, 64);
 	spinlock_t gpio_lock;	/* For serializing operations */
 	int irq;
 	struct irq_chip irqchip;
-	u32 irq_enable[2];
-	u32 irq_rising_edge[2];
-	u32 irq_falling_edge[2];
+	DECLARE_BITMAP(enable, 64);
+	DECLARE_BITMAP(rising_edge, 64);
+	DECLARE_BITMAP(falling_edge, 64);
 	struct clk *clk;
 };
 
-static inline int xgpio_index(struct xgpio_instance *chip, int gpio)
+static inline int xgpio_to_bit(struct xgpio_instance *chip, int gpio)
 {
-	if (gpio >= chip->gpio_width[0])
-		return 1;
+	return bitmap_bitremap(gpio, chip->sw_map, chip->hw_map, chip->gc.ngpio);
+}
 
-	return 0;
+static inline u32 xgpio_get_value32(const unsigned long *map, int bit)
+{
+	const size_t index = BIT_WORD(bit);
+	const unsigned long offset = (bit % BITS_PER_LONG) & BIT(5);
+
+	return (map[index] >> offset) & 0xFFFFFFFFul;
+}
+
+static inline void xgpio_set_value32(unsigned long *map, int bit, u32 v)
+{
+	const size_t index = BIT_WORD(bit);
+	const unsigned long offset = (bit % BITS_PER_LONG) & BIT(5);
+
+	map[index] &= ~(0xFFFFFFFFul << offset);
+	map[index] |= v << offset;
 }
 
 static inline int xgpio_regoffset(struct xgpio_instance *chip, int ch)
@@ -92,22 +109,32 @@ static inline int xgpio_regoffset(struct xgpio_instance *chip, int ch)
 	}
 }
 
-static inline u32 xgpio_read_chan(struct xgpio_instance *chip, int reg, int ch)
+static void xgpio_read_ch(struct xgpio_instance *chip, int reg, int bit, unsigned long *a)
 {
-	return xgpio_readreg(chip->regs + reg + xgpio_regoffset(chip, ch));
+	void __iomem *addr = chip->regs + reg + xgpio_regoffset(chip, bit / 32);
+	xgpio_set_value32(a, bit, xgpio_readreg(addr));
 }
 
-static inline void xgpio_write_chan(struct xgpio_instance *chip, int reg, int ch, u32 v)
+static void xgpio_write_ch(struct xgpio_instance *chip, int reg, int bit, unsigned long *a)
 {
-	xgpio_writereg(chip->regs + reg + xgpio_regoffset(chip, ch), v);
+	void __iomem *addr = chip->regs + reg + xgpio_regoffset(chip, bit / 32);
+	xgpio_writereg(addr, xgpio_get_value32(a, bit));
 }
 
-static inline int xgpio_offset(struct xgpio_instance *chip, int gpio)
+static void xgpio_read_ch_all(struct xgpio_instance *chip, int reg, unsigned long *a)
 {
-	if (xgpio_index(chip, gpio))
-		return gpio - chip->gpio_width[0];
+	int bit, lastbit = xgpio_to_bit(chip, chip->gc.ngpio - 1);
 
-	return gpio;
+	for (bit = 0; bit <= lastbit ; bit += 32)
+		xgpio_read_ch(chip, reg, bit, a);
+}
+
+static void xgpio_write_ch_all(struct xgpio_instance *chip, int reg, unsigned long *a)
+{
+	int bit, lastbit = xgpio_to_bit(chip, chip->gc.ngpio - 1);
+
+	for (bit = 0; bit <= lastbit ; bit += 32)
+		xgpio_write_ch(chip, reg, bit, a);
 }
 
 /**
@@ -124,13 +151,12 @@ static inline int xgpio_offset(struct xgpio_instance *chip, int gpio)
 static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
 {
 	struct xgpio_instance *chip = gpiochip_get_data(gc);
-	int index = xgpio_index(chip, gpio);
-	int offset = xgpio_offset(chip, gpio);
-	u32 val;
+	int bit = xgpio_to_bit(chip, gpio);
+	DECLARE_BITMAP(state, 64);
 
-	val = xgpio_read_chan(chip, XGPIO_DATA_OFFSET, index);
+	xgpio_read_ch(chip, XGPIO_DATA_OFFSET, bit, state);
 
-	return !!(val & BIT(offset));
+	return test_bit(bit, state);
 }
 
 /**
@@ -146,18 +172,14 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 {
 	unsigned long flags;
 	struct xgpio_instance *chip = gpiochip_get_data(gc);
-	int index =  xgpio_index(chip, gpio);
-	int offset =  xgpio_offset(chip, gpio);
+	int bit = xgpio_to_bit(chip, gpio);
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	/* Write to GPIO signal and set its direction to output */
-	if (val)
-		chip->gpio_state[index] |= BIT(offset);
-	else
-		chip->gpio_state[index] &= ~BIT(offset);
+	__assign_bit(bit, chip->state, val);
 
-	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index, chip->gpio_state[index]);
+	xgpio_write_ch(chip, XGPIO_DATA_OFFSET, bit, chip->state);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 }
@@ -174,35 +196,22 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
 			       unsigned long *bits)
 {
+	DECLARE_BITMAP(hw_mask, 64);
+	DECLARE_BITMAP(hw_bits, 64);
+	DECLARE_BITMAP(state, 64);
 	unsigned long flags;
 	struct xgpio_instance *chip = gpiochip_get_data(gc);
-	int index = xgpio_index(chip, 0);
-	int offset, i;
+
+	bitmap_remap(hw_mask, mask, chip->sw_map, chip->hw_map, 64);
+	bitmap_remap(hw_bits, bits, chip->sw_map, chip->hw_map, 64);
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
-	/* Write to GPIO signals */
-	for (i = 0; i < gc->ngpio; i++) {
-		if (*mask == 0)
-			break;
-		/* Once finished with an index write it out to the register */
-		if (index !=  xgpio_index(chip, i)) {
-			xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index,
-					 chip->gpio_state[index]);
-			spin_unlock_irqrestore(&chip->gpio_lock, flags);
-			index =  xgpio_index(chip, i);
-			spin_lock_irqsave(&chip->gpio_lock, flags);
-		}
-		if (__test_and_clear_bit(i, mask)) {
-			offset =  xgpio_offset(chip, i);
-			if (test_bit(i, bits))
-				chip->gpio_state[index] |= BIT(offset);
-			else
-				chip->gpio_state[index] &= ~BIT(offset);
-		}
-	}
+	bitmap_replace(state, chip->state, hw_bits, hw_mask, gc->ngpio);
 
-	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index, chip->gpio_state[index]);
+	xgpio_write_ch_all(chip, XGPIO_DATA_OFFSET, state);
+
+	bitmap_copy(chip->state, state, gc->ngpio);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 }
@@ -220,14 +229,13 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 {
 	unsigned long flags;
 	struct xgpio_instance *chip = gpiochip_get_data(gc);
-	int index =  xgpio_index(chip, gpio);
-	int offset =  xgpio_offset(chip, gpio);
+	int bit = xgpio_to_bit(chip, gpio);
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	/* Set the GPIO bit in shadow register and set direction as input */
-	chip->gpio_dir[index] |= BIT(offset);
-	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, index, chip->gpio_dir[index]);
+	__set_bit(bit, chip->dir);
+	xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
@@ -250,21 +258,17 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 {
 	unsigned long flags;
 	struct xgpio_instance *chip = gpiochip_get_data(gc);
-	int index =  xgpio_index(chip, gpio);
-	int offset =  xgpio_offset(chip, gpio);
+	int bit = xgpio_to_bit(chip, gpio);
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	/* Write state of GPIO signal */
-	if (val)
-		chip->gpio_state[index] |= BIT(offset);
-	else
-		chip->gpio_state[index] &= ~BIT(offset);
-	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, index, chip->gpio_state[index]);
+	__assign_bit(bit, chip->state, val);
+	xgpio_write_ch(chip, XGPIO_DATA_OFFSET, bit, chip->state);
 
 	/* Clear the GPIO bit in shadow register and set direction as output */
-	chip->gpio_dir[index] &= ~BIT(offset);
-	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, index, chip->gpio_dir[index]);
+	__clear_bit(bit, chip->dir);
+	xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
@@ -277,14 +281,8 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
  */
 static void xgpio_save_regs(struct xgpio_instance *chip)
 {
-	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, 0, chip->gpio_state[0]);
-	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, 0, chip->gpio_dir[0]);
-
-	if (!chip->gpio_width[1])
-		return;
-
-	xgpio_write_chan(chip, XGPIO_DATA_OFFSET, 1, chip->gpio_state[1]);
-	xgpio_write_chan(chip, XGPIO_TRI_OFFSET, 1, chip->gpio_dir[1]);
+	xgpio_write_ch_all(chip, XGPIO_DATA_OFFSET, chip->state);
+	xgpio_write_ch_all(chip, XGPIO_TRI_OFFSET, chip->dir);
 }
 
 static int xgpio_request(struct gpio_chip *chip, unsigned int offset)
@@ -399,18 +397,17 @@ static void xgpio_irq_mask(struct irq_data *irq_data)
 	unsigned long flags;
 	struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
 	int irq_offset = irqd_to_hwirq(irq_data);
-	int index = xgpio_index(chip, irq_offset);
-	int offset = xgpio_offset(chip, irq_offset);
+	int bit = xgpio_to_bit(chip, irq_offset);
+	u32 mask = BIT(bit / 32), temp;
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
-	chip->irq_enable[index] &= ~BIT(offset);
+	__clear_bit(bit, chip->enable);
 
-	if (!chip->irq_enable[index]) {
+	if (xgpio_get_value32(chip->enable, bit) == 0) {
 		/* Disable per channel interrupt */
-		u32 temp = xgpio_readreg(chip->regs + XGPIO_IPIER_OFFSET);
-
-		temp &= ~BIT(index);
+		temp = xgpio_readreg(chip->regs + XGPIO_IPIER_OFFSET);
+		temp &= ~mask;
 		xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, temp);
 	}
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
@@ -425,29 +422,26 @@ static void xgpio_irq_unmask(struct irq_data *irq_data)
 	unsigned long flags;
 	struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
 	int irq_offset = irqd_to_hwirq(irq_data);
-	int index = xgpio_index(chip, irq_offset);
-	int offset = xgpio_offset(chip, irq_offset);
-	u32 old_enable = chip->irq_enable[index];
+	int bit = xgpio_to_bit(chip, irq_offset);
+	u32 old_enable = xgpio_get_value32(chip->enable, bit);
+	u32 mask = BIT(bit / 32), val;
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
-	chip->irq_enable[index] |= BIT(offset);
+	__set_bit(bit, chip->enable);
 
-	if (!old_enable) {
+	if (old_enable == 0) {
 		/* Clear any existing per-channel interrupts */
-		u32 val = xgpio_readreg(chip->regs + XGPIO_IPISR_OFFSET) &
-			BIT(index);
-
-		if (val)
-			xgpio_writereg(chip->regs + XGPIO_IPISR_OFFSET, val);
+		val = xgpio_readreg(chip->regs + XGPIO_IPISR_OFFSET);
+		val &= mask;
+		xgpio_writereg(chip->regs + XGPIO_IPISR_OFFSET, val);
 
 		/* Update GPIO IRQ read data before enabling interrupt*/
-		val = xgpio_read_chan(chip, XGPIO_DATA_OFFSET, index);
-		chip->gpio_last_irq_read[index] = val;
+		xgpio_read_ch(chip, XGPIO_DATA_OFFSET, bit, chip->last_irq_read);
 
 		/* Enable per channel interrupt */
 		val = xgpio_readreg(chip->regs + XGPIO_IPIER_OFFSET);
-		val |= BIT(index);
+		val |= mask;
 		xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, val);
 	}
 
@@ -466,8 +460,7 @@ static int xgpio_set_irq_type(struct irq_data *irq_data, unsigned int type)
 {
 	struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
 	int irq_offset = irqd_to_hwirq(irq_data);
-	int index = xgpio_index(chip, irq_offset);
-	int offset = xgpio_offset(chip, irq_offset);
+	int bit = xgpio_to_bit(chip, irq_offset);
 
 	/*
 	 * The Xilinx GPIO hardware provides a single interrupt status
@@ -477,16 +470,16 @@ static int xgpio_set_irq_type(struct irq_data *irq_data, unsigned int type)
 	 */
 	switch (type & IRQ_TYPE_SENSE_MASK) {
 	case IRQ_TYPE_EDGE_BOTH:
-		chip->irq_rising_edge[index] |= BIT(offset);
-		chip->irq_falling_edge[index] |= BIT(offset);
+		__set_bit(bit, chip->rising_edge);
+		__set_bit(bit, chip->falling_edge);
 		break;
 	case IRQ_TYPE_EDGE_RISING:
-		chip->irq_rising_edge[index] |= BIT(offset);
-		chip->irq_falling_edge[index] &= ~BIT(offset);
+		__set_bit(bit, chip->rising_edge);
+		__clear_bit(bit, chip->falling_edge);
 		break;
 	case IRQ_TYPE_EDGE_FALLING:
-		chip->irq_rising_edge[index] &= ~BIT(offset);
-		chip->irq_falling_edge[index] |= BIT(offset);
+		__clear_bit(bit, chip->rising_edge);
+		__set_bit(bit, chip->falling_edge);
 		break;
 	default:
 		return -EINVAL;
@@ -503,46 +496,43 @@ static int xgpio_set_irq_type(struct irq_data *irq_data, unsigned int type)
 static void xgpio_irqhandler(struct irq_desc *desc)
 {
 	struct xgpio_instance *chip = irq_desc_get_handler_data(desc);
+	struct gpio_chip *gc = &chip->gc;
 	struct irq_chip *irqchip = irq_desc_get_chip(desc);
-	u32 num_channels = chip->gpio_width[1] ? 2 : 1;
-	u32 offset = 0, index;
-	u32 status = xgpio_readreg(chip->regs + XGPIO_IPISR_OFFSET);
+	DECLARE_BITMAP(rising, 64);
+	DECLARE_BITMAP(falling, 64);
+	DECLARE_BITMAP(all, 64);
+	u32 status;
+	u32 bit;
+	unsigned long flags;
 
+	status = xgpio_readreg(chip->regs + XGPIO_IPISR_OFFSET);
 	xgpio_writereg(chip->regs + XGPIO_IPISR_OFFSET, status);
 
 	chained_irq_enter(irqchip, desc);
-	for (index = 0; index < num_channels; index++) {
-		if ((status & BIT(index))) {
-			unsigned long rising_events, falling_events, all_events;
-			unsigned long flags;
-			u32 data, bit;
-			unsigned int irq;
-
-			spin_lock_irqsave(&chip->gpio_lock, flags);
-			data = xgpio_read_chan(chip, XGPIO_DATA_OFFSET, index);
-			rising_events = data &
-					~chip->gpio_last_irq_read[index] &
-					chip->irq_enable[index] &
-					chip->irq_rising_edge[index];
-			falling_events = ~data &
-					 chip->gpio_last_irq_read[index] &
-					 chip->irq_enable[index] &
-					 chip->irq_falling_edge[index];
-			dev_dbg(chip->gc.parent,
-				"IRQ chan %u rising 0x%lx falling 0x%lx\n",
-				index, rising_events, falling_events);
-			all_events = rising_events | falling_events;
-			chip->gpio_last_irq_read[index] = data;
-			spin_unlock_irqrestore(&chip->gpio_lock, flags);
-
-			for_each_set_bit(bit, &all_events, 32) {
-				irq = irq_find_mapping(chip->gc.irq.domain,
-						       offset + bit);
-				generic_handle_irq(irq);
-			}
-		}
-		offset += chip->gpio_width[index];
-	}
+
+	spin_lock_irqsave(&chip->gpio_lock, flags);
+
+	xgpio_read_ch_all(chip, XGPIO_DATA_OFFSET, all);
+
+	bitmap_complement(rising, chip->last_irq_read, 64);
+	bitmap_and(rising, rising, all, 64);
+	bitmap_and(rising, rising, chip->enable, 64);
+	bitmap_and(rising, rising, chip->rising_edge, 64);
+
+	bitmap_complement(falling, all, 64);
+	bitmap_and(falling, falling, chip->last_irq_read, 64);
+	bitmap_and(falling, falling, chip->enable, 64);
+	bitmap_and(falling, falling, chip->falling_edge, 64);
+
+	bitmap_copy(chip->last_irq_read, all, 64);
+	bitmap_or(all, rising, falling, 64);
+
+	spin_unlock_irqrestore(&chip->gpio_lock, flags);
+
+	dev_dbg(gc->parent, "IRQ rising %*pb falling %*pb\n", 64, rising, 64, falling);
+
+	for_each_set_bit(bit, all, 64)
+		generic_handle_irq(irq_find_mapping(gc->irq.domain, bit));
 
 	chained_irq_exit(irqchip, desc);
 }
@@ -562,6 +552,9 @@ static int xgpio_probe(struct platform_device *pdev)
 	struct device_node *np = pdev->dev.of_node;
 	u32 is_dual = 0;
 	u32 cells = 2;
+	u32 width[2];
+	u32 state[2];
+	u32 dir[2];
 	struct gpio_irq_chip *girq;
 	u32 temp;
 
@@ -571,13 +564,25 @@ static int xgpio_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, chip);
 
+	/* First, check if the device is dual-channel */
+	of_property_read_u32(np, "xlnx,is-dual", &is_dual);
+
+	/* Setup defaults */
+	memset32(width, 0, ARRAY_SIZE(width));
+	memset32(state, 0, ARRAY_SIZE(state));
+	memset32(dir, 0xFFFFFFFF, ARRAY_SIZE(dir));
+
 	/* Update GPIO state shadow register with default value */
-	if (of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state[0]))
-		chip->gpio_state[0] = 0x0;
+	of_property_read_u32(np, "xlnx,dout-default", &state[0]);
+	of_property_read_u32(np, "xlnx,dout-default-2", &state[1]);
+
+	bitmap_from_arr32(chip->state, state, 64);
 
 	/* Update GPIO direction shadow register with default value */
-	if (of_property_read_u32(np, "xlnx,tri-default", &chip->gpio_dir[0]))
-		chip->gpio_dir[0] = 0xFFFFFFFF;
+	of_property_read_u32(np, "xlnx,tri-default", &dir[0]);
+	of_property_read_u32(np, "xlnx,tri-default-2", &dir[1]);
+
+	bitmap_from_arr32(chip->dir, dir, 64);
 
 	/* Update cells with gpio-cells value */
 	if (of_property_read_u32(np, "#gpio-cells", &cells))
@@ -592,42 +597,29 @@ static int xgpio_probe(struct platform_device *pdev)
 	 * Check device node and parent device node for device width
 	 * and assume default width of 32
 	 */
-	if (of_property_read_u32(np, "xlnx,gpio-width", &chip->gpio_width[0]))
-		chip->gpio_width[0] = 32;
+	if (of_property_read_u32(np, "xlnx,gpio-width", &width[0]))
+		width[0] = 32;
 
-	if (chip->gpio_width[0] > 32)
+	if (width[0] > 32)
 		return -EINVAL;
 
-	spin_lock_init(&chip->gpio_lock);
+	if (is_dual && of_property_read_u32(np, "xlnx,gpio2-width", &width[1]))
+		width[1] = 32;
 
-	if (of_property_read_u32(np, "xlnx,is-dual", &is_dual))
-		is_dual = 0;
-
-	if (is_dual) {
-		/* Update GPIO state shadow register with default value */
-		if (of_property_read_u32(np, "xlnx,dout-default-2",
-					 &chip->gpio_state[1]))
-			chip->gpio_state[1] = 0x0;
-
-		/* Update GPIO direction shadow register with default value */
-		if (of_property_read_u32(np, "xlnx,tri-default-2",
-					 &chip->gpio_dir[1]))
-			chip->gpio_dir[1] = 0xFFFFFFFF;
-
-		/*
-		 * Check device node and parent device node for device width
-		 * and assume default width of 32
-		 */
-		if (of_property_read_u32(np, "xlnx,gpio2-width",
-					 &chip->gpio_width[1]))
-			chip->gpio_width[1] = 32;
-
-		if (chip->gpio_width[1] > 32)
-			return -EINVAL;
-	}
+	if (width[1] > 32)
+		return -EINVAL;
+
+	/* Setup software pin mapping */
+	bitmap_set(chip->sw_map, 0, width[0] + width[1]);
+
+	/* Setup hardware pin mapping */
+	bitmap_set(chip->hw_map,  0, width[0]);
+	bitmap_set(chip->hw_map, 32, width[1]);
+
+	spin_lock_init(&chip->gpio_lock);
 
 	chip->gc.base = -1;
-	chip->gc.ngpio = chip->gpio_width[0] + chip->gpio_width[1];
+	chip->gc.ngpio = bitmap_weight(chip->hw_map, 64);
 	chip->gc.parent = &pdev->dev;
 	chip->gc.direction_input = xgpio_dir_in;
 	chip->gc.direction_output = xgpio_dir_out;
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v1 5/5] gpio: xilinx: No need to disable IRQs in the handler
  2021-04-08 14:55 ` Andy Shevchenko
@ 2021-04-08 14:56   ` Andy Shevchenko
  -1 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 14:56 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray

In IRQ handler interrupts are already disabled, hence no need
to repeat it. Even in the threaded case, it is not a problem
because IRQ framework keeps interrupt disabled there as well.
Remove disabling IRQ part in the handler.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/gpio/gpio-xilinx.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index 98d90b4c4d2b..d5a08dcdd677 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -503,14 +503,13 @@ static void xgpio_irqhandler(struct irq_desc *desc)
 	DECLARE_BITMAP(all, 64);
 	u32 status;
 	u32 bit;
-	unsigned long flags;
 
 	status = xgpio_readreg(chip->regs + XGPIO_IPISR_OFFSET);
 	xgpio_writereg(chip->regs + XGPIO_IPISR_OFFSET, status);
 
 	chained_irq_enter(irqchip, desc);
 
-	spin_lock_irqsave(&chip->gpio_lock, flags);
+	spin_lock(&chip->gpio_lock);
 
 	xgpio_read_ch_all(chip, XGPIO_DATA_OFFSET, all);
 
@@ -527,7 +526,7 @@ static void xgpio_irqhandler(struct irq_desc *desc)
 	bitmap_copy(chip->last_irq_read, all, 64);
 	bitmap_or(all, rising, falling, 64);
 
-	spin_unlock_irqrestore(&chip->gpio_lock, flags);
+	spin_unlock(&chip->gpio_lock);
 
 	dev_dbg(gc->parent, "IRQ rising %*pb falling %*pb\n", 64, rising, 64, falling);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v1 5/5] gpio: xilinx: No need to disable IRQs in the handler
@ 2021-04-08 14:56   ` Andy Shevchenko
  0 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 14:56 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray

In IRQ handler interrupts are already disabled, hence no need
to repeat it. Even in the threaded case, it is not a problem
because IRQ framework keeps interrupt disabled there as well.
Remove disabling IRQ part in the handler.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/gpio/gpio-xilinx.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index 98d90b4c4d2b..d5a08dcdd677 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -503,14 +503,13 @@ static void xgpio_irqhandler(struct irq_desc *desc)
 	DECLARE_BITMAP(all, 64);
 	u32 status;
 	u32 bit;
-	unsigned long flags;
 
 	status = xgpio_readreg(chip->regs + XGPIO_IPISR_OFFSET);
 	xgpio_writereg(chip->regs + XGPIO_IPISR_OFFSET, status);
 
 	chained_irq_enter(irqchip, desc);
 
-	spin_lock_irqsave(&chip->gpio_lock, flags);
+	spin_lock(&chip->gpio_lock);
 
 	xgpio_read_ch_all(chip, XGPIO_DATA_OFFSET, all);
 
@@ -527,7 +526,7 @@ static void xgpio_irqhandler(struct irq_desc *desc)
 	bitmap_copy(chip->last_irq_read, all, 64);
 	bitmap_or(all, rising, falling, 64);
 
-	spin_unlock_irqrestore(&chip->gpio_lock, flags);
+	spin_unlock(&chip->gpio_lock);
 
 	dev_dbg(gc->parent, "IRQ rising %*pb falling %*pb\n", 64, rising, 64, falling);
 
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH v1 4/5] gpio: xilinx: Switch to use bitmap APIs
  2021-04-08 14:56   ` Andy Shevchenko
@ 2021-04-08 15:08     ` Andy Shevchenko
  -1 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 15:08 UTC (permalink / raw)
  To: linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray

On Thu, Apr 08, 2021 at 05:56:00PM +0300, Andy Shevchenko wrote:
> It seems that Xilinx GPIO driver operates with bit arrays longer than 32 and
> thus can leverage bitmap APIs for that. It makes code better to understand.
> 
> The ->probe() function is modified to try read properties for both channels
> since is_dual check makes only sense for the amount of pins used for the second
> channel. On top of that kzalloc() guarantees zero initial values for the fields
> in the private data structure, hence drop unneeded conditionals and assignments.
> 
> The change is inspired by Syed Nayyar Waris' ideas about bitmap API extension.

As I was afraid in the cover letter, I found some mistakes already.
In any case, I'll wait for the comments and test of other patches if possible.

Out of curiosity, below I point out the issues.

...

> +	return bitmap_bitremap(gpio, chip->sw_map, chip->hw_map, chip->gc.ngpio);

Seems we have to use 64 instead of ngpio here.

...

> +	bitmap_replace(state, chip->state, hw_bits, hw_mask, gc->ngpio);

Ditto.

...

> +	bitmap_copy(chip->state, state, gc->ngpio);

Ditto.

...

> +	for_each_set_bit(bit, all, 64)
> +		generic_handle_irq(irq_find_mapping(gc->irq.domain, bit));

Here should be used gpio actually and ngpio IIUC.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v1 4/5] gpio: xilinx: Switch to use bitmap APIs
@ 2021-04-08 15:08     ` Andy Shevchenko
  0 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 15:08 UTC (permalink / raw)
  To: linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray

On Thu, Apr 08, 2021 at 05:56:00PM +0300, Andy Shevchenko wrote:
> It seems that Xilinx GPIO driver operates with bit arrays longer than 32 and
> thus can leverage bitmap APIs for that. It makes code better to understand.
> 
> The ->probe() function is modified to try read properties for both channels
> since is_dual check makes only sense for the amount of pins used for the second
> channel. On top of that kzalloc() guarantees zero initial values for the fields
> in the private data structure, hence drop unneeded conditionals and assignments.
> 
> The change is inspired by Syed Nayyar Waris' ideas about bitmap API extension.

As I was afraid in the cover letter, I found some mistakes already.
In any case, I'll wait for the comments and test of other patches if possible.

Out of curiosity, below I point out the issues.

...

> +	return bitmap_bitremap(gpio, chip->sw_map, chip->hw_map, chip->gc.ngpio);

Seems we have to use 64 instead of ngpio here.

...

> +	bitmap_replace(state, chip->state, hw_bits, hw_mask, gc->ngpio);

Ditto.

...

> +	bitmap_copy(chip->state, state, gc->ngpio);

Ditto.

...

> +	for_each_set_bit(bit, all, 64)
> +		generic_handle_irq(irq_find_mapping(gc->irq.domain, bit));

Here should be used gpio actually and ngpio IIUC.

-- 
With Best Regards,
Andy Shevchenko



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 1/1] drivers/gpio/gpio-xilinx.c (updated): bitmap-fix
  2021-04-08 15:08     ` Andy Shevchenko
@ 2021-04-08 15:31       ` Andy Shevchenko
  -1 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 15:31 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Syed Nayyar Waris, vilhelm.gray

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/gpio/gpio-xilinx.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index d5a08dcdd677..109b32104867 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -75,9 +75,14 @@ struct xgpio_instance {
 	struct clk *clk;
 };
 
+static inline int xgpio_from_bit(struct xgpio_instance *chip, int bit)
+{
+	return bitmap_bitremap(bit, chip->hw_map, chip->sw_map, 64);
+}
+
 static inline int xgpio_to_bit(struct xgpio_instance *chip, int gpio)
 {
-	return bitmap_bitremap(gpio, chip->sw_map, chip->hw_map, chip->gc.ngpio);
+	return bitmap_bitremap(gpio, chip->sw_map, chip->hw_map, 64);
 }
 
 static inline u32 xgpio_get_value32(const unsigned long *map, int bit)
@@ -207,11 +212,11 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
-	bitmap_replace(state, chip->state, hw_bits, hw_mask, gc->ngpio);
+	bitmap_replace(state, chip->state, hw_bits, hw_mask, 64);
 
 	xgpio_write_ch_all(chip, XGPIO_DATA_OFFSET, state);
 
-	bitmap_copy(chip->state, state, gc->ngpio);
+	bitmap_copy(chip->state, state, 64);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 }
@@ -501,6 +506,7 @@ static void xgpio_irqhandler(struct irq_desc *desc)
 	DECLARE_BITMAP(rising, 64);
 	DECLARE_BITMAP(falling, 64);
 	DECLARE_BITMAP(all, 64);
+	int irq_offset;
 	u32 status;
 	u32 bit;
 
@@ -530,8 +536,10 @@ static void xgpio_irqhandler(struct irq_desc *desc)
 
 	dev_dbg(gc->parent, "IRQ rising %*pb falling %*pb\n", 64, rising, 64, falling);
 
-	for_each_set_bit(bit, all, 64)
-		generic_handle_irq(irq_find_mapping(gc->irq.domain, bit));
+	for_each_set_bit(bit, all, 64) {
+		irq_offset = xgpio_from_bit(chip, bit);
+		generic_handle_irq(irq_find_mapping(gc->irq.domain, irq_offset));
+	}
 
 	chained_irq_exit(irqchip, desc);
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 1/1] drivers/gpio/gpio-xilinx.c (updated): bitmap-fix
@ 2021-04-08 15:31       ` Andy Shevchenko
  0 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-08 15:31 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Syed Nayyar Waris, vilhelm.gray

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/gpio/gpio-xilinx.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index d5a08dcdd677..109b32104867 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -75,9 +75,14 @@ struct xgpio_instance {
 	struct clk *clk;
 };
 
+static inline int xgpio_from_bit(struct xgpio_instance *chip, int bit)
+{
+	return bitmap_bitremap(bit, chip->hw_map, chip->sw_map, 64);
+}
+
 static inline int xgpio_to_bit(struct xgpio_instance *chip, int gpio)
 {
-	return bitmap_bitremap(gpio, chip->sw_map, chip->hw_map, chip->gc.ngpio);
+	return bitmap_bitremap(gpio, chip->sw_map, chip->hw_map, 64);
 }
 
 static inline u32 xgpio_get_value32(const unsigned long *map, int bit)
@@ -207,11 +212,11 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
 
 	spin_lock_irqsave(&chip->gpio_lock, flags);
 
-	bitmap_replace(state, chip->state, hw_bits, hw_mask, gc->ngpio);
+	bitmap_replace(state, chip->state, hw_bits, hw_mask, 64);
 
 	xgpio_write_ch_all(chip, XGPIO_DATA_OFFSET, state);
 
-	bitmap_copy(chip->state, state, gc->ngpio);
+	bitmap_copy(chip->state, state, 64);
 
 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
 }
@@ -501,6 +506,7 @@ static void xgpio_irqhandler(struct irq_desc *desc)
 	DECLARE_BITMAP(rising, 64);
 	DECLARE_BITMAP(falling, 64);
 	DECLARE_BITMAP(all, 64);
+	int irq_offset;
 	u32 status;
 	u32 bit;
 
@@ -530,8 +536,10 @@ static void xgpio_irqhandler(struct irq_desc *desc)
 
 	dev_dbg(gc->parent, "IRQ rising %*pb falling %*pb\n", 64, rising, 64, falling);
 
-	for_each_set_bit(bit, all, 64)
-		generic_handle_irq(irq_find_mapping(gc->irq.domain, bit));
+	for_each_set_bit(bit, all, 64) {
+		irq_offset = xgpio_from_bit(chip, bit);
+		generic_handle_irq(irq_find_mapping(gc->irq.domain, irq_offset));
+	}
 
 	chained_irq_exit(irqchip, desc);
 }
-- 
2.30.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH v1 2/5] gpio: xilinx: Correct kernel doc for xgpio_probe()
  2021-04-08 14:55   ` Andy Shevchenko
@ 2021-04-08 16:16     ` Michal Simek
  -1 siblings, 0 replies; 30+ messages in thread
From: Michal Simek @ 2021-04-08 16:16 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray



On 4/8/21 4:55 PM, Andy Shevchenko wrote:
> Kernel doc validator complains:
> 
> .../gpio-xilinx.c:556: warning: expecting prototype for xgpio_of_probe(). Prototype was for xgpio_probe() instead
> 
> Correct as suggested by changing the name of the function in the doc..
> 
> Fixes: 749564ffd52d ("gpio/xilinx: Convert the driver to platform device interface")
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  drivers/gpio/gpio-xilinx.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
> index b411d3156e0b..136557e7dd3c 100644
> --- a/drivers/gpio/gpio-xilinx.c
> +++ b/drivers/gpio/gpio-xilinx.c
> @@ -542,7 +542,7 @@ static void xgpio_irqhandler(struct irq_desc *desc)
>  }
>  
>  /**
> - * xgpio_of_probe - Probe method for the GPIO device.
> + * xgpio_probe - Probe method for the GPIO device.
>   * @pdev: pointer to the platform device
>   *
>   * Return:
> 

Reviewed-by: Michal Simek <michal.simek@xilinx.com>

Thanks,
Michal

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v1 2/5] gpio: xilinx: Correct kernel doc for xgpio_probe()
@ 2021-04-08 16:16     ` Michal Simek
  0 siblings, 0 replies; 30+ messages in thread
From: Michal Simek @ 2021-04-08 16:16 UTC (permalink / raw)
  To: Andy Shevchenko, linux-gpio, linux-arm-kernel, linux-kernel
  Cc: Shubhrajyoti Datta, Srinivas Neeli, Michal Simek, Linus Walleij,
	Bartosz Golaszewski, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, vilhelm.gray



On 4/8/21 4:55 PM, Andy Shevchenko wrote:
> Kernel doc validator complains:
> 
> .../gpio-xilinx.c:556: warning: expecting prototype for xgpio_of_probe(). Prototype was for xgpio_probe() instead
> 
> Correct as suggested by changing the name of the function in the doc..
> 
> Fixes: 749564ffd52d ("gpio/xilinx: Convert the driver to platform device interface")
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  drivers/gpio/gpio-xilinx.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
> index b411d3156e0b..136557e7dd3c 100644
> --- a/drivers/gpio/gpio-xilinx.c
> +++ b/drivers/gpio/gpio-xilinx.c
> @@ -542,7 +542,7 @@ static void xgpio_irqhandler(struct irq_desc *desc)
>  }
>  
>  /**
> - * xgpio_of_probe - Probe method for the GPIO device.
> + * xgpio_probe - Probe method for the GPIO device.
>   * @pdev: pointer to the platform device
>   *
>   * Return:
> 

Reviewed-by: Michal Simek <michal.simek@xilinx.com>

Thanks,
Michal

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v1 1/5] bitmap: Make bitmap_remap() and bitmap_bitremap() available to users
  2021-04-08 14:55   ` Andy Shevchenko
@ 2021-04-08 16:52     ` Yury Norov
  -1 siblings, 0 replies; 30+ messages in thread
From: Yury Norov @ 2021-04-08 16:52 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-gpio, linux-arm-kernel, linux-kernel, Shubhrajyoti Datta,
	Srinivas Neeli, Michal Simek, Linus Walleij, Bartosz Golaszewski,
	Rasmus Villemoes, Syed Nayyar Waris, vilhelm.gray

On Thu, Apr 08, 2021 at 05:55:57PM +0300, Andy Shevchenko wrote:
> Currently the bitmap_remap() and bitmap_bitremap() are available
> only for CONFIG_NUMA=y case, while some users may benefit out of it
> and being independent to NUMA code. Make them available to users
> by moving out of ifdeffery and exporting for modules.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  lib/bitmap.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/bitmap.c b/lib/bitmap.c
> index 74ceb02f45e3..7b6b2a67a6a6 100644
> --- a/lib/bitmap.c
> +++ b/lib/bitmap.c
> @@ -784,8 +784,6 @@ int bitmap_parse(const char *start, unsigned int buflen,
>  }
>  EXPORT_SYMBOL(bitmap_parse);
>  
> -
> -#ifdef CONFIG_NUMA
>  /**
>   * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap
>   *	@buf: pointer to a bitmap
> @@ -894,6 +892,7 @@ void bitmap_remap(unsigned long *dst, const unsigned long *src,
>  			set_bit(bitmap_ord_to_pos(new, n % w, nbits), dst);
>  	}
>  }
> +EXPORT_SYMBOL(bitmap_remap);
>  
>  /**
>   * bitmap_bitremap - Apply map defined by a pair of bitmaps to a single bit
> @@ -931,7 +930,9 @@ int bitmap_bitremap(int oldbit, const unsigned long *old,
>  	else
>  		return bitmap_ord_to_pos(new, n % w, bits);
>  }
> +EXPORT_SYMBOL(bitmap_bitremap);
>  
> +#ifdef CONFIG_NUMA
>  /**
>   * bitmap_onto - translate one bitmap relative to another
>   *	@dst: resulting translated bitmap
> -- 
> 2.30.2

Acked-by: Yury Norov <yury.norov@gmail.com>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH v1 1/5] bitmap: Make bitmap_remap() and bitmap_bitremap() available to users
@ 2021-04-08 16:52     ` Yury Norov
  0 siblings, 0 replies; 30+ messages in thread
From: Yury Norov @ 2021-04-08 16:52 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-gpio, linux-arm-kernel, linux-kernel, Shubhrajyoti Datta,
	Srinivas Neeli, Michal Simek, Linus Walleij, Bartosz Golaszewski,
	Rasmus Villemoes, Syed Nayyar Waris, vilhelm.gray

On Thu, Apr 08, 2021 at 05:55:57PM +0300, Andy Shevchenko wrote:
> Currently the bitmap_remap() and bitmap_bitremap() are available
> only for CONFIG_NUMA=y case, while some users may benefit out of it
> and being independent to NUMA code. Make them available to users
> by moving out of ifdeffery and exporting for modules.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  lib/bitmap.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/bitmap.c b/lib/bitmap.c
> index 74ceb02f45e3..7b6b2a67a6a6 100644
> --- a/lib/bitmap.c
> +++ b/lib/bitmap.c
> @@ -784,8 +784,6 @@ int bitmap_parse(const char *start, unsigned int buflen,
>  }
>  EXPORT_SYMBOL(bitmap_parse);
>  
> -
> -#ifdef CONFIG_NUMA
>  /**
>   * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap
>   *	@buf: pointer to a bitmap
> @@ -894,6 +892,7 @@ void bitmap_remap(unsigned long *dst, const unsigned long *src,
>  			set_bit(bitmap_ord_to_pos(new, n % w, nbits), dst);
>  	}
>  }
> +EXPORT_SYMBOL(bitmap_remap);
>  
>  /**
>   * bitmap_bitremap - Apply map defined by a pair of bitmaps to a single bit
> @@ -931,7 +930,9 @@ int bitmap_bitremap(int oldbit, const unsigned long *old,
>  	else
>  		return bitmap_ord_to_pos(new, n % w, bits);
>  }
> +EXPORT_SYMBOL(bitmap_bitremap);
>  
> +#ifdef CONFIG_NUMA
>  /**
>   * bitmap_onto - translate one bitmap relative to another
>   *	@dst: resulting translated bitmap
> -- 
> 2.30.2

Acked-by: Yury Norov <yury.norov@gmail.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
  2021-04-08 14:55 ` Andy Shevchenko
@ 2021-04-23 20:41   ` Bartosz Golaszewski
  -1 siblings, 0 replies; 30+ messages in thread
From: Bartosz Golaszewski @ 2021-04-23 20:41 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-gpio, arm-soc, LKML, Shubhrajyoti Datta, Srinivas Neeli,
	Michal Simek, Linus Walleij, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, William Breathitt Gray

On Thu, Apr 8, 2021 at 4:55 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> The change in the series has been inspired by [1], which, I think,
> can be improved. Here I present the view how it can be done.
>
> The series marked as RFT since I have no hardware and I perform
> compile test only.
>
> The patches 1 and 2 can be (independently) applied for v5.13, but I'm not in
> hurry with the series, due to above (lack of real testing). So I'm flexible in
> a way how it can be proceed.
>
> [1]: cover.1617380819.git.syednwaris@gmail.com
>
> Andy Shevchenko (5):
>   bitmap: Make bitmap_remap() and bitmap_bitremap() available to users
>   gpio: xilinx: Correct kernel doc for xgpio_probe()
>   gpio: xilinx: Introduce xgpio_read_chan() / xgpio_write_chan()
>   gpio: xilinx: Switch to use bitmap APIs
>   gpio: xilinx: No need to disable IRQs in the handler
>
>  drivers/gpio/gpio-xilinx.c | 377 ++++++++++++++++++-------------------
>  lib/bitmap.c               |   5 +-
>  2 files changed, 190 insertions(+), 192 deletions(-)
>
> --
> 2.30.2
>

I usually trust Andy with his work but is there any chance we can get
a Tested-by before the merge window?

Bart

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
@ 2021-04-23 20:41   ` Bartosz Golaszewski
  0 siblings, 0 replies; 30+ messages in thread
From: Bartosz Golaszewski @ 2021-04-23 20:41 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-gpio, arm-soc, LKML, Shubhrajyoti Datta, Srinivas Neeli,
	Michal Simek, Linus Walleij, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, William Breathitt Gray

On Thu, Apr 8, 2021 at 4:55 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> The change in the series has been inspired by [1], which, I think,
> can be improved. Here I present the view how it can be done.
>
> The series marked as RFT since I have no hardware and I perform
> compile test only.
>
> The patches 1 and 2 can be (independently) applied for v5.13, but I'm not in
> hurry with the series, due to above (lack of real testing). So I'm flexible in
> a way how it can be proceed.
>
> [1]: cover.1617380819.git.syednwaris@gmail.com
>
> Andy Shevchenko (5):
>   bitmap: Make bitmap_remap() and bitmap_bitremap() available to users
>   gpio: xilinx: Correct kernel doc for xgpio_probe()
>   gpio: xilinx: Introduce xgpio_read_chan() / xgpio_write_chan()
>   gpio: xilinx: Switch to use bitmap APIs
>   gpio: xilinx: No need to disable IRQs in the handler
>
>  drivers/gpio/gpio-xilinx.c | 377 ++++++++++++++++++-------------------
>  lib/bitmap.c               |   5 +-
>  2 files changed, 190 insertions(+), 192 deletions(-)
>
> --
> 2.30.2
>

I usually trust Andy with his work but is there any chance we can get
a Tested-by before the merge window?

Bart

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
  2021-04-23 20:41   ` Bartosz Golaszewski
@ 2021-04-24 11:08     ` Andy Shevchenko
  -1 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-24 11:08 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: linux-gpio, arm-soc, LKML, Shubhrajyoti Datta, Srinivas Neeli,
	Michal Simek, Linus Walleij, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, William Breathitt Gray

On Fri, Apr 23, 2021 at 10:41:26PM +0200, Bartosz Golaszewski wrote:
> On Thu, Apr 8, 2021 at 4:55 PM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> >
> > The change in the series has been inspired by [1], which, I think,
> > can be improved. Here I present the view how it can be done.
> >
> > The series marked as RFT since I have no hardware and I perform
> > compile test only.
> >
> > The patches 1 and 2 can be (independently) applied for v5.13, but I'm not in
> > hurry with the series, due to above (lack of real testing). So I'm flexible in
> > a way how it can be proceed.
> >
> > [1]: cover.1617380819.git.syednwaris@gmail.com

> I usually trust Andy with his work but is there any chance we can get
> a Tested-by before the merge window?

I'm not in hurry with this and I really want to have a confirmation on this
before we proceed. I may send a v2 RFT after v5.13-rc1 is out.

Note TWIMC that the series has an additional followup fix that I sent
separately (it's properly linked to the thread nevertheless).

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
@ 2021-04-24 11:08     ` Andy Shevchenko
  0 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-24 11:08 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: linux-gpio, arm-soc, LKML, Shubhrajyoti Datta, Srinivas Neeli,
	Michal Simek, Linus Walleij, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, William Breathitt Gray

On Fri, Apr 23, 2021 at 10:41:26PM +0200, Bartosz Golaszewski wrote:
> On Thu, Apr 8, 2021 at 4:55 PM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> >
> > The change in the series has been inspired by [1], which, I think,
> > can be improved. Here I present the view how it can be done.
> >
> > The series marked as RFT since I have no hardware and I perform
> > compile test only.
> >
> > The patches 1 and 2 can be (independently) applied for v5.13, but I'm not in
> > hurry with the series, due to above (lack of real testing). So I'm flexible in
> > a way how it can be proceed.
> >
> > [1]: cover.1617380819.git.syednwaris@gmail.com

> I usually trust Andy with his work but is there any chance we can get
> a Tested-by before the merge window?

I'm not in hurry with this and I really want to have a confirmation on this
before we proceed. I may send a v2 RFT after v5.13-rc1 is out.

Note TWIMC that the series has an additional followup fix that I sent
separately (it's properly linked to the thread nevertheless).

-- 
With Best Regards,
Andy Shevchenko



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
  2021-04-23 20:41   ` Bartosz Golaszewski
@ 2021-04-24 11:14     ` Andy Shevchenko
  -1 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-24 11:14 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: linux-gpio, arm-soc, LKML, Shubhrajyoti Datta, Srinivas Neeli,
	Michal Simek, Linus Walleij, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, William Breathitt Gray

On Fri, Apr 23, 2021 at 10:41:26PM +0200, Bartosz Golaszewski wrote:
> On Thu, Apr 8, 2021 at 4:55 PM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> >
> > The change in the series has been inspired by [1], which, I think,
> > can be improved. Here I present the view how it can be done.
> >
> > The series marked as RFT since I have no hardware and I perform
> > compile test only.
> >
> > The patches 1 and 2 can be (independently) applied for v5.13, but I'm not in
> > hurry with the series, due to above (lack of real testing). So I'm flexible in
> > a way how it can be proceed.

> >   bitmap: Make bitmap_remap() and bitmap_bitremap() available to users
> >   gpio: xilinx: Correct kernel doc for xgpio_probe()

Bart, thanks for the warm words, just pointing out that patches 1 and 2 has
been reviewed and may be applied for v5.13 cycle. Up to you.

> I usually trust Andy with his work but is there any chance we can get
> a Tested-by before the merge window?

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
@ 2021-04-24 11:14     ` Andy Shevchenko
  0 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-24 11:14 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: linux-gpio, arm-soc, LKML, Shubhrajyoti Datta, Srinivas Neeli,
	Michal Simek, Linus Walleij, Yury Norov, Rasmus Villemoes,
	Syed Nayyar Waris, William Breathitt Gray

On Fri, Apr 23, 2021 at 10:41:26PM +0200, Bartosz Golaszewski wrote:
> On Thu, Apr 8, 2021 at 4:55 PM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> >
> > The change in the series has been inspired by [1], which, I think,
> > can be improved. Here I present the view how it can be done.
> >
> > The series marked as RFT since I have no hardware and I perform
> > compile test only.
> >
> > The patches 1 and 2 can be (independently) applied for v5.13, but I'm not in
> > hurry with the series, due to above (lack of real testing). So I'm flexible in
> > a way how it can be proceed.

> >   bitmap: Make bitmap_remap() and bitmap_bitremap() available to users
> >   gpio: xilinx: Correct kernel doc for xgpio_probe()

Bart, thanks for the warm words, just pointing out that patches 1 and 2 has
been reviewed and may be applied for v5.13 cycle. Up to you.

> I usually trust Andy with his work but is there any chance we can get
> a Tested-by before the merge window?

-- 
With Best Regards,
Andy Shevchenko



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
  2021-04-24 11:14     ` Andy Shevchenko
@ 2021-04-29 13:59       ` Srinivas Neeli
  -1 siblings, 0 replies; 30+ messages in thread
From: Srinivas Neeli @ 2021-04-29 13:59 UTC (permalink / raw)
  To: Andy Shevchenko, Bartosz Golaszewski
  Cc: linux-gpio, arm-soc, LKML, Shubhrajyoti Datta, Michal Simek,
	Linus Walleij, Yury Norov, Rasmus Villemoes, Syed Nayyar Waris,
	William Breathitt Gray

Hi Bartosz,

> -----Original Message-----
> From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Sent: Saturday, April 24, 2021 4:45 PM
> To: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> Cc: linux-gpio <linux-gpio@vger.kernel.org>; arm-soc <linux-arm-
> kernel@lists.infradead.org>; LKML <linux-kernel@vger.kernel.org>;
> Shubhrajyoti Datta <shubhraj@xilinx.com>; Srinivas Neeli
> <sneeli@xilinx.com>; Michal Simek <michals@xilinx.com>; Linus Walleij
> <linus.walleij@linaro.org>; Yury Norov <yury.norov@gmail.com>; Rasmus
> Villemoes <linux@rasmusvillemoes.dk>; Syed Nayyar Waris
> <syednwaris@gmail.com>; William Breathitt Gray <vilhelm.gray@gmail.com>
> Subject: Re: [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
> 
> On Fri, Apr 23, 2021 at 10:41:26PM +0200, Bartosz Golaszewski wrote:
> > On Thu, Apr 8, 2021 at 4:55 PM Andy Shevchenko
> > <andriy.shevchenko@linux.intel.com> wrote:
> > >
> > > The change in the series has been inspired by [1], which, I think,
> > > can be improved. Here I present the view how it can be done.
> > >
> > > The series marked as RFT since I have no hardware and I perform
> > > compile test only.
> > >
> > > The patches 1 and 2 can be (independently) applied for v5.13, but
> > > I'm not in hurry with the series, due to above (lack of real
> > > testing). So I'm flexible in a way how it can be proceed.
> 
> > >   bitmap: Make bitmap_remap() and bitmap_bitremap() available to
> users
> > >   gpio: xilinx: Correct kernel doc for xgpio_probe()
> 
> Bart, thanks for the warm words, just pointing out that patches 1 and 2 has
> been reviewed and may be applied for v5.13 cycle. Up to you.
> 
> > I usually trust Andy with his work but is there any chance we can get
> > a Tested-by before the merge window?

Patches tested. Functionality working fine.

Tested-by: Neeli Srinivas <sneeli@xilinx.com>

> 
> --
> With Best Regards,
> Andy Shevchenko
> 


^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
@ 2021-04-29 13:59       ` Srinivas Neeli
  0 siblings, 0 replies; 30+ messages in thread
From: Srinivas Neeli @ 2021-04-29 13:59 UTC (permalink / raw)
  To: Andy Shevchenko, Bartosz Golaszewski
  Cc: linux-gpio, arm-soc, LKML, Shubhrajyoti Datta, Michal Simek,
	Linus Walleij, Yury Norov, Rasmus Villemoes, Syed Nayyar Waris,
	William Breathitt Gray

Hi Bartosz,

> -----Original Message-----
> From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Sent: Saturday, April 24, 2021 4:45 PM
> To: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> Cc: linux-gpio <linux-gpio@vger.kernel.org>; arm-soc <linux-arm-
> kernel@lists.infradead.org>; LKML <linux-kernel@vger.kernel.org>;
> Shubhrajyoti Datta <shubhraj@xilinx.com>; Srinivas Neeli
> <sneeli@xilinx.com>; Michal Simek <michals@xilinx.com>; Linus Walleij
> <linus.walleij@linaro.org>; Yury Norov <yury.norov@gmail.com>; Rasmus
> Villemoes <linux@rasmusvillemoes.dk>; Syed Nayyar Waris
> <syednwaris@gmail.com>; William Breathitt Gray <vilhelm.gray@gmail.com>
> Subject: Re: [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
> 
> On Fri, Apr 23, 2021 at 10:41:26PM +0200, Bartosz Golaszewski wrote:
> > On Thu, Apr 8, 2021 at 4:55 PM Andy Shevchenko
> > <andriy.shevchenko@linux.intel.com> wrote:
> > >
> > > The change in the series has been inspired by [1], which, I think,
> > > can be improved. Here I present the view how it can be done.
> > >
> > > The series marked as RFT since I have no hardware and I perform
> > > compile test only.
> > >
> > > The patches 1 and 2 can be (independently) applied for v5.13, but
> > > I'm not in hurry with the series, due to above (lack of real
> > > testing). So I'm flexible in a way how it can be proceed.
> 
> > >   bitmap: Make bitmap_remap() and bitmap_bitremap() available to
> users
> > >   gpio: xilinx: Correct kernel doc for xgpio_probe()
> 
> Bart, thanks for the warm words, just pointing out that patches 1 and 2 has
> been reviewed and may be applied for v5.13 cycle. Up to you.
> 
> > I usually trust Andy with his work but is there any chance we can get
> > a Tested-by before the merge window?

Patches tested. Functionality working fine.

Tested-by: Neeli Srinivas <sneeli@xilinx.com>

> 
> --
> With Best Regards,
> Andy Shevchenko
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
  2021-04-29 13:59       ` Srinivas Neeli
@ 2021-04-29 14:30         ` Andy Shevchenko
  -1 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-29 14:30 UTC (permalink / raw)
  To: Srinivas Neeli
  Cc: Andy Shevchenko, Bartosz Golaszewski, linux-gpio, arm-soc, LKML,
	Shubhrajyoti Datta, Michal Simek, Linus Walleij, Yury Norov,
	Rasmus Villemoes, Syed Nayyar Waris, William Breathitt Gray

On Thu, Apr 29, 2021 at 5:00 PM Srinivas Neeli <sneeli@xilinx.com> wrote:
>
> Hi Bartosz,
>
> > -----Original Message-----
> > From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > Sent: Saturday, April 24, 2021 4:45 PM
> > To: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> > Cc: linux-gpio <linux-gpio@vger.kernel.org>; arm-soc <linux-arm-
> > kernel@lists.infradead.org>; LKML <linux-kernel@vger.kernel.org>;
> > Shubhrajyoti Datta <shubhraj@xilinx.com>; Srinivas Neeli
> > <sneeli@xilinx.com>; Michal Simek <michals@xilinx.com>; Linus Walleij
> > <linus.walleij@linaro.org>; Yury Norov <yury.norov@gmail.com>; Rasmus
> > Villemoes <linux@rasmusvillemoes.dk>; Syed Nayyar Waris
> > <syednwaris@gmail.com>; William Breathitt Gray <vilhelm.gray@gmail.com>
> > Subject: Re: [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
> >
> > On Fri, Apr 23, 2021 at 10:41:26PM +0200, Bartosz Golaszewski wrote:
> > > On Thu, Apr 8, 2021 at 4:55 PM Andy Shevchenko
> > > <andriy.shevchenko@linux.intel.com> wrote:
> > > >
> > > > The change in the series has been inspired by [1], which, I think,
> > > > can be improved. Here I present the view how it can be done.
> > > >
> > > > The series marked as RFT since I have no hardware and I perform
> > > > compile test only.
> > > >
> > > > The patches 1 and 2 can be (independently) applied for v5.13, but
> > > > I'm not in hurry with the series, due to above (lack of real
> > > > testing). So I'm flexible in a way how it can be proceed.
> >
> > > >   bitmap: Make bitmap_remap() and bitmap_bitremap() available to
> > users
> > > >   gpio: xilinx: Correct kernel doc for xgpio_probe()
> >
> > Bart, thanks for the warm words, just pointing out that patches 1 and 2 has
> > been reviewed and may be applied for v5.13 cycle. Up to you.
> >
> > > I usually trust Andy with his work but is there any chance we can get
> > > a Tested-by before the merge window?
>
> Patches tested. Functionality working fine.
>
> Tested-by: Neeli Srinivas <sneeli@xilinx.com>

Thank you very much! I'll send a v2 with your tags after v5.13-rc1 is out.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
@ 2021-04-29 14:30         ` Andy Shevchenko
  0 siblings, 0 replies; 30+ messages in thread
From: Andy Shevchenko @ 2021-04-29 14:30 UTC (permalink / raw)
  To: Srinivas Neeli
  Cc: Andy Shevchenko, Bartosz Golaszewski, linux-gpio, arm-soc, LKML,
	Shubhrajyoti Datta, Michal Simek, Linus Walleij, Yury Norov,
	Rasmus Villemoes, Syed Nayyar Waris, William Breathitt Gray

On Thu, Apr 29, 2021 at 5:00 PM Srinivas Neeli <sneeli@xilinx.com> wrote:
>
> Hi Bartosz,
>
> > -----Original Message-----
> > From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > Sent: Saturday, April 24, 2021 4:45 PM
> > To: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> > Cc: linux-gpio <linux-gpio@vger.kernel.org>; arm-soc <linux-arm-
> > kernel@lists.infradead.org>; LKML <linux-kernel@vger.kernel.org>;
> > Shubhrajyoti Datta <shubhraj@xilinx.com>; Srinivas Neeli
> > <sneeli@xilinx.com>; Michal Simek <michals@xilinx.com>; Linus Walleij
> > <linus.walleij@linaro.org>; Yury Norov <yury.norov@gmail.com>; Rasmus
> > Villemoes <linux@rasmusvillemoes.dk>; Syed Nayyar Waris
> > <syednwaris@gmail.com>; William Breathitt Gray <vilhelm.gray@gmail.com>
> > Subject: Re: [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API
> >
> > On Fri, Apr 23, 2021 at 10:41:26PM +0200, Bartosz Golaszewski wrote:
> > > On Thu, Apr 8, 2021 at 4:55 PM Andy Shevchenko
> > > <andriy.shevchenko@linux.intel.com> wrote:
> > > >
> > > > The change in the series has been inspired by [1], which, I think,
> > > > can be improved. Here I present the view how it can be done.
> > > >
> > > > The series marked as RFT since I have no hardware and I perform
> > > > compile test only.
> > > >
> > > > The patches 1 and 2 can be (independently) applied for v5.13, but
> > > > I'm not in hurry with the series, due to above (lack of real
> > > > testing). So I'm flexible in a way how it can be proceed.
> >
> > > >   bitmap: Make bitmap_remap() and bitmap_bitremap() available to
> > users
> > > >   gpio: xilinx: Correct kernel doc for xgpio_probe()
> >
> > Bart, thanks for the warm words, just pointing out that patches 1 and 2 has
> > been reviewed and may be applied for v5.13 cycle. Up to you.
> >
> > > I usually trust Andy with his work but is there any chance we can get
> > > a Tested-by before the merge window?
>
> Patches tested. Functionality working fine.
>
> Tested-by: Neeli Srinivas <sneeli@xilinx.com>

Thank you very much! I'll send a v2 with your tags after v5.13-rc1 is out.

-- 
With Best Regards,
Andy Shevchenko

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2021-04-29 14:32 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-08 14:55 [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API Andy Shevchenko
2021-04-08 14:55 ` Andy Shevchenko
2021-04-08 14:55 ` [PATCH v1 1/5] bitmap: Make bitmap_remap() and bitmap_bitremap() available to users Andy Shevchenko
2021-04-08 14:55   ` Andy Shevchenko
2021-04-08 16:52   ` Yury Norov
2021-04-08 16:52     ` Yury Norov
2021-04-08 14:55 ` [PATCH v1 2/5] gpio: xilinx: Correct kernel doc for xgpio_probe() Andy Shevchenko
2021-04-08 14:55   ` Andy Shevchenko
2021-04-08 16:16   ` Michal Simek
2021-04-08 16:16     ` Michal Simek
2021-04-08 14:55 ` [PATCH v1 3/5] gpio: xilinx: Introduce xgpio_read_chan() / xgpio_write_chan() Andy Shevchenko
2021-04-08 14:55   ` Andy Shevchenko
2021-04-08 14:56 ` [PATCH v1 4/5] gpio: xilinx: Switch to use bitmap APIs Andy Shevchenko
2021-04-08 14:56   ` Andy Shevchenko
2021-04-08 15:08   ` Andy Shevchenko
2021-04-08 15:08     ` Andy Shevchenko
2021-04-08 15:31     ` [PATCH 1/1] drivers/gpio/gpio-xilinx.c (updated): bitmap-fix Andy Shevchenko
2021-04-08 15:31       ` Andy Shevchenko
2021-04-08 14:56 ` [PATCH v1 5/5] gpio: xilinx: No need to disable IRQs in the handler Andy Shevchenko
2021-04-08 14:56   ` Andy Shevchenko
2021-04-23 20:41 ` [RFT, PATCH v1 0/5] gpio: xilinx: convert to use bitmap API Bartosz Golaszewski
2021-04-23 20:41   ` Bartosz Golaszewski
2021-04-24 11:08   ` Andy Shevchenko
2021-04-24 11:08     ` Andy Shevchenko
2021-04-24 11:14   ` Andy Shevchenko
2021-04-24 11:14     ` Andy Shevchenko
2021-04-29 13:59     ` Srinivas Neeli
2021-04-29 13:59       ` Srinivas Neeli
2021-04-29 14:30       ` Andy Shevchenko
2021-04-29 14:30         ` Andy Shevchenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.