Commit b3222f71 authored by Linus Walleij's avatar Linus Walleij

gpio: mpc8xxx: Do not reverse bits using bgpio

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: default avatarLinus Walleij <linus.walleij@linaro.org>
parent d7442368
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/gpio/driver.h> #include <linux/gpio/driver.h>
#include <linux/bitops.h>
#define MPC8XXX_GPIO_PINS 32 #define MPC8XXX_GPIO_PINS 32
...@@ -44,6 +45,16 @@ struct mpc8xxx_gpio_chip { ...@@ -44,6 +45,16 @@ struct mpc8xxx_gpio_chip {
unsigned int irqn; 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 /* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
* defined as output cannot be determined by reading GPDAT register, * defined as output cannot be determined by reading GPDAT register,
* so we use shadow data register instead. The status of input pins * 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) ...@@ -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; val = gc->read_reg(mpc8xxx_gc->regs + GPIO_DAT) & ~out_mask;
out_shadow = gc->bgpio_data & out_mask; out_shadow = gc->bgpio_data & out_mask;
return !!((val | out_shadow) & gc->pin2mask(gc, gpio)); return !!((val | out_shadow) & mpc_pin2mask(gpio));
} }
static int mpc5121_gpio_dir_out(struct gpio_chip *gc, static int mpc5121_gpio_dir_out(struct gpio_chip *gc,
...@@ -120,7 +131,7 @@ static void mpc8xxx_irq_unmask(struct irq_data *d) ...@@ -120,7 +131,7 @@ static void mpc8xxx_irq_unmask(struct irq_data *d)
gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR,
gc->read_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); raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
} }
...@@ -135,7 +146,7 @@ static void mpc8xxx_irq_mask(struct irq_data *d) ...@@ -135,7 +146,7 @@ static void mpc8xxx_irq_mask(struct irq_data *d)
gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR,
gc->read_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); raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
} }
...@@ -146,7 +157,7 @@ static void mpc8xxx_irq_ack(struct irq_data *d) ...@@ -146,7 +157,7 @@ static void mpc8xxx_irq_ack(struct irq_data *d)
struct gpio_chip *gc = &mpc8xxx_gc->gc; struct gpio_chip *gc = &mpc8xxx_gc->gc;
gc->write_reg(mpc8xxx_gc->regs + GPIO_IER, 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) 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) ...@@ -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); raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR, gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR,
gc->read_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); raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
break; break;
...@@ -168,7 +179,7 @@ static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) ...@@ -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); raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR, gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR,
gc->read_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); raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment