summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2017-10-20 10:08:12 -0400
committerLinus Walleij <linus.walleij@linaro.org>2017-10-25 05:25:40 -0400
commitb3222f7147e028d31f965f193b6f995147c64651 (patch)
tree7f75b5c93892bc59543fed5adcc53e38da6fc502
parentd74423687f9d70417bfec68121cbd35f79bb170f (diff)
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: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/gpio/gpio-mpc8xxx.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 8c93dec498fa..c8673a5d9412 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -21,6 +21,7 @@
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/irq.h> 22#include <linux/irq.h>
23#include <linux/gpio/driver.h> 23#include <linux/gpio/driver.h>
24#include <linux/bitops.h>
24 25
25#define MPC8XXX_GPIO_PINS 32 26#define MPC8XXX_GPIO_PINS 32
26 27
@@ -44,6 +45,16 @@ struct mpc8xxx_gpio_chip {
44 unsigned int irqn; 45 unsigned int irqn;
45}; 46};
46 47
48/*
49 * This hardware has a big endian bit assignment such that GPIO line 0 is
50 * connected to bit 31, line 1 to bit 30 ... line 31 to bit 0.
51 * This inline helper give the right bitmask for a certain line.
52 */
53static inline u32 mpc_pin2mask(unsigned int offset)
54{
55 return BIT(31 - offset);
56}
57
47/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs 58/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
48 * defined as output cannot be determined by reading GPDAT register, 59 * defined as output cannot be determined by reading GPDAT register,
49 * so we use shadow data register instead. The status of input pins 60 * 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 val = gc->read_reg(mpc8xxx_gc->regs + GPIO_DAT) & ~out_mask; 70 val = gc->read_reg(mpc8xxx_gc->regs + GPIO_DAT) & ~out_mask;
60 out_shadow = gc->bgpio_data & out_mask; 71 out_shadow = gc->bgpio_data & out_mask;
61 72
62 return !!((val | out_shadow) & gc->pin2mask(gc, gpio)); 73 return !!((val | out_shadow) & mpc_pin2mask(gpio));
63} 74}
64 75
65static int mpc5121_gpio_dir_out(struct gpio_chip *gc, 76static int mpc5121_gpio_dir_out(struct gpio_chip *gc,
@@ -120,7 +131,7 @@ static void mpc8xxx_irq_unmask(struct irq_data *d)
120 131
121 gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, 132 gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR,
122 gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR) 133 gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR)
123 | gc->pin2mask(gc, irqd_to_hwirq(d))); 134 | mpc_pin2mask(irqd_to_hwirq(d)));
124 135
125 raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); 136 raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
126} 137}
@@ -135,7 +146,7 @@ static void mpc8xxx_irq_mask(struct irq_data *d)
135 146
136 gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, 147 gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR,
137 gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR) 148 gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR)
138 & ~(gc->pin2mask(gc, irqd_to_hwirq(d)))); 149 & ~mpc_pin2mask(irqd_to_hwirq(d)));
139 150
140 raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); 151 raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
141} 152}
@@ -146,7 +157,7 @@ static void mpc8xxx_irq_ack(struct irq_data *d)
146 struct gpio_chip *gc = &mpc8xxx_gc->gc; 157 struct gpio_chip *gc = &mpc8xxx_gc->gc;
147 158
148 gc->write_reg(mpc8xxx_gc->regs + GPIO_IER, 159 gc->write_reg(mpc8xxx_gc->regs + GPIO_IER,
149 gc->pin2mask(gc, irqd_to_hwirq(d))); 160 mpc_pin2mask(irqd_to_hwirq(d)));
150} 161}
151 162
152static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) 163static 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 raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); 171 raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
161 gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR, 172 gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR,
162 gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR) 173 gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR)
163 | gc->pin2mask(gc, irqd_to_hwirq(d))); 174 | mpc_pin2mask(irqd_to_hwirq(d)));
164 raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); 175 raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
165 break; 176 break;
166 177
@@ -168,7 +179,7 @@ static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
168 raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); 179 raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
169 gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR, 180 gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR,
170 gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR) 181 gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR)
171 & ~(gc->pin2mask(gc, irqd_to_hwirq(d)))); 182 & ~mpc_pin2mask(irqd_to_hwirq(d)));
172 raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); 183 raw_spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
173 break; 184 break;
174 185