linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Linus Walleij <linus.walleij@linaro.org>
To: linux-gpio@vger.kernel.org
Cc: "Linus Walleij" <linus.walleij@linaro.org>,
	"Liu Gang" <Gang.Liu@nxp.com>,
	"Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
Subject: [PATCH] gpio: mpc8xxx: Do not reverse bits using bgpio
Date: Fri, 20 Oct 2017 16:14:13 +0200	[thread overview]
Message-ID: <20171020141413.29459-1-linus.walleij@linaro.org> (raw)

The MPC8xxx driver is always instantiating its generic GPIO functions
with the flag BGPIOF_BIG_ENDIAN. This means "big-endian bit order"
and means the bits representing the GPIO lines in the registers are
reversed around 31 bits so line 0 is at bit 31 and so forth down to
line 31 in bit 0.

Instead of looping into the generic MMIO gpio to do the simple
calculation of a bitmask, through a vtable call with two parameters
likely using stack frames etc (unless the compiler optimize it)
and obscuring the view for the programmer, let's just open-code
what the call does. This likely executes faster, saves space and
makes the code easier to read.

Cc: Liu Gang <Gang.Liu@nxp.com>
Cc: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpio/gpio-mpc8xxx.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 8c93dec498fa..ff5bf9c5dcec 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/irq.h>
 #include <linux/gpio/driver.h>
+#include <linux/bitops.h>
 
 #define MPC8XXX_GPIO_PINS	32
 
@@ -44,6 +45,16 @@ struct mpc8xxx_gpio_chip {
 	unsigned int irqn;
 };
 
+/*
+ * This hardware has a big endian bit assignment such that GPIO line 0 is
+ * connected to bit 31, line 1 to bit 30 ... line 31 to bit 0.
+ * This inline helper give the right bitmask for a certain line.
+ */
+static inline u32 mpc_pin2mask(unsigned int offset)
+{
+	return BIT(31 - offset);
+}
+
 /* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
  * defined as output cannot be determined by reading GPDAT register,
  * so we use shadow data register instead. The status of input pins
@@ -59,7 +70,7 @@ static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
 	val = gc->read_reg(mpc8xxx_gc->regs + GPIO_DAT) & ~out_mask;
 	out_shadow = gc->bgpio_data & out_mask;
 
-	return !!((val | out_shadow) & gc->pin2mask(gc, gpio));
+	return !!((val | out_shadow) & mpc_pin2mask(offset));
 }
 
 static int mpc5121_gpio_dir_out(struct gpio_chip *gc,
@@ -120,7 +131,7 @@ static void mpc8xxx_irq_unmask(struct irq_data *d)
 
 	gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR,
 		gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR)
-		| gc->pin2mask(gc, irqd_to_hwirq(d)));
+		| mpc_pin2mask(irqd_to_hwirq(d)));
 
 	raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 }
@@ -135,7 +146,7 @@ static void mpc8xxx_irq_mask(struct irq_data *d)
 
 	gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR,
 		gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR)
-		& ~(gc->pin2mask(gc, irqd_to_hwirq(d))));
+		& ~mpc_pin2mask(irqd_to_hwirq(d)));
 
 	raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 }
@@ -146,7 +157,7 @@ static void mpc8xxx_irq_ack(struct irq_data *d)
 	struct gpio_chip *gc = &mpc8xxx_gc->gc;
 
 	gc->write_reg(mpc8xxx_gc->regs + GPIO_IER,
-		      gc->pin2mask(gc, irqd_to_hwirq(d)));
+		      mpc_pin2mask(irqd_to_hwirq(d)));
 }
 
 static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
@@ -160,7 +171,7 @@ static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
 		raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 		gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR,
 			gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR)
-			| gc->pin2mask(gc, irqd_to_hwirq(d)));
+			| mpc_pin2mask(irqd_to_hwirq(d)));
 		raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 		break;
 
@@ -168,7 +179,7 @@ static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
 		raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 		gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR,
 			gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR)
-			& ~(gc->pin2mask(gc, irqd_to_hwirq(d))));
+			& ~mpc_pin2mask(irqd_to_hwirq(d)));
 		raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 		break;
 
-- 
2.13.6


                 reply	other threads:[~2017-10-20 14:16 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171020141413.29459-1-linus.walleij@linaro.org \
    --to=linus.walleij@linaro.org \
    --cc=Gang.Liu@nxp.com \
    --cc=linux-gpio@vger.kernel.org \
    --cc=u.kleine-koenig@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).