aboutsummaryrefslogtreecommitdiffstats
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.c130
1 files changed, 102 insertions, 28 deletions
diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c
index f7da40e46c55..f9042bcc27a4 100644
--- a/drivers/gpio/gpio-mmio.c
+++ b/drivers/gpio/gpio-mmio.c
@@ -126,20 +126,16 @@ static unsigned long bgpio_read32be(void __iomem *reg)
126 return ioread32be(reg); 126 return ioread32be(reg);
127} 127}
128 128
129static unsigned long bgpio_pin2mask(struct gpio_chip *gc, unsigned int pin) 129static unsigned long bgpio_line2mask(struct gpio_chip *gc, unsigned int line)
130{ 130{
131 return BIT(pin); 131 if (gc->be_bits)
132} 132 return BIT(gc->bgpio_bits - 1 - line);
133 133 return BIT(line);
134static unsigned long bgpio_pin2mask_be(struct gpio_chip *gc,
135 unsigned int pin)
136{
137 return BIT(gc->bgpio_bits - 1 - pin);
138} 134}
139 135
140static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio) 136static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio)
141{ 137{
142 unsigned long pinmask = gc->pin2mask(gc, gpio); 138 unsigned long pinmask = bgpio_line2mask(gc, gpio);
143 139
144 if (gc->bgpio_dir & pinmask) 140 if (gc->bgpio_dir & pinmask)
145 return !!(gc->read_reg(gc->reg_set) & pinmask); 141 return !!(gc->read_reg(gc->reg_set) & pinmask);
@@ -147,9 +143,76 @@ static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio)
147 return !!(gc->read_reg(gc->reg_dat) & pinmask); 143 return !!(gc->read_reg(gc->reg_dat) & pinmask);
148} 144}
149 145
146/*
147 * This assumes that the bits in the GPIO register are in native endianness.
148 * We only assign the function pointer if we have that.
149 */
150static int bgpio_get_set_multiple(struct gpio_chip *gc, unsigned long *mask,
151 unsigned long *bits)
152{
153 unsigned long get_mask = 0;
154 unsigned long set_mask = 0;
155 int bit = 0;
156
157 while ((bit = find_next_bit(mask, gc->ngpio, bit)) != gc->ngpio) {
158 if (gc->bgpio_dir & BIT(bit))
159 set_mask |= BIT(bit);
160 else
161 get_mask |= BIT(bit);
162 }
163
164 if (set_mask)
165 *bits |= gc->read_reg(gc->reg_set) & set_mask;
166 if (get_mask)
167 *bits |= gc->read_reg(gc->reg_dat) & get_mask;
168
169 return 0;
170}
171
150static int bgpio_get(struct gpio_chip *gc, unsigned int gpio) 172static int bgpio_get(struct gpio_chip *gc, unsigned int gpio)
151{ 173{
152 return !!(gc->read_reg(gc->reg_dat) & gc->pin2mask(gc, gpio)); 174 return !!(gc->read_reg(gc->reg_dat) & bgpio_line2mask(gc, gpio));
175}
176
177/*
178 * 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 */
181static int bgpio_get_multiple(struct gpio_chip *gc, unsigned long *mask,
182 unsigned long *bits)
183{
184
185 *bits = gc->read_reg(gc->reg_dat) & *mask;
186 return 0;
187}
188
189/*
190 * With big endian mirrored bit order it becomes more tedious.
191 */
192static int bgpio_get_multiple_be(struct gpio_chip *gc, unsigned long *mask,
193 unsigned long *bits)
194{
195 unsigned long readmask = 0;
196 unsigned long val;
197 int bit;
198
199 /* Create a mirrored mask */
200 bit = 0;
201 while ((bit = find_next_bit(mask, gc->ngpio, bit)) != gc->ngpio)
202 readmask |= bgpio_line2mask(gc, bit);
203
204 /* Read the register */
205 val = gc->read_reg(gc->reg_dat) & readmask;
206
207 /*
208 * 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.
210 */
211 bit = 0;
212 while ((bit = find_next_bit(&val, gc->ngpio, bit)) != gc->ngpio)
213 *bits |= bgpio_line2mask(gc, bit);
214
215 return 0;
153} 216}
154 217
155static void bgpio_set_none(struct gpio_chip *gc, unsigned int gpio, int val) 218static void bgpio_set_none(struct gpio_chip *gc, unsigned int gpio, int val)
@@ -158,7 +221,7 @@ static void bgpio_set_none(struct gpio_chip *gc, unsigned int gpio, int val)
158 221
159static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) 222static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
160{ 223{
161 unsigned long mask = gc->pin2mask(gc, gpio); 224 unsigned long mask = bgpio_line2mask(gc, gpio);
162 unsigned long flags; 225 unsigned long flags;
163 226
164 spin_lock_irqsave(&gc->bgpio_lock, flags); 227 spin_lock_irqsave(&gc->bgpio_lock, flags);
@@ -176,7 +239,7 @@ static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
176static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio, 239static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio,
177 int val) 240 int val)
178{ 241{
179 unsigned long mask = gc->pin2mask(gc, gpio); 242 unsigned long mask = bgpio_line2mask(gc, gpio);
180 243
181 if (val) 244 if (val)
182 gc->write_reg(gc->reg_set, mask); 245 gc->write_reg(gc->reg_set, mask);
@@ -186,7 +249,7 @@ static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio,
186 249
187static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val) 250static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val)
188{ 251{
189 unsigned long mask = gc->pin2mask(gc, gpio); 252 unsigned long mask = bgpio_line2mask(gc, gpio);
190 unsigned long flags; 253 unsigned long flags;
191 254
192 spin_lock_irqsave(&gc->bgpio_lock, flags); 255 spin_lock_irqsave(&gc->bgpio_lock, flags);
@@ -216,9 +279,9 @@ static void bgpio_multiple_get_masks(struct gpio_chip *gc,
216 break; 279 break;
217 if (__test_and_clear_bit(i, mask)) { 280 if (__test_and_clear_bit(i, mask)) {
218 if (test_bit(i, bits)) 281 if (test_bit(i, bits))
219 *set_mask |= gc->pin2mask(gc, i); 282 *set_mask |= bgpio_line2mask(gc, i);
220 else 283 else
221 *clear_mask |= gc->pin2mask(gc, i); 284 *clear_mask |= bgpio_line2mask(gc, i);
222 } 285 }
223 } 286 }
224} 287}
@@ -294,7 +357,7 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
294 357
295 spin_lock_irqsave(&gc->bgpio_lock, flags); 358 spin_lock_irqsave(&gc->bgpio_lock, flags);
296 359
297 gc->bgpio_dir &= ~gc->pin2mask(gc, gpio); 360 gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio);
298 gc->write_reg(gc->reg_dir, gc->bgpio_dir); 361 gc->write_reg(gc->reg_dir, gc->bgpio_dir);
299 362
300 spin_unlock_irqrestore(&gc->bgpio_lock, flags); 363 spin_unlock_irqrestore(&gc->bgpio_lock, flags);
@@ -305,7 +368,7 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
305static int bgpio_get_dir(struct gpio_chip *gc, unsigned int gpio) 368static int bgpio_get_dir(struct gpio_chip *gc, unsigned int gpio)
306{ 369{
307 /* Return 0 if output, 1 of input */ 370 /* Return 0 if output, 1 of input */
308 return !(gc->read_reg(gc->reg_dir) & gc->pin2mask(gc, gpio)); 371 return !(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio));
309} 372}
310 373
311static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) 374static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
@@ -316,7 +379,7 @@ static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
316 379
317 spin_lock_irqsave(&gc->bgpio_lock, flags); 380 spin_lock_irqsave(&gc->bgpio_lock, flags);
318 381
319 gc->bgpio_dir |= gc->pin2mask(gc, gpio); 382 gc->bgpio_dir |= bgpio_line2mask(gc, gpio);
320 gc->write_reg(gc->reg_dir, gc->bgpio_dir); 383 gc->write_reg(gc->reg_dir, gc->bgpio_dir);
321 384
322 spin_unlock_irqrestore(&gc->bgpio_lock, flags); 385 spin_unlock_irqrestore(&gc->bgpio_lock, flags);
@@ -330,7 +393,7 @@ static int bgpio_dir_in_inv(struct gpio_chip *gc, unsigned int gpio)
330 393
331 spin_lock_irqsave(&gc->bgpio_lock, flags); 394 spin_lock_irqsave(&gc->bgpio_lock, flags);
332 395
333 gc->bgpio_dir |= gc->pin2mask(gc, gpio); 396 gc->bgpio_dir |= bgpio_line2mask(gc, gpio);
334 gc->write_reg(gc->reg_dir, gc->bgpio_dir); 397 gc->write_reg(gc->reg_dir, gc->bgpio_dir);
335 398
336 spin_unlock_irqrestore(&gc->bgpio_lock, flags); 399 spin_unlock_irqrestore(&gc->bgpio_lock, flags);
@@ -346,7 +409,7 @@ static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val)
346 409
347 spin_lock_irqsave(&gc->bgpio_lock, flags); 410 spin_lock_irqsave(&gc->bgpio_lock, flags);
348 411
349 gc->bgpio_dir &= ~gc->pin2mask(gc, gpio); 412 gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio);
350 gc->write_reg(gc->reg_dir, gc->bgpio_dir); 413 gc->write_reg(gc->reg_dir, gc->bgpio_dir);
351 414
352 spin_unlock_irqrestore(&gc->bgpio_lock, flags); 415 spin_unlock_irqrestore(&gc->bgpio_lock, flags);
@@ -357,12 +420,11 @@ static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val)
357static int bgpio_get_dir_inv(struct gpio_chip *gc, unsigned int gpio) 420static int bgpio_get_dir_inv(struct gpio_chip *gc, unsigned int gpio)
358{ 421{
359 /* Return 0 if output, 1 if input */ 422 /* Return 0 if output, 1 if input */
360 return !!(gc->read_reg(gc->reg_dir) & gc->pin2mask(gc, gpio)); 423 return !!(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio));
361} 424}
362 425
363static int bgpio_setup_accessors(struct device *dev, 426static int bgpio_setup_accessors(struct device *dev,
364 struct gpio_chip *gc, 427 struct gpio_chip *gc,
365 bool bit_be,
366 bool byte_be) 428 bool byte_be)
367{ 429{
368 430
@@ -406,8 +468,6 @@ static int bgpio_setup_accessors(struct device *dev,
406 return -EINVAL; 468 return -EINVAL;
407 } 469 }
408 470
409 gc->pin2mask = bit_be ? bgpio_pin2mask_be : bgpio_pin2mask;
410
411 return 0; 471 return 0;
412} 472}
413 473
@@ -462,10 +522,24 @@ static int bgpio_setup_io(struct gpio_chip *gc,
462 } 522 }
463 523
464 if (!(flags & BGPIOF_UNREADABLE_REG_SET) && 524 if (!(flags & BGPIOF_UNREADABLE_REG_SET) &&
465 (flags & BGPIOF_READ_OUTPUT_REG_SET)) 525 (flags & BGPIOF_READ_OUTPUT_REG_SET)) {
466 gc->get = bgpio_get_set; 526 gc->get = bgpio_get_set;
467 else 527 if (!gc->be_bits)
528 gc->get_multiple = bgpio_get_set_multiple;
529 /*
530 * We deliberately avoid assigning the ->get_multiple() call
531 * for big endian mirrored registers which are ALSO reflecting
532 * their value in the set register when used as output. It is
533 * simply too much complexity, let the GPIO core fall back to
534 * reading each line individually in that fringe case.
535 */
536 } else {
468 gc->get = bgpio_get; 537 gc->get = bgpio_get;
538 if (gc->be_bits)
539 gc->get_multiple = bgpio_get_multiple_be;
540 else
541 gc->get_multiple = bgpio_get_multiple;
542 }
469 543
470 return 0; 544 return 0;
471} 545}
@@ -526,13 +600,13 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev,
526 gc->base = -1; 600 gc->base = -1;
527 gc->ngpio = gc->bgpio_bits; 601 gc->ngpio = gc->bgpio_bits;
528 gc->request = bgpio_request; 602 gc->request = bgpio_request;
603 gc->be_bits = !!(flags & BGPIOF_BIG_ENDIAN);
529 604
530 ret = bgpio_setup_io(gc, dat, set, clr, flags); 605 ret = bgpio_setup_io(gc, dat, set, clr, flags);
531 if (ret) 606 if (ret)
532 return ret; 607 return ret;
533 608
534 ret = bgpio_setup_accessors(dev, gc, flags & BGPIOF_BIG_ENDIAN, 609 ret = bgpio_setup_accessors(dev, gc, flags & BGPIOF_BIG_ENDIAN_BYTE_ORDER);
535 flags & BGPIOF_BIG_ENDIAN_BYTE_ORDER);
536 if (ret) 610 if (ret)
537 return ret; 611 return ret;
538 612