aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/gpio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-14 17:23:44 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-14 17:23:44 -0800
commit6aa2f9441f1ef21f10c41f45e6453b135e9cd736 (patch)
tree334e67c4693eddff47a098b9afad63ca2ccfcd55 /include/linux/gpio
parentMerge tag 'dma-mapping-4.15' of git://git.infradead.org/users/hch/dma-mapping (diff)
parentgpio: tegra186: Remove tegra186_gpio_lock_class (diff)
downloadlinux-dev-6aa2f9441f1ef21f10c41f45e6453b135e9cd736.tar.xz
linux-dev-6aa2f9441f1ef21f10c41f45e6453b135e9cd736.zip
Merge tag 'gpio-v4.15-1' of ssh://gitolite.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.15 kernel cycle: Core: - Fix the semantics of raw GPIO to actually be raw. No inversion semantics as before, but also no open draining, and allow the raw operations to affect lines used for interrupts as the caller supposedly knows what they are doing if they are getting the big hammer. - Rewrote the __inner_function() notation calls to names that make more sense. I just find this kind of code disturbing. - Drop the .irq_base() field from the gpiochip since now all IRQs are mapped dynamically. This is nice. - Support for .get_multiple() in the core driver API. This allows us to read several GPIO lines with a single register read. This has high value for some usecases: it can be used to create oscilloscopes and signal analyzers and other things that rely on reading several lines at exactly the same instant. Also a generally nice optimization. This uses the new assign_bit() macro from the bitops lib that was ACKed by Andrew Morton and is implemented for two drivers, one of them being the generic MMIO driver so everyone using that will be able to benefit from this. - Do not allow requests of Open Drain and Open Source setting of a GPIO line simultaneously. If the hardware actually supports enabling both at the same time the electrical result would be disastrous. - A new interrupt chip core helper. This will be helpful to deal with "banked" GPIOs, which means GPIO controllers with several logical blocks of GPIO inside them. This is several gpiochips per device in the device model, in contrast to the case when there is a 1-to-1 relationship between a device and a gpiochip. New drivers: - Maxim MAX3191x industrial serializer, a very interesting piece of professional I/O hardware. - Uniphier GPIO driver. This is the GPIO block from the recent Socionext (ex Fujitsu and Panasonic) platform. - Tegra 186 driver. This is based on the new banked GPIO infrastructure. Other improvements: - Some documentation improvements. - Wakeup support for the DesignWare DWAPB GPIO controller. - Reset line support on the DesignWare DWAPB GPIO controller. - Several non-critical bug fixes and improvements for the Broadcom BRCMSTB driver. - Misc non-critical bug fixes like exotic errorpaths, removal of dead code etc. - Explicit comments on fall-through switch() statements" * tag 'gpio-v4.15-1' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (65 commits) gpio: tegra186: Remove tegra186_gpio_lock_class gpio: rcar: Add r8a77995 (R-Car D3) support pinctrl: bcm2835: Fix some merge fallout gpio: Fix undefined lock_dep_class gpio: Automatically add lockdep keys gpio: Introduce struct gpio_irq_chip.first gpio: Disambiguate struct gpio_irq_chip.nested gpio: Add Tegra186 support gpio: Export gpiochip_irq_{map,unmap}() gpio: Implement tighter IRQ chip integration gpio: Move lock_key into struct gpio_irq_chip gpio: Move irq_valid_mask into struct gpio_irq_chip gpio: Move irq_nested into struct gpio_irq_chip gpio: Move irq_chained_parent to struct gpio_irq_chip gpio: Move irq_default_type to struct gpio_irq_chip gpio: Move irq_handler to struct gpio_irq_chip gpio: Move irqdomain into struct gpio_irq_chip gpio: Move irqchip into struct gpio_irq_chip gpio: Introduce struct gpio_irq_chip pinctrl: armada-37xx: remove unused variable ...
Diffstat (limited to 'include/linux/gpio')
-rw-r--r--include/linux/gpio/consumer.h43
-rw-r--r--include/linux/gpio/driver.h215
-rw-r--r--include/linux/gpio/machine.h2
3 files changed, 226 insertions, 34 deletions
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index c4a350d83578..6d236656aaef 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -100,10 +100,15 @@ int gpiod_direction_output_raw(struct gpio_desc *desc, int value);
/* Value get/set from non-sleeping context */
int gpiod_get_value(const struct gpio_desc *desc);
+int gpiod_get_array_value(unsigned int array_size,
+ struct gpio_desc **desc_array, int *value_array);
void gpiod_set_value(struct gpio_desc *desc, int value);
void gpiod_set_array_value(unsigned int array_size,
struct gpio_desc **desc_array, int *value_array);
int gpiod_get_raw_value(const struct gpio_desc *desc);
+int gpiod_get_raw_array_value(unsigned int array_size,
+ struct gpio_desc **desc_array,
+ int *value_array);
void gpiod_set_raw_value(struct gpio_desc *desc, int value);
void gpiod_set_raw_array_value(unsigned int array_size,
struct gpio_desc **desc_array,
@@ -111,11 +116,17 @@ void gpiod_set_raw_array_value(unsigned int array_size,
/* Value get/set from sleeping context */
int gpiod_get_value_cansleep(const struct gpio_desc *desc);
+int gpiod_get_array_value_cansleep(unsigned int array_size,
+ struct gpio_desc **desc_array,
+ int *value_array);
void gpiod_set_value_cansleep(struct gpio_desc *desc, int value);
void gpiod_set_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array,
int *value_array);
int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc);
+int gpiod_get_raw_array_value_cansleep(unsigned int array_size,
+ struct gpio_desc **desc_array,
+ int *value_array);
void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value);
void gpiod_set_raw_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array,
@@ -306,6 +317,14 @@ static inline int gpiod_get_value(const struct gpio_desc *desc)
WARN_ON(1);
return 0;
}
+static inline int gpiod_get_array_value(unsigned int array_size,
+ struct gpio_desc **desc_array,
+ int *value_array)
+{
+ /* GPIO can never have been requested */
+ WARN_ON(1);
+ return 0;
+}
static inline void gpiod_set_value(struct gpio_desc *desc, int value)
{
/* GPIO can never have been requested */
@@ -324,6 +343,14 @@ static inline int gpiod_get_raw_value(const struct gpio_desc *desc)
WARN_ON(1);
return 0;
}
+static inline int gpiod_get_raw_array_value(unsigned int array_size,
+ struct gpio_desc **desc_array,
+ int *value_array)
+{
+ /* GPIO can never have been requested */
+ WARN_ON(1);
+ return 0;
+}
static inline void gpiod_set_raw_value(struct gpio_desc *desc, int value)
{
/* GPIO can never have been requested */
@@ -343,6 +370,14 @@ static inline int gpiod_get_value_cansleep(const struct gpio_desc *desc)
WARN_ON(1);
return 0;
}
+static inline int gpiod_get_array_value_cansleep(unsigned int array_size,
+ struct gpio_desc **desc_array,
+ int *value_array)
+{
+ /* GPIO can never have been requested */
+ WARN_ON(1);
+ return 0;
+}
static inline void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
{
/* GPIO can never have been requested */
@@ -361,6 +396,14 @@ static inline int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc)
WARN_ON(1);
return 0;
}
+static inline int gpiod_get_raw_array_value_cansleep(unsigned int array_size,
+ struct gpio_desc **desc_array,
+ int *value_array)
+{
+ /* GPIO can never have been requested */
+ WARN_ON(1);
+ return 0;
+}
static inline void gpiod_set_raw_value_cansleep(struct gpio_desc *desc,
int value)
{
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 424e5139ff10..55e672592fa9 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -20,6 +20,131 @@ struct module;
#ifdef CONFIG_GPIOLIB
+#ifdef CONFIG_GPIOLIB_IRQCHIP
+/**
+ * struct gpio_irq_chip - GPIO interrupt controller
+ */
+struct gpio_irq_chip {
+ /**
+ * @chip:
+ *
+ * GPIO IRQ chip implementation, provided by GPIO driver.
+ */
+ struct irq_chip *chip;
+
+ /**
+ * @domain:
+ *
+ * Interrupt translation domain; responsible for mapping between GPIO
+ * hwirq number and Linux IRQ number.
+ */
+ struct irq_domain *domain;
+
+ /**
+ * @domain_ops:
+ *
+ * Table of interrupt domain operations for this IRQ chip.
+ */
+ const struct irq_domain_ops *domain_ops;
+
+ /**
+ * @handler:
+ *
+ * The IRQ handler to use (often a predefined IRQ core function) for
+ * GPIO IRQs, provided by GPIO driver.
+ */
+ irq_flow_handler_t handler;
+
+ /**
+ * @default_type:
+ *
+ * Default IRQ triggering type applied during GPIO driver
+ * initialization, provided by GPIO driver.
+ */
+ unsigned int default_type;
+
+ /**
+ * @lock_key:
+ *
+ * Per GPIO IRQ chip lockdep class.
+ */
+ struct lock_class_key *lock_key;
+
+ /**
+ * @parent_handler:
+ *
+ * The interrupt handler for the GPIO chip's parent interrupts, may be
+ * NULL if the parent interrupts are nested rather than cascaded.
+ */
+ irq_flow_handler_t parent_handler;
+
+ /**
+ * @parent_handler_data:
+ *
+ * Data associated, and passed to, the handler for the parent
+ * interrupt.
+ */
+ void *parent_handler_data;
+
+ /**
+ * @num_parents:
+ *
+ * The number of interrupt parents of a GPIO chip.
+ */
+ unsigned int num_parents;
+
+ /**
+ * @parents:
+ *
+ * A list of interrupt parents of a GPIO chip. This is owned by the
+ * driver, so the core will only reference this list, not modify it.
+ */
+ unsigned int *parents;
+
+ /**
+ * @map:
+ *
+ * A list of interrupt parents for each line of a GPIO chip.
+ */
+ unsigned int *map;
+
+ /**
+ * @threaded:
+ *
+ * True if set the interrupt handling uses nested threads.
+ */
+ bool threaded;
+
+ /**
+ * @need_valid_mask:
+ *
+ * If set core allocates @valid_mask with all bits set to one.
+ */
+ bool need_valid_mask;
+
+ /**
+ * @valid_mask:
+ *
+ * If not %NULL holds bitmask of GPIOs which are valid to be included
+ * in IRQ domain of the chip.
+ */
+ unsigned long *valid_mask;
+
+ /**
+ * @first:
+ *
+ * Required for static IRQ allocation. If set, irq_domain_add_simple()
+ * will allocate and map all IRQs during initialization.
+ */
+ unsigned int first;
+};
+
+static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip)
+{
+ return container_of(chip, struct gpio_irq_chip, chip);
+}
+#endif
+
/**
* struct gpio_chip - abstract a GPIO controller
* @label: a functional name for the GPIO device, such as a part
@@ -36,6 +161,8 @@ struct module;
* @direction_input: configures signal "offset" as input, or returns error
* @direction_output: configures signal "offset" as output, or returns error
* @get: returns value for signal "offset", 0=low, 1=high, or negative error
+ * @get_multiple: reads values for multiple signals defined by "mask" and
+ * stores them in "bits", returns 0 on success or negative error
* @set: assigns output value for signal "offset"
* @set_multiple: assigns output values for multiple signals defined by "mask"
* @set_config: optional hook for all kinds of settings. Uses the same
@@ -66,9 +193,9 @@ struct module;
* registers.
* @read_reg: reader function for generic GPIO
* @write_reg: writer function for generic GPIO
- * @pin2mask: some generic GPIO controllers work with the big-endian bits
- * notation, e.g. in a 8-bits register, GPIO7 is the least significant
- * bit. This callback assigns the right bit mask.
+ * @be_bits: if the generic GPIO has big endian bit order (bit 31 is representing
+ * line 0, bit 30 is line 1 ... bit 0 is line 31) this is set to true by the
+ * generic GPIO core. It is for internal housekeeping only.
* @reg_dat: data (in) register for generic GPIO
* @reg_set: output set register (out=high) for generic GPIO
* @reg_clr: output clear register (out=low) for generic GPIO
@@ -81,23 +208,6 @@ struct module;
* safely.
* @bgpio_dir: shadowed direction register for generic GPIO to clear/set
* direction safely.
- * @irqchip: GPIO IRQ chip impl, provided by GPIO driver
- * @irqdomain: Interrupt translation domain; responsible for mapping
- * between GPIO hwirq number and linux irq number
- * @irq_base: first linux IRQ number assigned to GPIO IRQ chip (deprecated)
- * @irq_handler: the irq handler to use (often a predefined irq core function)
- * for GPIO IRQs, provided by GPIO driver
- * @irq_default_type: default IRQ triggering type applied during GPIO driver
- * initialization, provided by GPIO driver
- * @irq_chained_parent: GPIO IRQ chip parent/bank linux irq number,
- * provided by GPIO driver for chained interrupt (not for nested
- * interrupts).
- * @irq_nested: True if set the interrupt handling is nested.
- * @irq_need_valid_mask: If set core allocates @irq_valid_mask with all
- * bits set to one
- * @irq_valid_mask: If not %NULL holds bitmask of GPIOs which are valid to
- * be included in IRQ domain of the chip
- * @lock_key: per GPIO IRQ chip lockdep class
*
* A gpio_chip can help platforms abstract various sources of GPIOs so
* they can all be accessed through a common programing interface.
@@ -127,6 +237,9 @@ struct gpio_chip {
unsigned offset, int value);
int (*get)(struct gpio_chip *chip,
unsigned offset);
+ int (*get_multiple)(struct gpio_chip *chip,
+ unsigned long *mask,
+ unsigned long *bits);
void (*set)(struct gpio_chip *chip,
unsigned offset, int value);
void (*set_multiple)(struct gpio_chip *chip,
@@ -148,7 +261,7 @@ struct gpio_chip {
#if IS_ENABLED(CONFIG_GPIO_GENERIC)
unsigned long (*read_reg)(void __iomem *reg);
void (*write_reg)(void __iomem *reg, unsigned long data);
- unsigned long (*pin2mask)(struct gpio_chip *gc, unsigned int pin);
+ bool be_bits;
void __iomem *reg_dat;
void __iomem *reg_set;
void __iomem *reg_clr;
@@ -164,16 +277,14 @@ struct gpio_chip {
* With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib
* to handle IRQs for most practical cases.
*/
- struct irq_chip *irqchip;
- struct irq_domain *irqdomain;
- unsigned int irq_base;
- irq_flow_handler_t irq_handler;
- unsigned int irq_default_type;
- unsigned int irq_chained_parent;
- bool irq_nested;
- bool irq_need_valid_mask;
- unsigned long *irq_valid_mask;
- struct lock_class_key *lock_key;
+
+ /**
+ * @irq:
+ *
+ * Integrates interrupt chip functionality with the GPIO chip. Can be
+ * used to handle IRQs for most practical cases.
+ */
+ struct gpio_irq_chip irq;
#endif
#if defined(CONFIG_OF_GPIO)
@@ -211,7 +322,41 @@ extern const char *gpiochip_is_requested(struct gpio_chip *chip,
unsigned offset);
/* add/remove chips */
-extern int gpiochip_add_data(struct gpio_chip *chip, void *data);
+extern int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
+ struct lock_class_key *lock_key);
+
+/**
+ * gpiochip_add_data() - register a gpio_chip
+ * @chip: the chip to register, with chip->base initialized
+ * @data: driver-private data associated with this chip
+ *
+ * Context: potentially before irqs will work
+ *
+ * When gpiochip_add_data() is called very early during boot, so that GPIOs
+ * can be freely used, the chip->parent device must be registered before
+ * the gpio framework's arch_initcall(). Otherwise sysfs initialization
+ * for GPIOs will fail rudely.
+ *
+ * gpiochip_add_data() must only be called after gpiolib initialization,
+ * ie after core_initcall().
+ *
+ * If chip->base is negative, this requests dynamic assignment of
+ * a range of valid GPIOs.
+ *
+ * Returns:
+ * A negative errno if the chip can't be registered, such as because the
+ * chip->base is invalid or already associated with a different chip.
+ * Otherwise it returns zero as a success code.
+ */
+#ifdef CONFIG_LOCKDEP
+#define gpiochip_add_data(chip, data) ({ \
+ static struct lock_class_key key; \
+ gpiochip_add_data_with_key(chip, data, &key); \
+ })
+#else
+#define gpiochip_add_data(chip, data) gpiochip_add_data_with_key(chip, data, NULL)
+#endif
+
static inline int gpiochip_add(struct gpio_chip *chip)
{
return gpiochip_add_data(chip, NULL);
@@ -265,6 +410,10 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev,
#ifdef CONFIG_GPIOLIB_IRQCHIP
+int gpiochip_irq_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hwirq);
+void gpiochip_irq_unmap(struct irq_domain *d, unsigned int irq);
+
void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
struct irq_chip *irqchip,
unsigned int parent_irq,
@@ -279,7 +428,7 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip,
unsigned int first_irq,
irq_flow_handler_t handler,
unsigned int type,
- bool nested,
+ bool threaded,
struct lock_class_key *lock_key);
#ifdef CONFIG_LOCKDEP
diff --git a/include/linux/gpio/machine.h b/include/linux/gpio/machine.h
index b7225369e568..846be7c69a52 100644
--- a/include/linux/gpio/machine.h
+++ b/include/linux/gpio/machine.h
@@ -11,7 +11,7 @@ enum gpio_lookup_flags {
GPIO_OPEN_DRAIN = (1 << 1),
GPIO_OPEN_SOURCE = (1 << 2),
GPIO_SLEEP_MAINTAIN_VALUE = (0 << 3),
- GPIO_SLEEP_MAY_LOOSE_VALUE = (1 << 3),
+ GPIO_SLEEP_MAY_LOSE_VALUE = (1 << 3),
};
/**