diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2017-10-20 10:08:12 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2017-10-25 05:25:40 -0400 |
commit | b3222f7147e028d31f965f193b6f995147c64651 (patch) | |
tree | 7f75b5c93892bc59543fed5adcc53e38da6fc502 | |
parent | d74423687f9d70417bfec68121cbd35f79bb170f (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.c | 23 |
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 | */ | ||
53 | static 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 | ||
65 | static int mpc5121_gpio_dir_out(struct gpio_chip *gc, | 76 | static 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 | ||
152 | static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) | 163 | 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 | 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 | ||