summaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-mmio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpio-mmio.c')
-rw-r--r--drivers/gpio/gpio-mmio.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c
index f9042bcc27a4..7b14d6280e44 100644
--- a/drivers/gpio/gpio-mmio.c
+++ b/drivers/gpio/gpio-mmio.c
@@ -152,14 +152,13 @@ static int bgpio_get_set_multiple(struct gpio_chip *gc, unsigned long *mask,
152{ 152{
153 unsigned long get_mask = 0; 153 unsigned long get_mask = 0;
154 unsigned long set_mask = 0; 154 unsigned long set_mask = 0;
155 int bit = 0;
156 155
157 while ((bit = find_next_bit(mask, gc->ngpio, bit)) != gc->ngpio) { 156 /* Make sure we first clear any bits that are zero when we read the register */
158 if (gc->bgpio_dir & BIT(bit)) 157 *bits &= ~*mask;
159 set_mask |= BIT(bit); 158
160 else 159 /* Exploit the fact that we know which directions are set */
161 get_mask |= BIT(bit); 160 set_mask = *mask & gc->bgpio_dir;
162 } 161 get_mask = *mask & ~gc->bgpio_dir;
163 162
164 if (set_mask) 163 if (set_mask)
165 *bits |= gc->read_reg(gc->reg_set) & set_mask; 164 *bits |= gc->read_reg(gc->reg_set) & set_mask;
@@ -176,13 +175,13 @@ static int bgpio_get(struct gpio_chip *gc, unsigned int gpio)
176 175
177/* 176/*
178 * This only works if the bits in the GPIO register are in native endianness. 177 * This only works if the bits in the GPIO register are in native endianness.
179 * It is dirt simple and fast in this case. (Also the most common case.)
180 */ 178 */
181static int bgpio_get_multiple(struct gpio_chip *gc, unsigned long *mask, 179static int bgpio_get_multiple(struct gpio_chip *gc, unsigned long *mask,
182 unsigned long *bits) 180 unsigned long *bits)
183{ 181{
184 182 /* Make sure we first clear any bits that are zero when we read the register */
185 *bits = gc->read_reg(gc->reg_dat) & *mask; 183 *bits &= ~*mask;
184 *bits |= gc->read_reg(gc->reg_dat) & *mask;
186 return 0; 185 return 0;
187} 186}
188 187
@@ -196,9 +195,12 @@ static int bgpio_get_multiple_be(struct gpio_chip *gc, unsigned long *mask,
196 unsigned long val; 195 unsigned long val;
197 int bit; 196 int bit;
198 197
198 /* Make sure we first clear any bits that are zero when we read the register */
199 *bits &= ~*mask;
200
199 /* Create a mirrored mask */ 201 /* Create a mirrored mask */
200 bit = 0; 202 bit = -1;
201 while ((bit = find_next_bit(mask, gc->ngpio, bit)) != gc->ngpio) 203 while ((bit = find_next_bit(mask, gc->ngpio, bit + 1)) < gc->ngpio)
202 readmask |= bgpio_line2mask(gc, bit); 204 readmask |= bgpio_line2mask(gc, bit);
203 205
204 /* Read the register */ 206 /* Read the register */
@@ -208,8 +210,8 @@ static int bgpio_get_multiple_be(struct gpio_chip *gc, unsigned long *mask,
208 * Mirror the result into the "bits" result, this will give line 0 210 * Mirror the result into the "bits" result, this will give line 0
209 * in bit 0 ... line 31 in bit 31 for a 32bit register. 211 * in bit 0 ... line 31 in bit 31 for a 32bit register.
210 */ 212 */
211 bit = 0; 213 bit = -1;
212 while ((bit = find_next_bit(&val, gc->ngpio, bit)) != gc->ngpio) 214 while ((bit = find_next_bit(&val, gc->ngpio, bit + 1)) < gc->ngpio)
213 *bits |= bgpio_line2mask(gc, bit); 215 *bits |= bgpio_line2mask(gc, bit);
214 216
215 return 0; 217 return 0;