2014-01-08 17:40:54 +07:00
|
|
|
/*
|
|
|
|
* Internal GPIO functions.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013, Intel Corporation
|
|
|
|
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef GPIOLIB_H
|
|
|
|
#define GPIOLIB_H
|
|
|
|
|
2015-10-20 16:10:38 +07:00
|
|
|
#include <linux/gpio/driver.h>
|
2018-02-08 23:57:43 +07:00
|
|
|
#include <linux/gpio/consumer.h> /* for enum gpiod_flags */
|
2014-01-08 17:40:56 +07:00
|
|
|
#include <linux/err.h>
|
|
|
|
#include <linux/device.h>
|
2015-10-20 16:10:38 +07:00
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/cdev.h>
|
2014-01-08 17:40:56 +07:00
|
|
|
|
2014-05-17 12:54:50 +07:00
|
|
|
enum of_gpio_flags;
|
2016-10-03 15:09:40 +07:00
|
|
|
enum gpio_lookup_flags;
|
2015-03-17 05:49:03 +07:00
|
|
|
struct acpi_device;
|
|
|
|
|
2015-10-20 16:10:38 +07:00
|
|
|
/**
|
|
|
|
* struct gpio_device - internal state container for GPIO devices
|
|
|
|
* @id: numerical ID number for the GPIO chip
|
|
|
|
* @dev: the GPIO device struct
|
gpio: add a userspace chardev ABI for GPIOs
A new chardev that is to be used for userspace GPIO access is
added in this patch. It is intended to gradually replace the
horribly broken sysfs ABI.
Using a chardev has many upsides:
- All operations are per-gpiochip, which is the actual
device underlying the GPIOs, making us tie in to the
kernel device model properly.
- Hotpluggable GPIO controllers can come and go, as this
kind of problem has been know to userspace for character
devices since ages, and if a gpiochip handle is held in
userspace we know we will break something, whereas the
sysfs is stateless.
- The one-value-per-file rule of sysfs is really hard to
maintain when you want to twist more than one knob at a time,
for example have in-kernel APIs to switch several GPIO
lines at the same time, and this will be possible to do
with a single ioctl() from userspace, saving a lot of
context switching.
We also need to add a new bus type for GPIO. This is
necessary for example for userspace coldplug, where sysfs is
traversed to find the boot-time device nodes and create the
character devices in /dev.
This new chardev ABI is *non* *optional* and can be counted
on to be present in the future, emphasizing the preference
of this ABI.
The ABI only implements one single ioctl() to get the name
and number of GPIO lines of a chip. Even this is debatable:
see it as a minimal example for review. This ABI shall be
ruthlessly reviewed and etched in stone.
The old /sys/class/gpio is still optional to compile in,
but will be deprecated.
Unique device IDs are created using IDR, which is overkill
and insanely scalable, but also well tested.
Cc: Johan Hovold <johan@kernel.org>
Cc: Michael Welling <mwelling@ieee.org>
Cc: Markus Pargmann <mpa@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-10-21 20:29:53 +07:00
|
|
|
* @chrdev: character device for the GPIO device
|
2016-02-09 19:21:06 +07:00
|
|
|
* @mockdev: class device used by the deprecated sysfs interface (may be
|
|
|
|
* NULL)
|
2015-10-20 16:10:38 +07:00
|
|
|
* @owner: helps prevent removal of modules exporting active GPIOs
|
|
|
|
* @chip: pointer to the corresponding gpiochip, holding static
|
|
|
|
* data for this device
|
2016-02-09 19:51:59 +07:00
|
|
|
* @descs: array of ngpio descriptors.
|
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>
2016-02-10 16:57:36 +07:00
|
|
|
* @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.
|
2016-02-12 20:48:23 +07:00
|
|
|
* @label: a descriptive name for the GPIO device, such as the part number
|
|
|
|
* or name of the IP component in a System on Chip.
|
2016-02-11 17:37:48 +07:00
|
|
|
* @data: per-instance data assigned by the driver
|
2015-10-20 16:10:38 +07:00
|
|
|
* @list: links gpio_device:s together for traversal
|
|
|
|
*
|
|
|
|
* This state container holds most of the runtime variable data
|
|
|
|
* for a GPIO device and can hold references and live on after the
|
|
|
|
* GPIO chip has been removed, if it is still being used from
|
|
|
|
* userspace.
|
|
|
|
*/
|
|
|
|
struct gpio_device {
|
|
|
|
int id;
|
|
|
|
struct device dev;
|
gpio: add a userspace chardev ABI for GPIOs
A new chardev that is to be used for userspace GPIO access is
added in this patch. It is intended to gradually replace the
horribly broken sysfs ABI.
Using a chardev has many upsides:
- All operations are per-gpiochip, which is the actual
device underlying the GPIOs, making us tie in to the
kernel device model properly.
- Hotpluggable GPIO controllers can come and go, as this
kind of problem has been know to userspace for character
devices since ages, and if a gpiochip handle is held in
userspace we know we will break something, whereas the
sysfs is stateless.
- The one-value-per-file rule of sysfs is really hard to
maintain when you want to twist more than one knob at a time,
for example have in-kernel APIs to switch several GPIO
lines at the same time, and this will be possible to do
with a single ioctl() from userspace, saving a lot of
context switching.
We also need to add a new bus type for GPIO. This is
necessary for example for userspace coldplug, where sysfs is
traversed to find the boot-time device nodes and create the
character devices in /dev.
This new chardev ABI is *non* *optional* and can be counted
on to be present in the future, emphasizing the preference
of this ABI.
The ABI only implements one single ioctl() to get the name
and number of GPIO lines of a chip. Even this is debatable:
see it as a minimal example for review. This ABI shall be
ruthlessly reviewed and etched in stone.
The old /sys/class/gpio is still optional to compile in,
but will be deprecated.
Unique device IDs are created using IDR, which is overkill
and insanely scalable, but also well tested.
Cc: Johan Hovold <johan@kernel.org>
Cc: Michael Welling <mwelling@ieee.org>
Cc: Markus Pargmann <mpa@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
2015-10-21 20:29:53 +07:00
|
|
|
struct cdev chrdev;
|
2016-02-09 19:21:06 +07:00
|
|
|
struct device *mockdev;
|
2015-10-20 16:10:38 +07:00
|
|
|
struct module *owner;
|
|
|
|
struct gpio_chip *chip;
|
2016-02-09 19:51:59 +07:00
|
|
|
struct gpio_desc *descs;
|
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>
2016-02-10 16:57:36 +07:00
|
|
|
int base;
|
|
|
|
u16 ngpio;
|
2017-12-13 18:25:19 +07:00
|
|
|
const char *label;
|
2016-02-11 17:37:48 +07:00
|
|
|
void *data;
|
2015-10-20 16:10:38 +07:00
|
|
|
struct list_head list;
|
2016-02-11 17:03:06 +07:00
|
|
|
|
|
|
|
#ifdef CONFIG_PINCTRL
|
|
|
|
/*
|
|
|
|
* If CONFIG_PINCTRL is enabled, then gpio controllers can optionally
|
|
|
|
* describe the actual pin range which they serve in an SoC. This
|
|
|
|
* information would be used by pinctrl subsystem to configure
|
|
|
|
* corresponding pins for gpio usage.
|
|
|
|
*/
|
|
|
|
struct list_head pin_ranges;
|
|
|
|
#endif
|
2015-10-20 16:10:38 +07:00
|
|
|
};
|
|
|
|
|
2014-01-08 17:40:56 +07:00
|
|
|
/**
|
|
|
|
* struct acpi_gpio_info - ACPI GPIO specific information
|
2017-11-10 20:40:30 +07:00
|
|
|
* @adev: reference to ACPI device which consumes GPIO resource
|
2017-05-24 00:03:23 +07:00
|
|
|
* @flags: GPIO initialization flags
|
2014-01-08 17:40:56 +07:00
|
|
|
* @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo
|
2017-01-04 00:01:18 +07:00
|
|
|
* @polarity: interrupt polarity as provided by ACPI
|
|
|
|
* @triggering: triggering type as provided by ACPI
|
2017-11-10 20:40:32 +07:00
|
|
|
* @quirks: Linux specific quirks as provided by struct acpi_gpio_mapping
|
2014-01-08 17:40:56 +07:00
|
|
|
*/
|
|
|
|
struct acpi_gpio_info {
|
2017-11-10 20:40:30 +07:00
|
|
|
struct acpi_device *adev;
|
2017-05-24 00:03:23 +07:00
|
|
|
enum gpiod_flags flags;
|
2014-01-08 17:40:56 +07:00
|
|
|
bool gpioint;
|
2015-12-24 05:25:34 +07:00
|
|
|
int polarity;
|
|
|
|
int triggering;
|
2017-11-10 20:40:32 +07:00
|
|
|
unsigned int quirks;
|
2014-01-08 17:40:56 +07:00
|
|
|
};
|
|
|
|
|
2015-02-11 23:27:55 +07:00
|
|
|
/* gpio suffixes used for ACPI and device tree lookup */
|
|
|
|
static const char * const gpio_suffixes[] = { "gpios", "gpio" };
|
|
|
|
|
2016-10-03 15:09:40 +07:00
|
|
|
#ifdef CONFIG_OF_GPIO
|
|
|
|
struct gpio_desc *of_find_gpio(struct device *dev,
|
|
|
|
const char *con_id,
|
|
|
|
unsigned int idx,
|
|
|
|
enum gpio_lookup_flags *flags);
|
2016-10-03 16:37:24 +07:00
|
|
|
struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
|
|
|
|
const char *list_name, int index, enum of_gpio_flags *flags);
|
2016-10-03 15:59:32 +07:00
|
|
|
int of_gpiochip_add(struct gpio_chip *gc);
|
|
|
|
void of_gpiochip_remove(struct gpio_chip *gc);
|
2016-10-03 15:09:40 +07:00
|
|
|
#else
|
|
|
|
static inline struct gpio_desc *of_find_gpio(struct device *dev,
|
|
|
|
const char *con_id,
|
|
|
|
unsigned int idx,
|
|
|
|
enum gpio_lookup_flags *flags)
|
|
|
|
{
|
|
|
|
return ERR_PTR(-ENOENT);
|
|
|
|
}
|
2016-10-03 16:37:24 +07:00
|
|
|
static inline struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
|
|
|
|
const char *list_name, int index, enum of_gpio_flags *flags)
|
|
|
|
{
|
|
|
|
return ERR_PTR(-ENOENT);
|
|
|
|
}
|
2016-10-03 15:59:32 +07:00
|
|
|
static inline int of_gpiochip_add(struct gpio_chip *gc) { return 0; }
|
|
|
|
static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
|
2016-10-03 15:09:40 +07:00
|
|
|
#endif /* CONFIG_OF_GPIO */
|
|
|
|
|
2014-01-08 17:40:54 +07:00
|
|
|
#ifdef CONFIG_ACPI
|
|
|
|
void acpi_gpiochip_add(struct gpio_chip *chip);
|
|
|
|
void acpi_gpiochip_remove(struct gpio_chip *chip);
|
2014-01-08 17:40:56 +07:00
|
|
|
|
2014-07-25 13:54:48 +07:00
|
|
|
void acpi_gpiochip_request_interrupts(struct gpio_chip *chip);
|
|
|
|
void acpi_gpiochip_free_interrupts(struct gpio_chip *chip);
|
|
|
|
|
2017-05-24 00:03:23 +07:00
|
|
|
int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags,
|
2017-11-10 20:40:31 +07:00
|
|
|
struct acpi_gpio_info *info);
|
2017-05-24 00:03:23 +07:00
|
|
|
|
2016-10-03 15:40:03 +07:00
|
|
|
struct gpio_desc *acpi_find_gpio(struct device *dev,
|
|
|
|
const char *con_id,
|
|
|
|
unsigned int idx,
|
2017-05-24 00:03:23 +07:00
|
|
|
enum gpiod_flags *dflags,
|
2016-10-03 15:40:03 +07:00
|
|
|
enum gpio_lookup_flags *lookupflags);
|
2015-08-27 09:42:33 +07:00
|
|
|
struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
|
|
|
|
const char *propname, int index,
|
|
|
|
struct acpi_gpio_info *info);
|
2015-02-11 23:27:58 +07:00
|
|
|
|
|
|
|
int acpi_gpio_count(struct device *dev, const char *con_id);
|
2015-11-12 02:45:30 +07:00
|
|
|
|
|
|
|
bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id);
|
2014-01-08 17:40:54 +07:00
|
|
|
#else
|
|
|
|
static inline void acpi_gpiochip_add(struct gpio_chip *chip) { }
|
|
|
|
static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { }
|
2014-01-08 17:40:56 +07:00
|
|
|
|
2014-07-25 13:54:48 +07:00
|
|
|
static inline void
|
|
|
|
acpi_gpiochip_request_interrupts(struct gpio_chip *chip) { }
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { }
|
|
|
|
|
2017-05-24 00:03:23 +07:00
|
|
|
static inline int
|
2017-11-10 20:40:31 +07:00
|
|
|
acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *info)
|
2017-05-24 00:03:23 +07:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-01-08 17:40:56 +07:00
|
|
|
static inline struct gpio_desc *
|
2016-10-03 15:40:03 +07:00
|
|
|
acpi_find_gpio(struct device *dev, const char *con_id,
|
2017-05-24 00:03:23 +07:00
|
|
|
unsigned int idx, enum gpiod_flags *dflags,
|
2016-10-03 15:40:03 +07:00
|
|
|
enum gpio_lookup_flags *lookupflags)
|
2014-01-08 17:40:56 +07:00
|
|
|
{
|
2016-10-03 15:40:03 +07:00
|
|
|
return ERR_PTR(-ENOENT);
|
2014-01-08 17:40:56 +07:00
|
|
|
}
|
2015-08-27 09:42:33 +07:00
|
|
|
static inline struct gpio_desc *
|
|
|
|
acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname,
|
|
|
|
int index, struct acpi_gpio_info *info)
|
|
|
|
{
|
|
|
|
return ERR_PTR(-ENXIO);
|
|
|
|
}
|
2015-02-11 23:27:58 +07:00
|
|
|
static inline int acpi_gpio_count(struct device *dev, const char *con_id)
|
|
|
|
{
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
2015-11-12 02:45:30 +07:00
|
|
|
|
|
|
|
static inline bool acpi_can_fallback_to_crs(struct acpi_device *adev,
|
|
|
|
const char *con_id)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2014-01-08 17:40:54 +07:00
|
|
|
#endif
|
|
|
|
|
2014-07-22 14:17:41 +07:00
|
|
|
struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, u16 hwnum);
|
2017-10-12 17:40:10 +07:00
|
|
|
int gpiod_get_array_value_complex(bool raw, bool can_sleep,
|
|
|
|
unsigned int array_size,
|
|
|
|
struct gpio_desc **desc_array,
|
|
|
|
int *value_array);
|
2016-04-24 16:36:59 +07:00
|
|
|
void gpiod_set_array_value_complex(bool raw, bool can_sleep,
|
|
|
|
unsigned int array_size,
|
|
|
|
struct gpio_desc **desc_array,
|
|
|
|
int *value_array);
|
2014-07-22 14:17:41 +07:00
|
|
|
|
2017-12-30 04:52:02 +07:00
|
|
|
/* This is just passed between gpiolib and devres */
|
|
|
|
struct gpio_desc *gpiod_get_from_of_node(struct device_node *node,
|
|
|
|
const char *propname, int index,
|
|
|
|
enum gpiod_flags dflags,
|
|
|
|
const char *label);
|
|
|
|
|
2014-07-01 12:45:15 +07:00
|
|
|
extern struct spinlock gpio_lock;
|
2015-10-20 16:10:38 +07:00
|
|
|
extern struct list_head gpio_devices;
|
2014-07-01 12:45:15 +07:00
|
|
|
|
|
|
|
struct gpio_desc {
|
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>
2016-02-10 16:57:36 +07:00
|
|
|
struct gpio_device *gdev;
|
2014-07-01 12:45:15 +07:00
|
|
|
unsigned long flags;
|
|
|
|
/* flag symbols are bit numbers */
|
|
|
|
#define FLAG_REQUESTED 0
|
|
|
|
#define FLAG_IS_OUT 1
|
|
|
|
#define FLAG_EXPORT 2 /* protected by sysfs_lock */
|
|
|
|
#define FLAG_SYSFS 3 /* exported via /sys/class/gpio/control */
|
|
|
|
#define FLAG_ACTIVE_LOW 6 /* value has active low */
|
|
|
|
#define FLAG_OPEN_DRAIN 7 /* Gpio is open drain type */
|
|
|
|
#define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */
|
|
|
|
#define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */
|
2015-02-03 00:44:44 +07:00
|
|
|
#define FLAG_IS_HOGGED 11 /* GPIO is hogged */
|
2017-11-30 10:55:24 +07:00
|
|
|
#define FLAG_TRANSITORY 12 /* GPIO may lose value in sleep or reset */
|
2014-07-01 12:45:15 +07:00
|
|
|
|
2015-08-14 21:10:59 +07:00
|
|
|
/* Connection label */
|
2014-07-01 12:45:15 +07:00
|
|
|
const char *label;
|
2015-08-14 21:10:59 +07:00
|
|
|
/* Name of the GPIO */
|
|
|
|
const char *name;
|
2014-07-01 12:45:15 +07:00
|
|
|
};
|
|
|
|
|
|
|
|
int gpiod_request(struct gpio_desc *desc, const char *label);
|
|
|
|
void gpiod_free(struct gpio_desc *desc);
|
2017-05-24 00:03:16 +07:00
|
|
|
int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
|
|
|
|
unsigned long lflags, enum gpiod_flags dflags);
|
2015-02-03 00:44:44 +07:00
|
|
|
int gpiod_hog(struct gpio_desc *desc, const char *name,
|
|
|
|
unsigned long lflags, enum gpiod_flags dflags);
|
2014-07-01 12:45:15 +07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Return the GPIO number of the passed descriptor relative to its chip
|
|
|
|
*/
|
2017-07-11 21:41:43 +07:00
|
|
|
static inline int gpio_chip_hwgpio(const struct gpio_desc *desc)
|
2014-07-01 12:45:15 +07:00
|
|
|
{
|
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>
2016-02-10 16:57:36 +07:00
|
|
|
return desc - &desc->gdev->descs[0];
|
2014-07-01 12:45:15 +07:00
|
|
|
}
|
|
|
|
|
2017-12-15 21:02:33 +07:00
|
|
|
void devprop_gpiochip_set_names(struct gpio_chip *chip,
|
|
|
|
const struct fwnode_handle *fwnode);
|
2016-10-21 21:21:31 +07:00
|
|
|
|
2014-07-01 12:45:15 +07:00
|
|
|
/* With descriptor prefix */
|
|
|
|
|
|
|
|
#define gpiod_emerg(desc, fmt, ...) \
|
|
|
|
pr_emerg("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?",\
|
|
|
|
##__VA_ARGS__)
|
|
|
|
#define gpiod_crit(desc, fmt, ...) \
|
|
|
|
pr_crit("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?", \
|
|
|
|
##__VA_ARGS__)
|
|
|
|
#define gpiod_err(desc, fmt, ...) \
|
|
|
|
pr_err("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?", \
|
|
|
|
##__VA_ARGS__)
|
|
|
|
#define gpiod_warn(desc, fmt, ...) \
|
|
|
|
pr_warn("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?", \
|
|
|
|
##__VA_ARGS__)
|
|
|
|
#define gpiod_info(desc, fmt, ...) \
|
|
|
|
pr_info("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?", \
|
|
|
|
##__VA_ARGS__)
|
|
|
|
#define gpiod_dbg(desc, fmt, ...) \
|
|
|
|
pr_debug("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?",\
|
|
|
|
##__VA_ARGS__)
|
|
|
|
|
|
|
|
/* With chip prefix */
|
|
|
|
|
|
|
|
#define chip_emerg(chip, fmt, ...) \
|
2015-10-20 16:31:54 +07:00
|
|
|
dev_emerg(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__)
|
2014-07-01 12:45:15 +07:00
|
|
|
#define chip_crit(chip, fmt, ...) \
|
2015-10-20 16:31:54 +07:00
|
|
|
dev_crit(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__)
|
2014-07-01 12:45:15 +07:00
|
|
|
#define chip_err(chip, fmt, ...) \
|
2015-10-20 16:31:54 +07:00
|
|
|
dev_err(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__)
|
2014-07-01 12:45:15 +07:00
|
|
|
#define chip_warn(chip, fmt, ...) \
|
2015-10-20 16:31:54 +07:00
|
|
|
dev_warn(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__)
|
2014-07-01 12:45:15 +07:00
|
|
|
#define chip_info(chip, fmt, ...) \
|
2015-10-20 16:31:54 +07:00
|
|
|
dev_info(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__)
|
2014-07-01 12:45:15 +07:00
|
|
|
#define chip_dbg(chip, fmt, ...) \
|
2015-10-20 16:31:54 +07:00
|
|
|
dev_dbg(&chip->gpiodev->dev, "(%s): " fmt, chip->label, ##__VA_ARGS__)
|
2014-07-01 12:45:15 +07:00
|
|
|
|
|
|
|
#ifdef CONFIG_GPIO_SYSFS
|
|
|
|
|
2016-02-09 19:21:06 +07:00
|
|
|
int gpiochip_sysfs_register(struct gpio_device *gdev);
|
|
|
|
void gpiochip_sysfs_unregister(struct gpio_device *gdev);
|
2014-07-01 12:45:15 +07:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
2016-02-09 19:21:06 +07:00
|
|
|
static inline int gpiochip_sysfs_register(struct gpio_device *gdev)
|
2014-07-01 12:45:15 +07:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-02-09 19:21:06 +07:00
|
|
|
static inline void gpiochip_sysfs_unregister(struct gpio_device *gdev)
|
2014-07-01 12:45:15 +07:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* CONFIG_GPIO_SYSFS */
|
|
|
|
|
2014-01-08 17:40:54 +07:00
|
|
|
#endif /* GPIOLIB_H */
|