summaryrefslogtreecommitdiff
path: root/drivers/gpio/gpio-mmio.c
AgeCommit message (Collapse)Author
2020-07-16gpio: mmio: replace open-coded for_each_set_bit()Andy Shevchenko
Use for_each_set_bit() instead of open-coding it to simplify the code. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Link: https://lore.kernel.org/r/20200713154429.23662-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2020-03-25gpio: mmio: introduce BGPIOF_NO_SET_ON_INPUTChuanhong Guo
Some gpio controllers ignores pin value writing when that pin is configured as input mode. As a result, bgpio_dir_out should set pin to output before configuring pin values or gpio pin values can't be set up properly. Introduce two variants of bgpio_dir_out: bgpio_dir_out_val_first and bgpio_dir_out_dir_first, and assign direction_output according to a new flag: BGPIOF_NO_SET_ON_INPUT. Signed-off-by: Chuanhong Guo <gch981213@gmail.com> Tested-by: René van Dorst <opensource@vdorst.com> Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
2019-11-13gpio: mmio: remove untrue leftover commentMatti Vaittinen
The comment should have been removed when new GPIO direction definitions were taken in use as the function logic was changed. It is now perfectly valid and Ok to hit the return from the bottom of the direction getting function. Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
2019-11-07gpio: Use new GPIO_LINE_DIRECTIONMatti Vaittinen
It's hard for occasional GPIO code reader/writer to know if values 0/1 equal to IN or OUT. Use defined GPIO_LINE_DIRECTION_IN and GPIO_LINE_DIRECTION_OUT to help them out. NOTE - for gpio-amd-fch and gpio-bd9571mwv: This commit also changes the return value for direction get to equal 1 for direction INPUT. Prior this commit these drivers might have returned some other positive value but 1 for INPUT. Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> Acked-by: Scott Branden <scott.branden@broadcom.com> Reviewed-by: Grygorii Strashko <grygorii.strashko@ti.com> Reviewed-by: Michal Simek <michal.simek@xilinx.com> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Acked-by: William Breathitt Gray <vilhelm.gray@gmail.com> Acked-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2019-04-08gpio: mmio: Drop bgpio_dir_invertedLinus Walleij
The direction inversion semantics are now handled by simply using the registers for in/out available, no need to keep track of inversion semantics exmplicitly anymore. Reviewed-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: Jan Kotas <jank@cadence.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2019-04-05gpio: mmio: Fix bgpio_get_set & bgpio_get_set_multipleJan Kotas
During my regression testing I noticed the cadence GPIO driver fails on the latest gpio for-next tree. I think the reason is this patch: commit 96cd559817f2 ("Merge branch 'devel' into for-next") Here is a part of the test log: Loopback 8 -> 24 TESTING: gpio: 488: output direction PASSED TESTING: gpio: 504: input direction PASSED TESTING: gpio: 488: 0 PASSED TESTING: gpio: 488 -> 504: 0 PASSED TESTING: gpio: 488: 1 FAILED TESTING: gpio: 488 -> 504: 1 FAILED TESTING: gpio: 488: 0 PASSED TESTING: gpio: 488 -> 504: 0 PASSED It looks like the issue is that gc->bgpio_dir has changed its meaning. It used to be set to the register value (so it was being inverted). Now it's always set to 1 for output and 0 for input. However the bgpio_get_set functions were not updated. So they invert the bit again, which means a wrong register is being accessed. This patch fixes that by removing the unnecessary inversion. Signed-off-by: Jan Kotas <jank@cadence.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2019-04-05gpio: mmio: Support two direction registersLinus Walleij
It turns out that one specific hardware has two direction registers: one to set a GPIO line as input and another one to set a GPIO line as output. So in theory a line can be configured as input and output at the same time. Make the MMIO GPIO helper deal with this: store both registers in the state container, use both in the generic code if present. Synchronize the input register to the output register when we register a GPIO chip, with the output settings taking precedence. Keep the helper variable to detect inverted direction semantics (only direction in register) but augment the code to be more straight-forward for the generic case when setting the registers. Fix some flunky with unreadable direction registers at the same time as we're touching this code. Cc: David Woods <dwoods@mellanox.com> Cc: Shravan Kumar Ramani <sramani@mellanox.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2018-09-25gpio: Use SPDX header for core libraryLinus Walleij
Use the SPDX headers and cut down on boilerplate to indicate the license in the core gpiolib implementation. Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2018-08-10gpio: mmio: Fix up inverted direction registersLinus Walleij
The bgpio_init() takes one of two arguments to specify a register to set the direction of the GPIO line: either dirout that indicates that a 1 in the bit in that register sets the corresponding line to output, or dirin which indicates that a 1 in the bit in that register sets the corresponding line to input. Conversely setting the bit to 0 on these will turn the line into input and output respectively. One of these can be defined but not both. This means that a platform that sets a bit to 1 for output only defines dirout and a platform that sets a bit to 0 for output only defines dirin. In short this defines the polarity of the direction register. Both can also be left as NULL meaning the GPIO chip is either input only or output only. Tomer Maimon discovered that for get/set chips (those where the get and set registers are defined but no separate clear register, and specifying BGPIOF_READ_OUTPUT_REG_SET so that we say we want to read the output value from the SET register) we are unconditionally reading the value from the SET register when the direction bit is 1 and from the DAT register when the direction bit is 0, not taking the direction bit polarity into account. It would be expected that when the direction bit is inverted (dirin is defined but not dirout) we read the current value from the DAT register when the bit is 1 and from the SET register when the bit is 0. Currently only some versions of ATH79, brcmstb, some versions of CLP711x, GE, IOP and Loongson use the dirin mode (a 1 in the register means input). They are unaffected because BGPIOF_READ_OUTPUT_REG_SET is not set on any of them. (They do not read back the SET register to figure out the output value.) So this is no regression with current drivers. However the behaviour is wrong and does not work with Tomer's new driver where he needs to use the BGIOF_READ_OUTPUT_REG_SET. This fixes the above issue by: - Instead of defining separate functions for the inverted case, set up a flag in the gpio_chip that indicates that the direction is inverted. - Remove the special inverted functions for setting input/output and getting the direction, rely on the flag instead. - Respect this flag in bgpio_get_set() and bgpio_get_set_multiple() Reported-by: Tomer Maimon <tmaimon77@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2018-01-16gpio: mmio: Also read bits that are zeroLinus Walleij
The code for .get_multiple() has bugs: 1. The simple .get_multiple() just reads a register, masks it and sets the return value. This is not correct: we only want to assign values (whether 0 or 1) to the bits that are set in the mask. Fix this by using &= ~mask to clear all bits in the mask and then |= val & mask to set the corresponding bits from the read. 2. The bgpio_get_multiple_be() call has a similar problem: it uses the |= operator to set the bits, so only the bits in the mask are affected, but it misses to clear all returned bits from the mask initially, so some bits will be returned erroneously set to 1. 3. The bgpio_get_set_multiple() again fails to clear the bits from the mask. 4. find_next_bit() wasn't handled correctly, use a totally different approach for one function and change the other function to follow the design pattern of assigning the first bit to -1, then use bit + 1 in the for loop and < num_iterations as break condition. Fixes: 80057cb417b2 ("gpio-mmio: Use the new .get_multiple() callback") Cc: Bartosz Golaszewski <brgl@bgdev.pl> Reported-by: Clemens Gruber <clemens.gruber@pqgruber.com> Tested-by: Clemens Gruber <clemens.gruber@pqgruber.com> Reported-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2017-10-30gpio-mmio: Use the new .get_multiple() callbackLinus Walleij
It is possible to read all lines of a generic MMIO GPIO chip with a single register read so support this if we are in native endianness. Add an especially quirky callback to read multiple lines for the variants that require you to read values from the output registers if and only if the line is set as output. We managed to do that with a maximum of two register reads, and just one read if the requested lines are all input or all output. Cc: Anton Vorontsov <anton@enomsg.org> Cc: Lukas Wunner <lukas@wunner.de> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2017-10-25gpio: mmio: Make pin2mask() a private businessLinus Walleij
The vtable call pin2mask() was introducing a vtable function call in every gpiochip callback for a generic MMIO GPIO chip. This was not exactly efficient. (Maybe link-time optimization could get rid of it, I don't know.) After removing all external calls into this API we can make it a boolean flag in the struct gpio_chip call and sink the function into the gpio-mmio driver yielding encapsulation and potential speedups. Cc: Anton Vorontsov <anton@enomsg.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2017-03-23gpio: mmio: add support for NI 169445 NAND GPIONathan Sullivan
The GPIO-based NAND controller on National Instruments 169445 hardware exposes a set of simple lines for the control signals. Signed-off-by: Nathan Sullivan <nathan.sullivan@ni.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-08-11gpio: mmio: add brcm,bcm6345 supportChristian Lamparter
This patch adds support for the GPIO found in Broadcom's bcm63xx-gpio chips. This GPIO controller is used in the following Broadcom SoCs: BCM6338, BCM6345. It can be used in newer SoCs, without the capability of pin multiplexing. Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-06-08gpio: mmio: add MyBook Live GPIO supportChristian Lamparter
This patch adds support for the Western Digital's MyBook Live memory-mapped GPIO controllers. The GPIOs will be supported by the generic driver for memory-mapped GPIO controllers. Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Acked-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-06-08gpio: mmio: add DT support for memory-mapped GPIOsÁlvaro Fernández Rojas
This patch adds support for defining memory-mapped GPIOs which are compatible with the existing gpio-mmio interface. The generic library provides support for many memory-mapped GPIO controllers that are found in various on-board FPGA and ASIC solutions that are used to control board's switches, LEDs, chip-selects, Ethernet/USB PHY power, etc. For setting GPIOs there are three configurations: 1. single input/output register resource (named "dat"), 2. set/clear pair (named "set" and "clr"), 3. single output register resource and single input resource ("set" and dat"). The configuration is detected by which resources are present. For the single output register, this drives a 1 by setting a bit and a zero by clearing a bit. For the set clr pair, this drives a 1 by setting a bit in the set register and clears it by setting a bit in the clear register. For setting the GPIO direction, there are three configurations: a. simple bidirectional GPIOs that requires no configuration. b. an output direction register (named "dirout") where a 1 bit indicates the GPIO is an output. c. an input direction register (named "dirin") where a 1 bit indicates the GPIO is an input. Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Acked-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2016-04-29gpio: rename gpio-generic.c into gpio-mmio.cChristian Lamparter
This patch renames the gpio-generic.c into gpio-mmio.c. This is because currently the file only contains code for a memory-mapped GPIO driver. There isn't any support for ioports or other resource type. Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>