summaryrefslogtreecommitdiff
path: root/drivers/gpio/gpiolib.h
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2016-02-10 12:57:36 +0300
committerLinus Walleij <linus.walleij@linaro.org>2016-02-11 22:29:46 +0300
commitfdeb8e1547cb9dd39d5d7223b33f3565cf86c28e (patch)
tree65016a6cdaaa86565803c77f662c4b298c7b19f1 /drivers/gpio/gpiolib.h
parent6cee3821e4e4bd6e6cdf0870b6c72d455460bd39 (diff)
downloadlinux-fdeb8e1547cb9dd39d5d7223b33f3565cf86c28e.tar.xz
gpio: reflect base and ngpio into gpio_device
Some information about the GPIO chip need to stay around also after the gpio_chip has been removed and only the gpio_device persist. The base and ngpio are such things, for example we don't want a new chip arriving to overlap the number space of a dangling gpio_device, and the chardev may still query the device for the number of lines etc. Note that the code that assigns base and insert gpio_device into the global list no longer check for a missing gpio_chip: we respect the number space allocated by any other gpio_device. As a consequence of the gdev being referenced directly from the gpio_desc, we need to verify it differently from all in-kernel API calls that fall through to direct queries to the gpio_chip vtable: we first check that desc is !NULL, then that desc->gdev is !NULL, then, if desc->gdev->chip is NULL, we *BAIL OUT* without any error, so as to manage the case where operations are requested on a device that is gone. These checks were non-uniform and partly missing in the past: so to simplify: create the macros VALIDATE_DESC() that will return -EINVAL if the desc or desc->gdev is missing and just 0 if the chip is gone, and conversely VALIDATE_DESC_VOID() for the case where the function does not return an error. By using these macros, we get warning messages about missing gdev with reference to the right function in the kernel log. Despite the macro business this simplifies the code and make it more readable than if we copy/paste the same descriptor checking code into all code ABI call sites (IMHO). Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpiolib.h')
-rw-r--r--drivers/gpio/gpiolib.h10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 39b8301c98b6..d154984c71d9 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -33,6 +33,10 @@ struct acpi_device;
* @chip: pointer to the corresponding gpiochip, holding static
* data for this device
* @descs: array of ngpio descriptors.
+ * @ngpio: the number of GPIO lines on this GPIO device, equal to the size
+ * of the @descs array.
+ * @base: GPIO base in the DEPRECATED global Linux GPIO numberspace, assigned
+ * at device creation time.
* @list: links gpio_device:s together for traversal
*
* This state container holds most of the runtime variable data
@@ -48,6 +52,8 @@ struct gpio_device {
struct module *owner;
struct gpio_chip *chip;
struct gpio_desc *descs;
+ int base;
+ u16 ngpio;
struct list_head list;
};
@@ -125,7 +131,7 @@ extern struct spinlock gpio_lock;
extern struct list_head gpio_devices;
struct gpio_desc {
- struct gpio_chip *chip;
+ struct gpio_device *gdev;
unsigned long flags;
/* flag symbols are bit numbers */
#define FLAG_REQUESTED 0
@@ -154,7 +160,7 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
*/
static int __maybe_unused gpio_chip_hwgpio(const struct gpio_desc *desc)
{
- return desc - &desc->chip->gpiodev->descs[0];
+ return desc - &desc->gdev->descs[0];
}
/* With descriptor prefix */