aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-mmio.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-08-16 00:35:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-16 00:35:38 -0400
commit6de4c691eab8f421e34c5250f63bf3f477d30eec (patch)
treedd3deaa163bb478b13778a712afdfccc8cf43f20 /drivers/gpio/gpio-mmio.c
parentc1c2ad82c772966d3cdb9a4852329fa2cf71853a (diff)
parenta5ec96ddfd55c501d451cb310566a1170c267ecb (diff)
Merge tag 'gpio-v4.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio
Pull GPIO updates from Linus Walleij: "This is the bulk of GPIO changes for the v4.19 kernel cycle. I don't know if anything in particular stands out. Maybe the Aspeed coprocessor thing from Benji: Aspeed is doing baseboard management chips (BMC's) for servers etc. These Aspeed's are ARM processors that exist inside (I guess) Intel servers, and they are moving forward to using mainline Linux in those. This is one of the pieces of the puzzle to achive that. They are doing OpenBMC, it's pretty cool: https://lwn.net/Articles/683320/ Summary: Core changes: - Add a new API for explicitly naming GPIO consumers, when needed. - Don't let userspace set values on input lines. While we do not think anyone would do this crazy thing we better plug the hole before someone uses it and think it's a nifty feature. - Avoid calling chip->request() for unused GPIOs. New drivers/subdrivers: - The Mediatek MT7621 is supported which is a big win for OpenWRT and similar router distributions using this chip, as it seems every major router manufacturer on the planet has made products using this chip: https://wikidevi.com/wiki/MediaTek_MT7621 - The Tegra 194 is now supported. - The IT87 driver now supports IT8786E and IT8718F super-IO chips. - Add support for Rockchip RK3328 in the syscon GPIO driver. Driver changes: - Handle the get/set_multiple() properly on MMIO chips with inverted direction registers. We didn't have this problem until a new chip appear that has get/set registers AND inverted direction bits, OK now we handle it. - A patch series making more error codes percolate upward properly for different errors on gpiochip_lock_as_irq(). - Get/set multiple for the OMAP driver, accelerating these multiple line operations if possible. - A coprocessor interface for the Aspeed driver. Sometimes a few GPIO lines need to be grabbed by a co-processor for doing automated tasks, sometimes they are available as GPIO lines. By adding an explicit API in this driver we make it possible for the two line consumers to coexist. (This work was made available on the ib-aspeed branch, which may be appearing in other pull requests.) - Implemented .get_direction() and open drain in the SCH311x driver. - Continuing cleanup of included headers in GPIO drivers" * tag 'gpio-v4.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (80 commits) gpio: it87: Add support for IT8613 gpio: it87: add support for IT8718F Super I/O. gpiolib: Avoid calling chip->request() for unused gpios gpio: tegra: Include the right header gpio: mmio: Fix up inverted direction registers gpio: xilinx: Use the right include gpio: timberdale: Include the right header gpio: tb10x: Use the right include gpiolib: Fix of_node inconsistency gpio: vr41xx: Bail out on gpiochip_lock_as_irq() error gpio: uniphier: Bail out on gpiochip_lock_as_irq() error gpio: xgene-sb: Don't shadow error code of gpiochip_lock_as_irq() gpio: em: Don't shadow error code of gpiochip_lock_as_irq() gpio: dwapb: Don't shadow error code of gpiochip_lock_as_irq() gpio: bcm-kona: Don't shadow error code of gpiochip_lock_as_irq() gpiolib: Don't shadow error code of gpiochip_lock_as_irq() gpio: syscon: rockchip: add GRF GPIO support for rk3328 gpio: omap: Add get/set_multiple() callbacks gpio: pxa: remove set but not used variable 'gpio_offset' gpio-it87: add support for IT8786E Super I/O ...
Diffstat (limited to 'drivers/gpio/gpio-mmio.c')
-rw-r--r--drivers/gpio/gpio-mmio.c108
1 files changed, 63 insertions, 45 deletions
diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c
index 7b14d6280e44..935292a30c99 100644
--- a/drivers/gpio/gpio-mmio.c
+++ b/drivers/gpio/gpio-mmio.c
@@ -136,8 +136,20 @@ static unsigned long bgpio_line2mask(struct gpio_chip *gc, unsigned int line)
136static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio) 136static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio)
137{ 137{
138 unsigned long pinmask = bgpio_line2mask(gc, gpio); 138 unsigned long pinmask = bgpio_line2mask(gc, gpio);
139 bool dir = !!(gc->bgpio_dir & pinmask);
139 140
140 if (gc->bgpio_dir & pinmask) 141 /*
142 * If the direction is OUT we read the value from the SET
143 * register, and if the direction is IN we read the value
144 * from the DAT register.
145 *
146 * If the direction bits are inverted, naturally this gets
147 * inverted too.
148 */
149 if (gc->bgpio_dir_inverted)
150 dir = !dir;
151
152 if (dir)
141 return !!(gc->read_reg(gc->reg_set) & pinmask); 153 return !!(gc->read_reg(gc->reg_set) & pinmask);
142 else 154 else
143 return !!(gc->read_reg(gc->reg_dat) & pinmask); 155 return !!(gc->read_reg(gc->reg_dat) & pinmask);
@@ -157,8 +169,13 @@ static int bgpio_get_set_multiple(struct gpio_chip *gc, unsigned long *mask,
157 *bits &= ~*mask; 169 *bits &= ~*mask;
158 170
159 /* Exploit the fact that we know which directions are set */ 171 /* Exploit the fact that we know which directions are set */
160 set_mask = *mask & gc->bgpio_dir; 172 if (gc->bgpio_dir_inverted) {
161 get_mask = *mask & ~gc->bgpio_dir; 173 set_mask = *mask & ~gc->bgpio_dir;
174 get_mask = *mask & gc->bgpio_dir;
175 } else {
176 set_mask = *mask & gc->bgpio_dir;
177 get_mask = *mask & ~gc->bgpio_dir;
178 }
162 179
163 if (set_mask) 180 if (set_mask)
164 *bits |= gc->read_reg(gc->reg_set) & set_mask; 181 *bits |= gc->read_reg(gc->reg_set) & set_mask;
@@ -359,7 +376,10 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
359 376
360 spin_lock_irqsave(&gc->bgpio_lock, flags); 377 spin_lock_irqsave(&gc->bgpio_lock, flags);
361 378
362 gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio); 379 if (gc->bgpio_dir_inverted)
380 gc->bgpio_dir |= bgpio_line2mask(gc, gpio);
381 else
382 gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio);
363 gc->write_reg(gc->reg_dir, gc->bgpio_dir); 383 gc->write_reg(gc->reg_dir, gc->bgpio_dir);
364 384
365 spin_unlock_irqrestore(&gc->bgpio_lock, flags); 385 spin_unlock_irqrestore(&gc->bgpio_lock, flags);
@@ -370,7 +390,10 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
370static int bgpio_get_dir(struct gpio_chip *gc, unsigned int gpio) 390static int bgpio_get_dir(struct gpio_chip *gc, unsigned int gpio)
371{ 391{
372 /* Return 0 if output, 1 of input */ 392 /* Return 0 if output, 1 of input */
373 return !(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio)); 393 if (gc->bgpio_dir_inverted)
394 return !!(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio));
395 else
396 return !(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio));
374} 397}
375 398
376static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) 399static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
@@ -381,37 +404,10 @@ static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
381 404
382 spin_lock_irqsave(&gc->bgpio_lock, flags); 405 spin_lock_irqsave(&gc->bgpio_lock, flags);
383 406
384 gc->bgpio_dir |= bgpio_line2mask(gc, gpio); 407 if (gc->bgpio_dir_inverted)
385 gc->write_reg(gc->reg_dir, gc->bgpio_dir); 408 gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio);
386 409 else
387 spin_unlock_irqrestore(&gc->bgpio_lock, flags); 410 gc->bgpio_dir |= bgpio_line2mask(gc, gpio);
388
389 return 0;
390}
391
392static int bgpio_dir_in_inv(struct gpio_chip *gc, unsigned int gpio)
393{
394 unsigned long flags;
395
396 spin_lock_irqsave(&gc->bgpio_lock, flags);
397
398 gc->bgpio_dir |= bgpio_line2mask(gc, gpio);
399 gc->write_reg(gc->reg_dir, gc->bgpio_dir);
400
401 spin_unlock_irqrestore(&gc->bgpio_lock, flags);
402
403 return 0;
404}
405
406static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val)
407{
408 unsigned long flags;
409
410 gc->set(gc, gpio, val);
411
412 spin_lock_irqsave(&gc->bgpio_lock, flags);
413
414 gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio);
415 gc->write_reg(gc->reg_dir, gc->bgpio_dir); 411 gc->write_reg(gc->reg_dir, gc->bgpio_dir);
416 412
417 spin_unlock_irqrestore(&gc->bgpio_lock, flags); 413 spin_unlock_irqrestore(&gc->bgpio_lock, flags);
@@ -419,12 +415,6 @@ static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val)
419 return 0; 415 return 0;
420} 416}
421 417
422static int bgpio_get_dir_inv(struct gpio_chip *gc, unsigned int gpio)
423{
424 /* Return 0 if output, 1 if input */
425 return !!(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio));
426}
427
428static int bgpio_setup_accessors(struct device *dev, 418static int bgpio_setup_accessors(struct device *dev,
429 struct gpio_chip *gc, 419 struct gpio_chip *gc,
430 bool byte_be) 420 bool byte_be)
@@ -560,9 +550,10 @@ static int bgpio_setup_direction(struct gpio_chip *gc,
560 gc->get_direction = bgpio_get_dir; 550 gc->get_direction = bgpio_get_dir;
561 } else if (dirin) { 551 } else if (dirin) {
562 gc->reg_dir = dirin; 552 gc->reg_dir = dirin;
563 gc->direction_output = bgpio_dir_out_inv; 553 gc->direction_output = bgpio_dir_out;
564 gc->direction_input = bgpio_dir_in_inv; 554 gc->direction_input = bgpio_dir_in;
565 gc->get_direction = bgpio_get_dir_inv; 555 gc->get_direction = bgpio_get_dir;
556 gc->bgpio_dir_inverted = true;
566 } else { 557 } else {
567 if (flags & BGPIOF_NO_OUTPUT) 558 if (flags & BGPIOF_NO_OUTPUT)
568 gc->direction_output = bgpio_dir_out_err; 559 gc->direction_output = bgpio_dir_out_err;
@@ -582,6 +573,33 @@ static int bgpio_request(struct gpio_chip *chip, unsigned gpio_pin)
582 return -EINVAL; 573 return -EINVAL;
583} 574}
584 575
576/**
577 * bgpio_init() - Initialize generic GPIO accessor functions
578 * @gc: the GPIO chip to set up
579 * @dev: the parent device of the new GPIO chip (compulsory)
580 * @sz: the size (width) of the MMIO registers in bytes, typically 1, 2 or 4
581 * @dat: MMIO address for the register to READ the value of the GPIO lines, it
582 * is expected that a 1 in the corresponding bit in this register means the
583 * line is asserted
584 * @set: MMIO address for the register to SET the value of the GPIO lines, it is
585 * expected that we write the line with 1 in this register to drive the GPIO line
586 * high.
587 * @clr: MMIO address for the register to CLEAR the value of the GPIO lines, it is
588 * expected that we write the line with 1 in this register to drive the GPIO line
589 * low. It is allowed to leave this address as NULL, in that case the SET register
590 * will be assumed to also clear the GPIO lines, by actively writing the line
591 * with 0.
592 * @dirout: MMIO address for the register to set the line as OUTPUT. It is assumed
593 * that setting a line to 1 in this register will turn that line into an
594 * output line. Conversely, setting the line to 0 will turn that line into
595 * an input. Either this or @dirin can be defined, but never both.
596 * @dirin: MMIO address for the register to set this line as INPUT. It is assumed
597 * that setting a line to 1 in this register will turn that line into an
598 * input line. Conversely, setting the line to 0 will turn that line into
599 * an output. Either this or @dirout can be defined, but never both.
600 * @flags: Different flags that will affect the behaviour of the device, such as
601 * endianness etc.
602 */
585int bgpio_init(struct gpio_chip *gc, struct device *dev, 603int bgpio_init(struct gpio_chip *gc, struct device *dev,
586 unsigned long sz, void __iomem *dat, void __iomem *set, 604 unsigned long sz, void __iomem *dat, void __iomem *set,
587 void __iomem *clr, void __iomem *dirout, void __iomem *dirin, 605 void __iomem *clr, void __iomem *dirout, void __iomem *dirin,