restore lost packages from 0.2.3 + fix overwritten 0.2.4 files

- Restore 29 recipe symlinks (libdrm, qtbase, dbus, sddm, pipewire, etc.)
- Restore 33 patches (KDE, libdrm, mesa, pipewire, sddm, wireplumber)
- Restore 20+ local/scripts (audit, lint, test, build helpers)
- Restore src/cook/scheduler.rs, status.rs, gnu-config/
- Restore scripts/patch-inclusion-gate.sh, run_mini1.sh, validate-collision-log.sh
- Recover TLC source from HEAD (was overwritten by 0.2.3 checkout)
- Recover 11 local/docs plans from HEAD (were overwritten)
- Recover qt6-wayland-smoke symlink from HEAD
- Fix MOTD: remove garbled ASCII art, use clean text
- Update version: 0.2.0 -> 0.2.4 in os-release, motd, config
- Reduce filesystem_size: 1536 -> 512 MiB
- Add ABSOLUTE RULE to AGENTS.md: never delete/ignore packages
- Reduce pcid scheme log verbosity: info -> debug
This commit is contained in:
2026-06-19 12:39:14 +03:00
parent ffbe098ef8
commit dc68054305
6418 changed files with 7066233 additions and 8670 deletions
@@ -0,0 +1,19 @@
#ifndef __GPIO_ASPEED_H
#define __GPIO_ASPEED_H
#include <linux/types.h>
struct gpio_desc;
struct aspeed_gpio_copro_ops {
int (*request_access)(void *data);
int (*release_access)(void *data);
};
int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc,
u16 *vreg_offset, u16 *dreg_offset, u8 *bit);
int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc);
int aspeed_gpio_copro_set_ops(const struct aspeed_gpio_copro_ops *ops, void *data);
#endif /* __GPIO_ASPEED_H */
@@ -0,0 +1,738 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_GPIO_CONSUMER_H
#define __LINUX_GPIO_CONSUMER_H
#include <linux/bits.h>
#include <linux/err.h>
#include <linux/types.h>
#include "defs.h"
struct acpi_device;
struct device;
struct fwnode_handle;
struct gpio_array;
struct gpio_desc;
/**
* struct gpio_descs - Struct containing an array of descriptors that can be
* obtained using gpiod_get_array()
*
* @info: Pointer to the opaque gpio_array structure
* @ndescs: Number of held descriptors
* @desc: Array of pointers to GPIO descriptors
*/
struct gpio_descs {
struct gpio_array *info;
unsigned int ndescs;
struct gpio_desc *desc[];
};
#define GPIOD_FLAGS_BIT_DIR_SET BIT(0)
#define GPIOD_FLAGS_BIT_DIR_OUT BIT(1)
#define GPIOD_FLAGS_BIT_DIR_VAL BIT(2)
#define GPIOD_FLAGS_BIT_OPEN_DRAIN BIT(3)
/* GPIOD_FLAGS_BIT_NONEXCLUSIVE is DEPRECATED, don't use in new code. */
#define GPIOD_FLAGS_BIT_NONEXCLUSIVE BIT(4)
/**
* enum gpiod_flags - Optional flags that can be passed to one of gpiod_* to
* configure direction and output value. These values
* cannot be OR'd.
*
* @GPIOD_ASIS: Don't change anything
* @GPIOD_IN: Set lines to input mode
* @GPIOD_OUT_LOW: Set lines to output and drive them low
* @GPIOD_OUT_HIGH: Set lines to output and drive them high
* @GPIOD_OUT_LOW_OPEN_DRAIN: Set lines to open-drain output and drive them low
* @GPIOD_OUT_HIGH_OPEN_DRAIN: Set lines to open-drain output and drive them high
*/
enum gpiod_flags {
GPIOD_ASIS = 0,
GPIOD_IN = GPIOD_FLAGS_BIT_DIR_SET,
GPIOD_OUT_LOW = GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT,
GPIOD_OUT_HIGH = GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT |
GPIOD_FLAGS_BIT_DIR_VAL,
GPIOD_OUT_LOW_OPEN_DRAIN = GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_OPEN_DRAIN,
GPIOD_OUT_HIGH_OPEN_DRAIN = GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_OPEN_DRAIN,
};
#ifdef CONFIG_GPIOLIB
/* Return the number of GPIOs associated with a device / function */
int gpiod_count(struct device *dev, const char *con_id);
/* Acquire and dispose GPIOs */
struct gpio_desc *__must_check gpiod_get(struct device *dev,
const char *con_id,
enum gpiod_flags flags);
struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
const char *con_id,
unsigned int idx,
enum gpiod_flags flags);
struct gpio_desc *__must_check gpiod_get_optional(struct device *dev,
const char *con_id,
enum gpiod_flags flags);
struct gpio_desc *__must_check gpiod_get_index_optional(struct device *dev,
const char *con_id,
unsigned int index,
enum gpiod_flags flags);
struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
const char *con_id,
enum gpiod_flags flags);
struct gpio_descs *__must_check gpiod_get_array_optional(struct device *dev,
const char *con_id,
enum gpiod_flags flags);
void gpiod_put(struct gpio_desc *desc);
void gpiod_put_array(struct gpio_descs *descs);
struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
const char *con_id,
enum gpiod_flags flags);
struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
const char *con_id,
unsigned int idx,
enum gpiod_flags flags);
struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev,
const char *con_id,
enum gpiod_flags flags);
struct gpio_desc *__must_check
devm_gpiod_get_index_optional(struct device *dev, const char *con_id,
unsigned int index, enum gpiod_flags flags);
struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev,
const char *con_id,
enum gpiod_flags flags);
struct gpio_descs *__must_check
devm_gpiod_get_array_optional(struct device *dev, const char *con_id,
enum gpiod_flags flags);
void devm_gpiod_put(struct device *dev, struct gpio_desc *desc);
void devm_gpiod_unhinge(struct device *dev, struct gpio_desc *desc);
void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs);
int gpiod_get_direction(struct gpio_desc *desc);
int gpiod_direction_input(struct gpio_desc *desc);
int gpiod_direction_output(struct gpio_desc *desc, int value);
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,
struct gpio_array *array_info,
unsigned long *value_bitmap);
int gpiod_set_value(struct gpio_desc *desc, int value);
int gpiod_set_array_value(unsigned int array_size,
struct gpio_desc **desc_array,
struct gpio_array *array_info,
unsigned long *value_bitmap);
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,
struct gpio_array *array_info,
unsigned long *value_bitmap);
int gpiod_set_raw_value(struct gpio_desc *desc, int value);
int gpiod_set_raw_array_value(unsigned int array_size,
struct gpio_desc **desc_array,
struct gpio_array *array_info,
unsigned long *value_bitmap);
/* 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,
struct gpio_array *array_info,
unsigned long *value_bitmap);
int gpiod_set_value_cansleep(struct gpio_desc *desc, int value);
int gpiod_set_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array,
struct gpio_array *array_info,
unsigned long *value_bitmap);
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,
struct gpio_array *array_info,
unsigned long *value_bitmap);
int gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value);
int gpiod_set_raw_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array,
struct gpio_array *array_info,
unsigned long *value_bitmap);
int gpiod_set_config(struct gpio_desc *desc, unsigned long config);
int gpiod_set_debounce(struct gpio_desc *desc, unsigned int debounce);
void gpiod_toggle_active_low(struct gpio_desc *desc);
int gpiod_is_active_low(const struct gpio_desc *desc);
int gpiod_cansleep(const struct gpio_desc *desc);
int gpiod_to_irq(const struct gpio_desc *desc);
int gpiod_set_consumer_name(struct gpio_desc *desc, const char *name);
bool gpiod_is_shared(const struct gpio_desc *desc);
/* Convert between the old gpio_ and new gpiod_ interfaces */
struct gpio_desc *gpio_to_desc(unsigned gpio);
int desc_to_gpio(const struct gpio_desc *desc);
int gpiod_hwgpio(const struct gpio_desc *desc);
struct gpio_desc *fwnode_gpiod_get_index(struct fwnode_handle *fwnode,
const char *con_id, int index,
enum gpiod_flags flags,
const char *label);
struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev,
struct fwnode_handle *child,
const char *con_id, int index,
enum gpiod_flags flags,
const char *label);
bool gpiod_is_equal(const struct gpio_desc *desc,
const struct gpio_desc *other);
#else /* CONFIG_GPIOLIB */
#include <linux/bug.h>
#include <linux/kernel.h>
static inline int gpiod_count(struct device *dev, const char *con_id)
{
return 0;
}
static inline struct gpio_desc *__must_check gpiod_get(struct device *dev,
const char *con_id,
enum gpiod_flags flags)
{
return ERR_PTR(-ENOSYS);
}
static inline struct gpio_desc *__must_check
gpiod_get_index(struct device *dev,
const char *con_id,
unsigned int idx,
enum gpiod_flags flags)
{
return ERR_PTR(-ENOSYS);
}
static inline struct gpio_desc *__must_check
gpiod_get_optional(struct device *dev, const char *con_id,
enum gpiod_flags flags)
{
return NULL;
}
static inline struct gpio_desc *__must_check
gpiod_get_index_optional(struct device *dev, const char *con_id,
unsigned int index, enum gpiod_flags flags)
{
return NULL;
}
static inline struct gpio_descs *__must_check
gpiod_get_array(struct device *dev, const char *con_id,
enum gpiod_flags flags)
{
return ERR_PTR(-ENOSYS);
}
static inline struct gpio_descs *__must_check
gpiod_get_array_optional(struct device *dev, const char *con_id,
enum gpiod_flags flags)
{
return NULL;
}
static inline void gpiod_put(struct gpio_desc *desc)
{
might_sleep();
/* GPIO can never have been requested */
WARN_ON(desc);
}
static inline void devm_gpiod_unhinge(struct device *dev,
struct gpio_desc *desc)
{
might_sleep();
/* GPIO can never have been requested */
WARN_ON(desc);
}
static inline void gpiod_put_array(struct gpio_descs *descs)
{
might_sleep();
/* GPIO can never have been requested */
WARN_ON(descs);
}
static inline struct gpio_desc *__must_check
devm_gpiod_get(struct device *dev,
const char *con_id,
enum gpiod_flags flags)
{
return ERR_PTR(-ENOSYS);
}
static inline
struct gpio_desc *__must_check
devm_gpiod_get_index(struct device *dev,
const char *con_id,
unsigned int idx,
enum gpiod_flags flags)
{
return ERR_PTR(-ENOSYS);
}
static inline struct gpio_desc *__must_check
devm_gpiod_get_optional(struct device *dev, const char *con_id,
enum gpiod_flags flags)
{
return NULL;
}
static inline struct gpio_desc *__must_check
devm_gpiod_get_index_optional(struct device *dev, const char *con_id,
unsigned int index, enum gpiod_flags flags)
{
return NULL;
}
static inline struct gpio_descs *__must_check
devm_gpiod_get_array(struct device *dev, const char *con_id,
enum gpiod_flags flags)
{
return ERR_PTR(-ENOSYS);
}
static inline struct gpio_descs *__must_check
devm_gpiod_get_array_optional(struct device *dev, const char *con_id,
enum gpiod_flags flags)
{
return NULL;
}
static inline void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
{
might_sleep();
/* GPIO can never have been requested */
WARN_ON(desc);
}
static inline void devm_gpiod_put_array(struct device *dev,
struct gpio_descs *descs)
{
might_sleep();
/* GPIO can never have been requested */
WARN_ON(descs);
}
static inline int gpiod_get_direction(const struct gpio_desc *desc)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return -ENOSYS;
}
static inline int gpiod_direction_input(struct gpio_desc *desc)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return -ENOSYS;
}
static inline int gpiod_direction_output(struct gpio_desc *desc, int value)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return -ENOSYS;
}
static inline int gpiod_direction_output_raw(struct gpio_desc *desc, int value)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return -ENOSYS;
}
static inline int gpiod_get_value(const struct gpio_desc *desc)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return 0;
}
static inline int gpiod_get_array_value(unsigned int array_size,
struct gpio_desc **desc_array,
struct gpio_array *array_info,
unsigned long *value_bitmap)
{
/* GPIO can never have been requested */
WARN_ON(desc_array);
return 0;
}
static inline int gpiod_set_value(struct gpio_desc *desc, int value)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return 0;
}
static inline int gpiod_set_array_value(unsigned int array_size,
struct gpio_desc **desc_array,
struct gpio_array *array_info,
unsigned long *value_bitmap)
{
/* GPIO can never have been requested */
WARN_ON(desc_array);
return 0;
}
static inline int gpiod_get_raw_value(const struct gpio_desc *desc)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return 0;
}
static inline int gpiod_get_raw_array_value(unsigned int array_size,
struct gpio_desc **desc_array,
struct gpio_array *array_info,
unsigned long *value_bitmap)
{
/* GPIO can never have been requested */
WARN_ON(desc_array);
return 0;
}
static inline int gpiod_set_raw_value(struct gpio_desc *desc, int value)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return 0;
}
static inline int gpiod_set_raw_array_value(unsigned int array_size,
struct gpio_desc **desc_array,
struct gpio_array *array_info,
unsigned long *value_bitmap)
{
/* GPIO can never have been requested */
WARN_ON(desc_array);
return 0;
}
static inline int gpiod_get_value_cansleep(const struct gpio_desc *desc)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return 0;
}
static inline int gpiod_get_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array,
struct gpio_array *array_info,
unsigned long *value_bitmap)
{
/* GPIO can never have been requested */
WARN_ON(desc_array);
return 0;
}
static inline int gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return 0;
}
static inline int gpiod_set_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array,
struct gpio_array *array_info,
unsigned long *value_bitmap)
{
/* GPIO can never have been requested */
WARN_ON(desc_array);
return 0;
}
static inline int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return 0;
}
static inline int gpiod_get_raw_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array,
struct gpio_array *array_info,
unsigned long *value_bitmap)
{
/* GPIO can never have been requested */
WARN_ON(desc_array);
return 0;
}
static inline int gpiod_set_raw_value_cansleep(struct gpio_desc *desc,
int value)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return 0;
}
static inline int gpiod_set_raw_array_value_cansleep(unsigned int array_size,
struct gpio_desc **desc_array,
struct gpio_array *array_info,
unsigned long *value_bitmap)
{
/* GPIO can never have been requested */
WARN_ON(desc_array);
return 0;
}
static inline int gpiod_set_config(struct gpio_desc *desc, unsigned long config)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return -ENOSYS;
}
static inline int gpiod_set_debounce(struct gpio_desc *desc, unsigned int debounce)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return -ENOSYS;
}
static inline void gpiod_toggle_active_low(struct gpio_desc *desc)
{
/* GPIO can never have been requested */
WARN_ON(desc);
}
static inline int gpiod_is_active_low(const struct gpio_desc *desc)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return 0;
}
static inline int gpiod_cansleep(const struct gpio_desc *desc)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return 0;
}
static inline int gpiod_to_irq(const struct gpio_desc *desc)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return -EINVAL;
}
static inline int gpiod_set_consumer_name(struct gpio_desc *desc,
const char *name)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return -EINVAL;
}
static inline bool gpiod_is_shared(const struct gpio_desc *desc)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return false;
}
static inline struct gpio_desc *gpio_to_desc(unsigned gpio)
{
return NULL;
}
static inline int desc_to_gpio(const struct gpio_desc *desc)
{
/* GPIO can never have been requested */
WARN_ON(desc);
return -EINVAL;
}
static inline
struct gpio_desc *fwnode_gpiod_get_index(struct fwnode_handle *fwnode,
const char *con_id, int index,
enum gpiod_flags flags,
const char *label)
{
return ERR_PTR(-ENOSYS);
}
static inline
struct gpio_desc *devm_fwnode_gpiod_get_index(struct device *dev,
struct fwnode_handle *fwnode,
const char *con_id, int index,
enum gpiod_flags flags,
const char *label)
{
return ERR_PTR(-ENOSYS);
}
static inline bool
gpiod_is_equal(const struct gpio_desc *desc, const struct gpio_desc *other)
{
WARN_ON(desc || other);
return false;
}
#endif /* CONFIG_GPIOLIB */
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_HTE)
int gpiod_enable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags);
int gpiod_disable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags);
#else
#include <linux/bug.h>
static inline int gpiod_enable_hw_timestamp_ns(struct gpio_desc *desc,
unsigned long flags)
{
if (!IS_ENABLED(CONFIG_GPIOLIB))
WARN_ON(desc);
return -ENOSYS;
}
static inline int gpiod_disable_hw_timestamp_ns(struct gpio_desc *desc,
unsigned long flags)
{
if (!IS_ENABLED(CONFIG_GPIOLIB))
WARN_ON(desc);
return -ENOSYS;
}
#endif /* CONFIG_GPIOLIB && CONFIG_HTE */
static inline
struct gpio_desc *devm_fwnode_gpiod_get(struct device *dev,
struct fwnode_handle *fwnode,
const char *con_id,
enum gpiod_flags flags,
const char *label)
{
return devm_fwnode_gpiod_get_index(dev, fwnode, con_id, 0,
flags, label);
}
/**
* devm_fwnode_gpiod_get_optional - obtain an optional GPIO from firmware node
* @dev: GPIO consumer
* @fwnode: handle of the firmware node
* @con_id: function within the GPIO consumer
* @flags: GPIO initialization flags
* @label: label to attach to the requested GPIO
*
* This function can be used for drivers that get their configuration
* from opaque firmware.
*
* GPIO descriptors returned from this function are automatically disposed on
* driver detach.
*
* Returns:
* The GPIO descriptor corresponding to the optional function @con_id of device
* dev, NULL if no GPIO has been assigned to the requested function, or
* another IS_ERR() code if an error occurred while trying to acquire the GPIO.
*/
static inline
struct gpio_desc *devm_fwnode_gpiod_get_optional(struct device *dev,
struct fwnode_handle *fwnode,
const char *con_id,
enum gpiod_flags flags,
const char *label)
{
struct gpio_desc *desc;
desc = devm_fwnode_gpiod_get_index(dev, fwnode, con_id, 0,
flags, label);
if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT)
return NULL;
return desc;
}
struct acpi_gpio_params {
unsigned int crs_entry_index;
unsigned short line_index;
bool active_low;
};
struct acpi_gpio_mapping {
const char *name;
const struct acpi_gpio_params *data;
unsigned int size;
/* Ignore IoRestriction field */
#define ACPI_GPIO_QUIRK_NO_IO_RESTRICTION BIT(0)
/*
* When ACPI GPIO mapping table is in use the index parameter inside it
* refers to the GPIO resource in _CRS method. That index has no
* distinction of actual type of the resource. When consumer wants to
* get GpioIo type explicitly, this quirk may be used.
*/
#define ACPI_GPIO_QUIRK_ONLY_GPIOIO BIT(1)
/* Use given pin as an absolute GPIO number in the system */
#define ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER BIT(2)
unsigned int quirks;
};
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_ACPI)
int acpi_dev_add_driver_gpios(struct acpi_device *adev,
const struct acpi_gpio_mapping *gpios);
void acpi_dev_remove_driver_gpios(struct acpi_device *adev);
int devm_acpi_dev_add_driver_gpios(struct device *dev,
const struct acpi_gpio_mapping *gpios);
#else /* CONFIG_GPIOLIB && CONFIG_ACPI */
static inline int acpi_dev_add_driver_gpios(struct acpi_device *adev,
const struct acpi_gpio_mapping *gpios)
{
return -ENXIO;
}
static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev) {}
static inline int devm_acpi_dev_add_driver_gpios(struct device *dev,
const struct acpi_gpio_mapping *gpios)
{
return -ENXIO;
}
#endif /* CONFIG_GPIOLIB && CONFIG_ACPI */
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
int gpiod_export_link(struct device *dev, const char *name,
struct gpio_desc *desc);
void gpiod_unexport(struct gpio_desc *desc);
#else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
static inline int gpiod_export(struct gpio_desc *desc,
bool direction_may_change)
{
return -ENOSYS;
}
static inline int gpiod_export_link(struct device *dev, const char *name,
struct gpio_desc *desc)
{
return -ENOSYS;
}
static inline void gpiod_unexport(struct gpio_desc *desc)
{
}
#endif /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
static inline int gpiod_multi_set_value_cansleep(struct gpio_descs *descs,
unsigned long *value_bitmap)
{
if (IS_ERR_OR_NULL(descs))
return PTR_ERR_OR_ZERO(descs);
return gpiod_set_array_value_cansleep(descs->ndescs, descs->desc,
descs->info, value_bitmap);
}
#endif
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_GPIO_DEFS_H
#define __LINUX_GPIO_DEFS_H
#define GPIO_LINE_DIRECTION_IN 1
#define GPIO_LINE_DIRECTION_OUT 0
#endif /* __LINUX_GPIO_DEFS_H */
@@ -0,0 +1,911 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_GPIO_DRIVER_H
#define __LINUX_GPIO_DRIVER_H
#include <linux/bits.h>
#include <linux/cleanup.h>
#include <linux/err.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/irqhandler.h>
#include <linux/lockdep.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/property.h>
#include <linux/spinlock_types.h>
#include <linux/types.h>
#include <linux/util_macros.h>
#ifdef CONFIG_GENERIC_MSI_IRQ
#include <asm/msi.h>
#endif
#include "defs.h"
struct device;
struct irq_chip;
struct irq_data;
struct module;
struct of_phandle_args;
struct pinctrl_dev;
struct seq_file;
struct gpio_chip;
struct gpio_desc;
struct gpio_device;
enum gpio_lookup_flags;
enum gpiod_flags;
union gpio_irq_fwspec {
struct irq_fwspec fwspec;
#ifdef CONFIG_GENERIC_MSI_IRQ
msi_alloc_info_t msiinfo;
#endif
};
/**
* 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;
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
/**
* @fwnode:
*
* Firmware node corresponding to this gpiochip/irqchip, necessary
* for hierarchical irqdomain support.
*/
struct fwnode_handle *fwnode;
/**
* @parent_domain:
*
* If non-NULL, will be set as the parent of this GPIO interrupt
* controller's IRQ domain to establish a hierarchical interrupt
* domain. The presence of this will activate the hierarchical
* interrupt support.
*/
struct irq_domain *parent_domain;
/**
* @child_to_parent_hwirq:
*
* This callback translates a child hardware IRQ offset to a parent
* hardware IRQ offset on a hierarchical interrupt chip. The child
* hardware IRQs correspond to the GPIO index 0..ngpio-1 (see the
* ngpio field of struct gpio_chip) and the corresponding parent
* hardware IRQ and type (such as IRQ_TYPE_*) shall be returned by
* the driver. The driver can calculate this from an offset or using
* a lookup table or whatever method is best for this chip. Return
* 0 on successful translation in the driver.
*
* If some ranges of hardware IRQs do not have a corresponding parent
* HWIRQ, return -EINVAL, but also make sure to fill in @valid_mask and
* @need_valid_mask to make these GPIO lines unavailable for
* translation.
*/
int (*child_to_parent_hwirq)(struct gpio_chip *gc,
unsigned int child_hwirq,
unsigned int child_type,
unsigned int *parent_hwirq,
unsigned int *parent_type);
/**
* @populate_parent_alloc_arg :
*
* This optional callback allocates and populates the specific struct
* for the parent's IRQ domain. If this is not specified, then
* &gpiochip_populate_parent_fwspec_twocell will be used. A four-cell
* variant named &gpiochip_populate_parent_fwspec_fourcell is also
* available.
*/
int (*populate_parent_alloc_arg)(struct gpio_chip *gc,
union gpio_irq_fwspec *fwspec,
unsigned int parent_hwirq,
unsigned int parent_type);
/**
* @child_offset_to_irq:
*
* This optional callback is used to translate the child's GPIO line
* offset on the GPIO chip to an IRQ number for the GPIO to_irq()
* callback. If this is not specified, then a default callback will be
* provided that returns the line offset.
*/
unsigned int (*child_offset_to_irq)(struct gpio_chip *gc,
unsigned int pin);
/**
* @child_irq_domain_ops:
*
* The IRQ domain operations that will be used for this GPIO IRQ
* chip. If no operations are provided, then default callbacks will
* be populated to setup the IRQ hierarchy. Some drivers need to
* supply their own translate function.
*/
struct irq_domain_ops child_irq_domain_ops;
#endif
/**
* @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 for IRQ lock.
*/
struct lock_class_key *lock_key;
/**
* @request_key:
*
* Per GPIO IRQ chip lockdep class for IRQ request.
*/
struct lock_class_key *request_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;
union {
/**
* @parent_handler_data:
*
* If @per_parent_data is false, @parent_handler_data is a
* single pointer used as the data associated with every
* parent interrupt.
*/
void *parent_handler_data;
/**
* @parent_handler_data_array:
*
* If @per_parent_data is true, @parent_handler_data_array is
* an array of @num_parents pointers, and is used to associate
* different data for each parent. This cannot be NULL if
* @per_parent_data is true.
*/
void **parent_handler_data_array;
};
/**
* @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;
/**
* @per_parent_data:
*
* True if parent_handler_data_array describes a @num_parents
* sized array to be used as parent data.
*/
bool per_parent_data;
/**
* @initialized:
*
* Flag to track GPIO chip irq member's initialization.
* This flag will make sure GPIO chip irq members are not used
* before they are initialized.
*/
bool initialized;
/**
* @domain_is_allocated_externally:
*
* True it the irq_domain was allocated outside of gpiolib, in which
* case gpiolib won't free the irq_domain itself.
*/
bool domain_is_allocated_externally;
/**
* @init_hw: optional routine to initialize hardware before
* an IRQ chip will be added. This is quite useful when
* a particular driver wants to clear IRQ related registers
* in order to avoid undesired events.
*/
int (*init_hw)(struct gpio_chip *gc);
/**
* @init_valid_mask: optional routine to initialize @valid_mask, to be
* used if not all GPIO lines are valid interrupts. Sometimes some
* lines just cannot fire interrupts, and this routine, when defined,
* is passed a bitmap in "valid_mask" and it will have ngpios
* bits from 0..(ngpios-1) set to "1" as in valid. The callback can
* then directly set some bits to "0" if they cannot be used for
* interrupts.
*/
void (*init_valid_mask)(struct gpio_chip *gc,
unsigned long *valid_mask,
unsigned int ngpios);
/**
* @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_create_simple() will allocate and map all IRQs
* during initialization.
*/
unsigned int first;
/**
* @irq_enable:
*
* Store old irq_chip irq_enable callback
*/
void (*irq_enable)(struct irq_data *data);
/**
* @irq_disable:
*
* Store old irq_chip irq_disable callback
*/
void (*irq_disable)(struct irq_data *data);
/**
* @irq_unmask:
*
* Store old irq_chip irq_unmask callback
*/
void (*irq_unmask)(struct irq_data *data);
/**
* @irq_mask:
*
* Store old irq_chip irq_mask callback
*/
void (*irq_mask)(struct irq_data *data);
};
/**
* struct gpio_chip - abstract a GPIO controller
* @label: a functional name for the GPIO device, such as a part
* number or the name of the SoC IP-block implementing it.
* @gpiodev: the internal state holder, opaque struct
* @parent: optional parent device providing the GPIOs
* @fwnode: optional fwnode providing this controller's properties
* @owner: helps prevent removal of modules exporting active GPIOs
* @request: optional hook for chip-specific activation, such as
* enabling module power and clock; may sleep; must return 0 on success
* or negative error number on failure
* @free: optional hook for chip-specific deactivation, such as
* disabling module power and clock; may sleep
* @get_direction: returns direction for signal "offset", 0=out, 1=in,
* (same as GPIO_LINE_DIRECTION_OUT / GPIO_LINE_DIRECTION_IN),
* or negative error. It is recommended to always implement this
* function, even on input-only or output-only gpio chips.
* @direction_input: configures signal "offset" as input, returns 0 on success
* or a negative error number. This can be omitted on input-only or
* output-only gpio chips.
* @direction_output: configures signal "offset" as output, returns 0 on
* success or a negative error number. This can be omitted on input-only
* or output-only gpio chips.
* @get: returns value for signal "offset", 0=low, 1=high, or negative error.
* the low and high values are defined as physical low on the line
* in/out to the connector such as a physical pad, pin or rail. The GPIO
* library has internal logic to handle lines that are active low, such
* as indicated by overstrike or #name in a schematic, and the driver
* should not try to second-guess the logic value of a line.
* @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", returns 0 on success or
* negative error value. The output value follows the same semantic
* rules as for @get.
* @set_multiple: assigns output values for multiple signals defined by
* "mask", returns 0 on success or negative error value
* @set_config: optional hook for all kinds of settings. Uses the same
* packed config format as generic pinconf. Must return 0 on success and
* a negative error number on failure.
* @to_irq: optional hook supporting non-static gpiod_to_irq() mappings;
* implementation may not sleep
* @dbg_show: optional routine to show contents in debugfs; default code
* will be used when this is omitted, but custom code can show extra
* state (such as pullup/pulldown configuration).
* @init_valid_mask: optional routine to initialize @valid_mask, to be used if
* not all GPIOs are valid.
* @add_pin_ranges: optional routine to initialize pin ranges, to be used when
* requires special mapping of the pins that provides GPIO functionality.
* It is called after adding GPIO chip and before adding IRQ chip.
* @en_hw_timestamp: Dependent on GPIO chip, an optional routine to
* enable hardware timestamp.
* @dis_hw_timestamp: Dependent on GPIO chip, an optional routine to
* disable hardware timestamp.
* @base: identifies the first GPIO number handled by this chip;
* or, if negative during registration, requests dynamic ID allocation.
* DEPRECATION: providing anything non-negative and nailing the base
* offset of GPIO chips is deprecated. Please pass -1 as base to
* let gpiolib select the chip base in all possible cases. We want to
* get rid of the static GPIO number space in the long run.
* @ngpio: the number of GPIOs handled by this controller; the last GPIO
* handled is (base + ngpio - 1).
* @offset: when multiple gpio chips belong to the same device this
* can be used as offset within the device so friendly names can
* be properly assigned.
* @names: if set, must be an array of strings to use as alternative
* names for the GPIOs in this chip. Any entry in the array
* may be NULL if there is no alias for the GPIO, however the
* array must be @ngpio entries long.
* @can_sleep: flag must be set iff get()/set() methods sleep, as they
* must while accessing GPIO expander chips over I2C or SPI. This
* implies that if the chip supports IRQs, these IRQs need to be threaded
* as the chip access may sleep when e.g. reading out the IRQ status
* registers.
*
* A gpio_chip can help platforms abstract various sources of GPIOs so
* they can all be accessed through a common programming interface.
* Example sources would be SOC controllers, FPGAs, multifunction
* chips, dedicated GPIO expanders, and so on.
*
* Each chip controls a number of signals, identified in method calls
* by "offset" values in the range 0..(@ngpio - 1). When those signals
* are referenced through calls like gpio_get_value(gpio), the offset
* is calculated by subtracting @base from the gpio number.
*/
struct gpio_chip {
const char *label;
struct gpio_device *gpiodev;
struct device *parent;
struct fwnode_handle *fwnode;
struct module *owner;
int (*request)(struct gpio_chip *gc,
unsigned int offset);
void (*free)(struct gpio_chip *gc,
unsigned int offset);
int (*get_direction)(struct gpio_chip *gc,
unsigned int offset);
int (*direction_input)(struct gpio_chip *gc,
unsigned int offset);
int (*direction_output)(struct gpio_chip *gc,
unsigned int offset, int value);
int (*get)(struct gpio_chip *gc,
unsigned int offset);
int (*get_multiple)(struct gpio_chip *gc,
unsigned long *mask,
unsigned long *bits);
int (*set)(struct gpio_chip *gc,
unsigned int offset, int value);
int (*set_multiple)(struct gpio_chip *gc,
unsigned long *mask,
unsigned long *bits);
int (*set_config)(struct gpio_chip *gc,
unsigned int offset,
unsigned long config);
int (*to_irq)(struct gpio_chip *gc,
unsigned int offset);
void (*dbg_show)(struct seq_file *s,
struct gpio_chip *gc);
int (*init_valid_mask)(struct gpio_chip *gc,
unsigned long *valid_mask,
unsigned int ngpios);
int (*add_pin_ranges)(struct gpio_chip *gc);
int (*en_hw_timestamp)(struct gpio_chip *gc,
u32 offset,
unsigned long flags);
int (*dis_hw_timestamp)(struct gpio_chip *gc,
u32 offset,
unsigned long flags);
int base;
u16 ngpio;
u16 offset;
const char *const *names;
bool can_sleep;
#ifdef CONFIG_GPIOLIB_IRQCHIP
/*
* With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib
* to handle IRQs for most practical cases.
*/
/**
* @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 /* CONFIG_GPIOLIB_IRQCHIP */
#if defined(CONFIG_OF_GPIO)
/*
* If CONFIG_OF_GPIO is enabled, then all GPIO controllers described in
* the device tree automatically may have an OF translation
*/
/**
* @of_gpio_n_cells:
*
* Number of cells used to form the GPIO specifier. The standard is 2
* cells:
*
* gpios = <&gpio offset flags>;
*
* some complex GPIO controllers instantiate more than one chip per
* device tree node and have 3 cells:
*
* gpios = <&gpio instance offset flags>;
*
* Legacy GPIO controllers may even have 1 cell:
*
* gpios = <&gpio offset>;
*/
unsigned int of_gpio_n_cells;
/**
* @of_node_instance_match:
*
* Determine if a chip is the right instance. Must be implemented by
* any driver using more than one gpio_chip per device tree node.
* Returns true if gc is the instance indicated by i (which is the
* first cell in the phandles for GPIO lines and gpio-ranges).
*/
bool (*of_node_instance_match)(struct gpio_chip *gc, unsigned int i);
/**
* @of_xlate:
*
* Callback to translate a device tree GPIO specifier into a chip-
* relative GPIO number and flags.
*/
int (*of_xlate)(struct gpio_chip *gc,
const struct of_phandle_args *gpiospec, u32 *flags);
#endif /* CONFIG_OF_GPIO */
};
char *gpiochip_dup_line_label(struct gpio_chip *gc, unsigned int offset);
struct _gpiochip_for_each_data {
const char **label;
unsigned int *i;
};
DEFINE_CLASS(_gpiochip_for_each_data,
struct _gpiochip_for_each_data,
if (*_T.label) kfree(*_T.label),
({
struct _gpiochip_for_each_data _data = { label, i };
*_data.i = 0;
_data;
}),
const char **label, int *i)
/**
* for_each_hwgpio_in_range - Iterates over all GPIOs in a given range
* @_chip: Chip to iterate over.
* @_i: Loop counter.
* @_base: First GPIO in the ranger.
* @_size: Amount of GPIOs to check starting from @base.
* @_label: Place to store the address of the label if the GPIO is requested.
* Set to NULL for unused GPIOs.
*/
#define for_each_hwgpio_in_range(_chip, _i, _base, _size, _label) \
for (CLASS(_gpiochip_for_each_data, _data)(&_label, &_i); \
_i < _size; \
_i++, kfree(_label), _label = NULL) \
for_each_if(!IS_ERR(_label = gpiochip_dup_line_label(_chip, _base + _i)))
/**
* for_each_hwgpio - Iterates over all GPIOs for given chip.
* @_chip: Chip to iterate over.
* @_i: Loop counter.
* @_label: Place to store the address of the label if the GPIO is requested.
* Set to NULL for unused GPIOs.
*/
#define for_each_hwgpio(_chip, _i, _label) \
for_each_hwgpio_in_range(_chip, _i, 0, _chip->ngpio, _label)
/**
* for_each_requested_gpio_in_range - iterates over requested GPIOs in a given range
* @_chip: the chip to query
* @_i: loop variable
* @_base: first GPIO in the range
* @_size: amount of GPIOs to check starting from @base
* @_label: label of current GPIO
*/
#define for_each_requested_gpio_in_range(_chip, _i, _base, _size, _label) \
for_each_hwgpio_in_range(_chip, _i, _base, _size, _label) \
for_each_if(_label)
/* Iterates over all requested GPIO of the given @chip */
#define for_each_requested_gpio(chip, i, label) \
for_each_requested_gpio_in_range(chip, i, 0, chip->ngpio, label)
/* add/remove chips */
int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
struct lock_class_key *lock_key,
struct lock_class_key *request_key);
/**
* gpiochip_add_data() - register a gpio_chip
* @gc: the chip to register, with gc->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 gc->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,
* i.e. after core_initcall().
*
* If gc->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
* gc->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(gc, data) ({ \
static struct lock_class_key lock_key; \
static struct lock_class_key request_key; \
gpiochip_add_data_with_key(gc, data, &lock_key, \
&request_key); \
})
#define devm_gpiochip_add_data(dev, gc, data) ({ \
static struct lock_class_key lock_key; \
static struct lock_class_key request_key; \
devm_gpiochip_add_data_with_key(dev, gc, data, &lock_key, \
&request_key); \
})
#else
#define gpiochip_add_data(gc, data) gpiochip_add_data_with_key(gc, data, NULL, NULL)
#define devm_gpiochip_add_data(dev, gc, data) \
devm_gpiochip_add_data_with_key(dev, gc, data, NULL, NULL)
#endif /* CONFIG_LOCKDEP */
void gpiochip_remove(struct gpio_chip *gc);
int devm_gpiochip_add_data_with_key(struct device *dev, struct gpio_chip *gc,
void *data, struct lock_class_key *lock_key,
struct lock_class_key *request_key);
struct gpio_device *gpio_device_find(const void *data,
int (*match)(struct gpio_chip *gc,
const void *data));
struct gpio_device *gpio_device_get(struct gpio_device *gdev);
void gpio_device_put(struct gpio_device *gdev);
DEFINE_FREE(gpio_device_put, struct gpio_device *,
if (!IS_ERR_OR_NULL(_T)) gpio_device_put(_T))
struct device *gpio_device_to_device(struct gpio_device *gdev);
bool gpiochip_line_is_irq(struct gpio_chip *gc, unsigned int offset);
int gpiochip_reqres_irq(struct gpio_chip *gc, unsigned int offset);
void gpiochip_relres_irq(struct gpio_chip *gc, unsigned int offset);
void gpiochip_disable_irq(struct gpio_chip *gc, unsigned int offset);
void gpiochip_enable_irq(struct gpio_chip *gc, unsigned int offset);
/* irq_data versions of the above */
int gpiochip_irq_reqres(struct irq_data *data);
void gpiochip_irq_relres(struct irq_data *data);
/* Paste this in your irq_chip structure */
#define GPIOCHIP_IRQ_RESOURCE_HELPERS \
.irq_request_resources = gpiochip_irq_reqres, \
.irq_release_resources = gpiochip_irq_relres
static inline void gpio_irq_chip_set_chip(struct gpio_irq_chip *girq,
const struct irq_chip *chip)
{
/* Yes, dropping const is ugly, but it isn't like we have a choice */
girq->chip = (struct irq_chip *)chip;
}
/* Line status inquiry for drivers */
bool gpiochip_line_is_open_drain(struct gpio_chip *gc, unsigned int offset);
bool gpiochip_line_is_open_source(struct gpio_chip *gc, unsigned int offset);
/* Sleep persistence inquiry for drivers */
bool gpiochip_line_is_persistent(struct gpio_chip *gc, unsigned int offset);
bool gpiochip_line_is_valid(const struct gpio_chip *gc, unsigned int offset);
const unsigned long *gpiochip_query_valid_mask(const struct gpio_chip *gc);
/* get driver data */
void *gpiochip_get_data(struct gpio_chip *gc);
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
int gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *gc,
union gpio_irq_fwspec *gfwspec,
unsigned int parent_hwirq,
unsigned int parent_type);
int gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *gc,
union gpio_irq_fwspec *gfwspec,
unsigned int parent_hwirq,
unsigned int parent_type);
#endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */
#ifdef CONFIG_GPIOLIB_IRQCHIP
int gpiochip_irqchip_add_domain(struct gpio_chip *gc,
struct irq_domain *domain);
#else
#include <asm/bug.h>
static inline int gpiochip_irqchip_add_domain(struct gpio_chip *gc,
struct irq_domain *domain)
{
WARN_ON(1);
return -EINVAL;
}
#endif
int gpiochip_generic_request(struct gpio_chip *gc, unsigned int offset);
void gpiochip_generic_free(struct gpio_chip *gc, unsigned int offset);
int gpiochip_generic_config(struct gpio_chip *gc, unsigned int offset,
unsigned long config);
/**
* struct gpio_pin_range - pin range controlled by a gpio chip
* @node: list for maintaining set of pin ranges, used internally
* @pctldev: pinctrl device which handles corresponding pins
* @range: actual range of pins controlled by a gpio controller
*/
struct gpio_pin_range {
struct list_head node;
struct pinctrl_dev *pctldev;
struct pinctrl_gpio_range range;
};
#ifdef CONFIG_PINCTRL
int gpiochip_add_pin_range_with_pins(struct gpio_chip *gc,
const char *pinctl_name,
unsigned int gpio_offset,
unsigned int pin_offset,
unsigned int const *pins,
unsigned int npins);
int gpiochip_add_pingroup_range(struct gpio_chip *gc,
struct pinctrl_dev *pctldev,
unsigned int gpio_offset, const char *pin_group);
void gpiochip_remove_pin_ranges(struct gpio_chip *gc);
static inline int
gpiochip_add_pin_range(struct gpio_chip *gc,
const char *pinctl_name,
unsigned int gpio_offset,
unsigned int pin_offset,
unsigned int npins)
{
return gpiochip_add_pin_range_with_pins(gc, pinctl_name, gpio_offset,
pin_offset, NULL, npins);
}
static inline int
gpiochip_add_sparse_pin_range(struct gpio_chip *gc,
const char *pinctl_name,
unsigned int gpio_offset,
unsigned int const *pins,
unsigned int npins)
{
return gpiochip_add_pin_range_with_pins(gc, pinctl_name, gpio_offset, 0,
pins, npins);
}
#else /* ! CONFIG_PINCTRL */
static inline int
gpiochip_add_pin_range_with_pins(struct gpio_chip *gc,
const char *pinctl_name,
unsigned int gpio_offset,
unsigned int pin_offset,
unsigned int npins)
{
return 0;
}
static inline int
gpiochip_add_pin_range(struct gpio_chip *gc, const char *pinctl_name,
unsigned int gpio_offset, unsigned int pin_offset,
unsigned int npins)
{
return 0;
}
static inline int
gpiochip_add_sparse_pin_range(struct gpio_chip *gc,
const char *pinctl_name,
unsigned int gpio_offset,
unsigned int const *pins,
unsigned int npins)
{
return 0;
}
static inline int
gpiochip_add_pingroup_range(struct gpio_chip *gc,
struct pinctrl_dev *pctldev,
unsigned int gpio_offset, const char *pin_group)
{
return 0;
}
static inline void
gpiochip_remove_pin_ranges(struct gpio_chip *gc)
{
}
#endif /* CONFIG_PINCTRL */
struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *gc,
unsigned int hwnum,
const char *label,
enum gpio_lookup_flags lflags,
enum gpiod_flags dflags);
void gpiochip_free_own_desc(struct gpio_desc *desc);
struct gpio_desc *
gpio_device_get_desc(struct gpio_device *gdev, unsigned int hwnum);
struct gpio_chip *gpio_device_get_chip(struct gpio_device *gdev);
#ifdef CONFIG_GPIOLIB
/* lock/unlock as IRQ */
int gpiochip_lock_as_irq(struct gpio_chip *gc, unsigned int offset);
void gpiochip_unlock_as_irq(struct gpio_chip *gc, unsigned int offset);
struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc);
struct gpio_device *gpiod_to_gpio_device(struct gpio_desc *desc);
/* struct gpio_device getters */
int gpio_device_get_base(struct gpio_device *gdev);
const char *gpio_device_get_label(struct gpio_device *gdev);
struct gpio_device *gpio_device_find_by_label(const char *label);
struct gpio_device *gpio_device_find_by_fwnode(const struct fwnode_handle *fwnode);
#else /* CONFIG_GPIOLIB */
#include <asm/bug.h>
static inline struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc)
{
/* GPIO can never have been requested */
WARN_ON(1);
return ERR_PTR(-ENODEV);
}
static inline struct gpio_device *gpiod_to_gpio_device(struct gpio_desc *desc)
{
WARN_ON(1);
return ERR_PTR(-ENODEV);
}
static inline int gpio_device_get_base(struct gpio_device *gdev)
{
WARN_ON(1);
return -ENODEV;
}
static inline const char *gpio_device_get_label(struct gpio_device *gdev)
{
WARN_ON(1);
return NULL;
}
static inline struct gpio_device *gpio_device_find_by_label(const char *label)
{
WARN_ON(1);
return NULL;
}
static inline struct gpio_device *gpio_device_find_by_fwnode(const struct fwnode_handle *fwnode)
{
WARN_ON(1);
return NULL;
}
static inline int gpiochip_lock_as_irq(struct gpio_chip *gc,
unsigned int offset)
{
WARN_ON(1);
return -EINVAL;
}
static inline void gpiochip_unlock_as_irq(struct gpio_chip *gc,
unsigned int offset)
{
WARN_ON(1);
}
#endif /* CONFIG_GPIOLIB */
#define for_each_gpiochip_node(dev, child) \
device_for_each_child_node(dev, child) \
for_each_if(fwnode_property_present(child, "gpio-controller"))
static inline unsigned int gpiochip_node_count(struct device *dev)
{
struct fwnode_handle *child;
unsigned int count = 0;
for_each_gpiochip_node(dev, child)
count++;
return count;
}
static inline struct fwnode_handle *gpiochip_node_get_first(struct device *dev)
{
struct fwnode_handle *fwnode;
for_each_gpiochip_node(dev, fwnode)
return fwnode;
return NULL;
}
#endif /* __LINUX_GPIO_DRIVER_H */
@@ -0,0 +1,41 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_GPIO_FORWARDER_H
#define __LINUX_GPIO_FORWARDER_H
struct gpio_desc;
struct gpio_chip;
struct gpiochip_fwd;
struct gpiochip_fwd *devm_gpiochip_fwd_alloc(struct device *dev,
unsigned int ngpios);
int gpiochip_fwd_desc_add(struct gpiochip_fwd *fwd,
struct gpio_desc *desc, unsigned int offset);
void gpiochip_fwd_desc_free(struct gpiochip_fwd *fwd, unsigned int offset);
int gpiochip_fwd_register(struct gpiochip_fwd *fwd, void *data);
struct gpio_chip *gpiochip_fwd_get_gpiochip(struct gpiochip_fwd *fwd);
void *gpiochip_fwd_get_data(struct gpiochip_fwd *fwd);
int gpiochip_fwd_gpio_request(struct gpiochip_fwd *fwd, unsigned int offset);
int gpiochip_fwd_gpio_get_direction(struct gpiochip_fwd *fwd,
unsigned int offset);
int gpiochip_fwd_gpio_direction_input(struct gpiochip_fwd *fwd,
unsigned int offset);
int gpiochip_fwd_gpio_direction_output(struct gpiochip_fwd *fwd,
unsigned int offset,
int value);
int gpiochip_fwd_gpio_get(struct gpiochip_fwd *fwd, unsigned int offset);
int gpiochip_fwd_gpio_get_multiple(struct gpiochip_fwd *fwd,
unsigned long *mask,
unsigned long *bits);
int gpiochip_fwd_gpio_set(struct gpiochip_fwd *fwd, unsigned int offset,
int value);
int gpiochip_fwd_gpio_set_multiple(struct gpiochip_fwd *fwd,
unsigned long *mask,
unsigned long *bits);
int gpiochip_fwd_gpio_set_config(struct gpiochip_fwd *fwd, unsigned int offset,
unsigned long config);
int gpiochip_fwd_gpio_to_irq(struct gpiochip_fwd *fwd, unsigned int offset);
#endif
@@ -0,0 +1,196 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_GPIO_GENERIC_H
#define __LINUX_GPIO_GENERIC_H
#include <linux/bits.h>
#include <linux/bug.h>
#include <linux/cleanup.h>
#include <linux/container_of.h>
#include <linux/errno.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/gpio/driver.h>
struct device;
#define GPIO_GENERIC_BIG_ENDIAN BIT(0)
#define GPIO_GENERIC_UNREADABLE_REG_SET BIT(1) /* reg_set is unreadable */
#define GPIO_GENERIC_UNREADABLE_REG_DIR BIT(2) /* reg_dir is unreadable */
#define GPIO_GENERIC_BIG_ENDIAN_BYTE_ORDER BIT(3)
#define GPIO_GENERIC_READ_OUTPUT_REG_SET BIT(4) /* reg_set stores output value */
#define GPIO_GENERIC_NO_OUTPUT BIT(5) /* only input */
#define GPIO_GENERIC_NO_SET_ON_INPUT BIT(6)
#define GPIO_GENERIC_PINCTRL_BACKEND BIT(7) /* Call pinctrl direction setters */
#define GPIO_GENERIC_NO_INPUT BIT(8) /* only output */
/**
* struct gpio_generic_chip_config - Generic GPIO chip configuration data
* @dev: Parent device of the new GPIO chip (compulsory).
* @sz: Size (width) of the MMIO registers in bytes, typically 1, 2 or 4.
* @dat: MMIO address for the register to READ the value of the GPIO lines, it
* is expected that a 1 in the corresponding bit in this register means
* the line is asserted.
* @set: MMIO address for the register to SET the value of the GPIO lines, it
* is expected that we write the line with 1 in this register to drive
* the GPIO line high.
* @clr: MMIO address for the register to CLEAR the value of the GPIO lines,
* it is expected that we write the line with 1 in this register to
* drive the GPIO line low. It is allowed to leave this address as NULL,
* in that case the SET register will be assumed to also clear the GPIO
* lines, by actively writing the line with 0.
* @dirout: MMIO address for the register to set the line as OUTPUT. It is
* assumed that setting a line to 1 in this register will turn that
* line into an output line. Conversely, setting the line to 0 will
* turn that line into an input.
* @dirin: MMIO address for the register to set this line as INPUT. It is
* assumed that setting a line to 1 in this register will turn that
* line into an input line. Conversely, setting the line to 0 will
* turn that line into an output.
* @flags: Different flags that will affect the behaviour of the device, such
* as endianness etc.
*/
struct gpio_generic_chip_config {
struct device *dev;
unsigned long sz;
void __iomem *dat;
void __iomem *set;
void __iomem *clr;
void __iomem *dirout;
void __iomem *dirin;
unsigned long flags;
};
/**
* struct gpio_generic_chip - Generic GPIO chip implementation.
* @gc: The underlying struct gpio_chip object, implementing low-level GPIO
* chip routines.
* @read_reg: reader function for generic GPIO
* @write_reg: writer function for generic GPIO
* @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
* @reg_dir_out: direction out setting register for generic GPIO
* @reg_dir_in: direction in setting register for generic GPIO
* @dir_unreadable: indicates that the direction register(s) cannot be read and
* we need to rely on out internal state tracking.
* @pinctrl: the generic GPIO uses a pin control backend.
* @bits: number of register bits used for a generic GPIO
* i.e. <register width> * 8
* @lock: used to lock chip->sdata. Also, this is needed to keep
* shadowed and real data registers writes together.
* @sdata: shadowed data register for generic GPIO to clear/set bits safely.
* @sdir: shadowed direction register for generic GPIO to clear/set direction
* safely. A "1" in this word means the line is set as output.
*/
struct gpio_generic_chip {
struct gpio_chip gc;
unsigned long (*read_reg)(void __iomem *reg);
void (*write_reg)(void __iomem *reg, unsigned long data);
bool be_bits;
void __iomem *reg_dat;
void __iomem *reg_set;
void __iomem *reg_clr;
void __iomem *reg_dir_out;
void __iomem *reg_dir_in;
bool dir_unreadable;
bool pinctrl;
int bits;
raw_spinlock_t lock;
unsigned long sdata;
unsigned long sdir;
};
static inline struct gpio_generic_chip *
to_gpio_generic_chip(struct gpio_chip *gc)
{
return container_of(gc, struct gpio_generic_chip, gc);
}
int gpio_generic_chip_init(struct gpio_generic_chip *chip,
const struct gpio_generic_chip_config *cfg);
/**
* gpio_generic_chip_set() - Set the GPIO line value of the generic GPIO chip.
* @chip: Generic GPIO chip to use.
* @offset: Hardware offset of the line to set.
* @value: New GPIO line value.
*
* Some modules using the generic GPIO chip, need to set line values in their
* direction setters but they don't have access to the gpio-mmio symbols so
* they use the function pointer in struct gpio_chip directly. This is not
* optimal and can lead to crashes at run-time in some instances. This wrapper
* provides a safe interface for users.
*
* Returns: 0 on success, negative error number of failure.
*/
static inline int
gpio_generic_chip_set(struct gpio_generic_chip *chip, unsigned int offset,
int value)
{
if (WARN_ON(!chip->gc.set))
return -EOPNOTSUPP;
return chip->gc.set(&chip->gc, offset, value);
}
/**
* gpio_generic_read_reg() - Read a register using the underlying callback.
* @chip: Generic GPIO chip to use.
* @reg: Register to read.
*
* Returns: value read from register.
*/
static inline unsigned long
gpio_generic_read_reg(struct gpio_generic_chip *chip, void __iomem *reg)
{
if (WARN_ON(!chip->read_reg))
return 0;
return chip->read_reg(reg);
}
/**
* gpio_generic_write_reg() - Write a register using the underlying callback.
* @chip: Generic GPIO chip to use.
* @reg: Register to write to.
* @val: New value to write.
*/
static inline void gpio_generic_write_reg(struct gpio_generic_chip *chip,
void __iomem *reg, unsigned long val)
{
if (WARN_ON(!chip->write_reg))
return;
chip->write_reg(reg, val);
}
#define gpio_generic_chip_lock(gen_gc) \
raw_spin_lock(&(gen_gc)->lock)
#define gpio_generic_chip_unlock(gen_gc) \
raw_spin_unlock(&(gen_gc)->lock)
#define gpio_generic_chip_lock_irqsave(gen_gc, flags) \
raw_spin_lock_irqsave(&(gen_gc)->lock, flags)
#define gpio_generic_chip_unlock_irqrestore(gen_gc, flags) \
raw_spin_unlock_irqrestore(&(gen_gc)->lock, flags)
DEFINE_LOCK_GUARD_1(gpio_generic_lock,
struct gpio_generic_chip,
gpio_generic_chip_lock(_T->lock),
gpio_generic_chip_unlock(_T->lock))
DEFINE_LOCK_GUARD_1(gpio_generic_lock_irqsave,
struct gpio_generic_chip,
gpio_generic_chip_lock_irqsave(_T->lock, _T->flags),
gpio_generic_chip_unlock_irqrestore(_T->lock, _T->flags),
unsigned long flags)
#endif /* __LINUX_GPIO_GENERIC_H */
@@ -0,0 +1,290 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_GPIO_NOMADIK_H
#define __LINUX_GPIO_NOMADIK_H
struct fwnode_handle;
/* Package definitions */
#define PINCTRL_NMK_STN8815 0
#define PINCTRL_NMK_DB8500 1
#define GPIO_BLOCK_SHIFT 5
#define NMK_GPIO_PER_CHIP BIT(GPIO_BLOCK_SHIFT)
#define NMK_MAX_BANKS DIV_ROUND_UP(512, NMK_GPIO_PER_CHIP)
/* Register in the logic block */
#define NMK_GPIO_DAT 0x00
#define NMK_GPIO_DATS 0x04
#define NMK_GPIO_DATC 0x08
#define NMK_GPIO_PDIS 0x0c
#define NMK_GPIO_DIR 0x10
#define NMK_GPIO_DIRS 0x14
#define NMK_GPIO_DIRC 0x18
#define NMK_GPIO_SLPC 0x1c
#define NMK_GPIO_AFSLA 0x20
#define NMK_GPIO_AFSLB 0x24
#define NMK_GPIO_LOWEMI 0x28
#define NMK_GPIO_RIMSC 0x40
#define NMK_GPIO_FIMSC 0x44
#define NMK_GPIO_IS 0x48
#define NMK_GPIO_IC 0x4c
#define NMK_GPIO_RWIMSC 0x50
#define NMK_GPIO_FWIMSC 0x54
#define NMK_GPIO_WKS 0x58
/* These appear in DB8540 and later ASICs */
#define NMK_GPIO_EDGELEVEL 0x5C
#define NMK_GPIO_LEVEL 0x60
/* Pull up/down values */
enum nmk_gpio_pull {
NMK_GPIO_PULL_NONE,
NMK_GPIO_PULL_UP,
NMK_GPIO_PULL_DOWN,
};
/* Sleep mode */
enum nmk_gpio_slpm {
NMK_GPIO_SLPM_INPUT,
NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
NMK_GPIO_SLPM_NOCHANGE,
NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
};
struct nmk_gpio_chip {
struct gpio_chip chip;
void __iomem *addr;
struct clk *clk;
unsigned int bank;
void (*set_ioforce)(bool enable);
spinlock_t lock;
bool sleepmode;
bool is_mobileye_soc;
/* Keep track of configured edges */
u32 edge_rising;
u32 edge_falling;
u32 real_wake;
u32 rwimsc;
u32 fwimsc;
u32 rimsc;
u32 fimsc;
u32 pull_up;
u32 lowemi;
};
/* Alternate functions: function C is set in hw by setting both A and B */
#define NMK_GPIO_ALT_GPIO 0
#define NMK_GPIO_ALT_A 1
#define NMK_GPIO_ALT_B 2
#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
#define NMK_GPIO_ALT_CX_SHIFT 2
#define NMK_GPIO_ALT_C1 ((1<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
#define NMK_GPIO_ALT_C2 ((2<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
#define NMK_GPIO_ALT_C3 ((3<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
#define NMK_GPIO_ALT_C4 ((4<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
#define PRCM_GPIOCR_ALTCX(pin_num,\
altc1_used, altc1_ri, altc1_cb,\
altc2_used, altc2_ri, altc2_cb,\
altc3_used, altc3_ri, altc3_cb,\
altc4_used, altc4_ri, altc4_cb)\
{\
.pin = pin_num,\
.altcx[PRCM_IDX_GPIOCR_ALTC1] = {\
.used = altc1_used,\
.reg_index = altc1_ri,\
.control_bit = altc1_cb\
},\
.altcx[PRCM_IDX_GPIOCR_ALTC2] = {\
.used = altc2_used,\
.reg_index = altc2_ri,\
.control_bit = altc2_cb\
},\
.altcx[PRCM_IDX_GPIOCR_ALTC3] = {\
.used = altc3_used,\
.reg_index = altc3_ri,\
.control_bit = altc3_cb\
},\
.altcx[PRCM_IDX_GPIOCR_ALTC4] = {\
.used = altc4_used,\
.reg_index = altc4_ri,\
.control_bit = altc4_cb\
},\
}
/**
* enum prcm_gpiocr_reg_index - Used to reference a PRCM GPIOCR register address.
*/
enum prcm_gpiocr_reg_index {
PRCM_IDX_GPIOCR1,
PRCM_IDX_GPIOCR2,
PRCM_IDX_GPIOCR3
};
/**
* enum prcm_gpiocr_altcx_index - Used to reference an Other alternate-C function.
*/
enum prcm_gpiocr_altcx_index {
PRCM_IDX_GPIOCR_ALTC1,
PRCM_IDX_GPIOCR_ALTC2,
PRCM_IDX_GPIOCR_ALTC3,
PRCM_IDX_GPIOCR_ALTC4,
PRCM_IDX_GPIOCR_ALTC_MAX,
};
/**
* struct prcm_gpiocr_altcx - Other alternate-C function
* @used: other alternate-C function availability
* @reg_index: PRCM GPIOCR register index used to control the function
* @control_bit: PRCM GPIOCR bit used to control the function
*/
struct prcm_gpiocr_altcx {
bool used:1;
u8 reg_index:2;
u8 control_bit:5;
} __packed;
/**
* struct prcm_gpiocr_altcx_pin_desc - Other alternate-C pin
* @pin: The pin number
* @altcx: array of other alternate-C[1-4] functions
*/
struct prcm_gpiocr_altcx_pin_desc {
unsigned short pin;
struct prcm_gpiocr_altcx altcx[PRCM_IDX_GPIOCR_ALTC_MAX];
};
/**
* struct nmk_function - Nomadik pinctrl mux function
* @name: The name of the function, exported to pinctrl core.
* @groups: An array of pin groups that may select this function.
* @ngroups: The number of entries in @groups.
*/
struct nmk_function {
const char *name;
const char * const *groups;
unsigned int ngroups;
};
/**
* struct nmk_pingroup - describes a Nomadik pin group
* @grp: Generic data of the pin group (name and pins)
* @altsetting: the altsetting to apply to all pins in this group to
* configure them to be used by a function
*/
struct nmk_pingroup {
struct pingroup grp;
int altsetting;
};
#define NMK_PIN_GROUP(a, b) \
{ \
.grp = PINCTRL_PINGROUP(#a, a##_pins, ARRAY_SIZE(a##_pins)), \
.altsetting = b, \
}
/**
* struct nmk_pinctrl_soc_data - Nomadik pin controller per-SoC configuration
* @pins: An array describing all pins the pin controller affects.
* All pins which are also GPIOs must be listed first within the
* array, and be numbered identically to the GPIO controller's
* numbering.
* @npins: The number of entries in @pins.
* @functions: The functions supported on this SoC.
* @nfunctions: The number of entries in @functions.
* @groups: An array describing all pin groups the pin SoC supports.
* @ngroups: The number of entries in @groups.
* @altcx_pins: The pins that support Other alternate-C function on this SoC
* @npins_altcx: The number of Other alternate-C pins
* @prcm_gpiocr_registers: The array of PRCM GPIOCR registers on this SoC
*/
struct nmk_pinctrl_soc_data {
const struct pinctrl_pin_desc *pins;
unsigned int npins;
const struct nmk_function *functions;
unsigned int nfunctions;
const struct nmk_pingroup *groups;
unsigned int ngroups;
const struct prcm_gpiocr_altcx_pin_desc *altcx_pins;
unsigned int npins_altcx;
const u16 *prcm_gpiocr_registers;
};
#ifdef CONFIG_PINCTRL_STN8815
void nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc);
#else
static inline void
nmk_pinctrl_stn8815_init(const struct nmk_pinctrl_soc_data **soc)
{
}
#endif
#ifdef CONFIG_PINCTRL_DB8500
void nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc);
#else
static inline void
nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc)
{
}
#endif
#ifdef CONFIG_PINCTRL_DB8540
void nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc);
#else
static inline void
nmk_pinctrl_db8540_init(const struct nmk_pinctrl_soc_data **soc)
{
}
#endif
struct platform_device;
#ifdef CONFIG_DEBUG_FS
/*
* Symbols declared in gpio-nomadik used by pinctrl-nomadik. If pinctrl-nomadik
* is enabled, then gpio-nomadik is enabled as well; the reverse if not always
* true.
*/
void nmk_gpio_dbg_show_one(struct seq_file *s, struct pinctrl_dev *pctldev,
struct gpio_chip *chip, unsigned int offset);
#else
static inline void nmk_gpio_dbg_show_one(struct seq_file *s,
struct pinctrl_dev *pctldev,
struct gpio_chip *chip,
unsigned int offset)
{
}
#endif
void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
unsigned int offset, int val);
void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip, unsigned int offset,
enum nmk_gpio_slpm mode);
struct nmk_gpio_chip *nmk_gpio_populate_chip(struct fwnode_handle *fwnode,
struct platform_device *pdev);
/* Symbols declared in pinctrl-nomadik used by gpio-nomadik. */
#ifdef CONFIG_PINCTRL_NOMADIK
extern struct nmk_gpio_chip *nmk_gpio_chips[NMK_MAX_BANKS];
extern spinlock_t nmk_gpio_slpm_lock;
int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev,
int gpio);
#endif
#endif /* __LINUX_GPIO_NOMADIK_H */
@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef GPIO_REG_H
#define GPIO_REG_H
#include <linux/types.h>
struct device;
struct irq_domain;
struct gpio_chip;
struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
int base, int num, const char *label, u32 direction, u32 def_out,
const char *const *names, struct irq_domain *irqdom, const int *irqs);
int gpio_reg_resume(struct gpio_chip *gc);
#endif /* GPIO_REG_H */
@@ -0,0 +1,94 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_GPIO_MACHINE_H
#define __LINUX_GPIO_MACHINE_H
#include <linux/types.h>
enum gpio_lookup_flags {
GPIO_ACTIVE_HIGH = (0 << 0),
GPIO_ACTIVE_LOW = (1 << 0),
GPIO_OPEN_DRAIN = (1 << 1),
GPIO_OPEN_SOURCE = (1 << 2),
GPIO_PERSISTENT = (0 << 3),
GPIO_TRANSITORY = (1 << 3),
GPIO_PULL_UP = (1 << 4),
GPIO_PULL_DOWN = (1 << 5),
GPIO_PULL_DISABLE = (1 << 6),
GPIO_LOOKUP_FLAGS_DEFAULT = GPIO_ACTIVE_HIGH | GPIO_PERSISTENT,
};
/**
* struct gpiod_lookup - lookup table
* @key: either the name of the chip the GPIO belongs to, or the GPIO line name
* Note that GPIO line names are not guaranteed to be globally unique,
* so this will use the first match found!
* @chip_hwnum: hardware number (i.e. relative to the chip) of the GPIO, or
* U16_MAX to indicate that @key is a GPIO line name
* @con_id: name of the GPIO from the device's point of view
* @idx: index of the GPIO in case several GPIOs share the same name
* @flags: bitmask of gpio_lookup_flags GPIO_* values
*
* gpiod_lookup is a lookup table for associating GPIOs to specific devices and
* functions using platform data.
*/
struct gpiod_lookup {
const char *key;
u16 chip_hwnum;
const char *con_id;
unsigned int idx;
unsigned long flags;
};
struct gpiod_lookup_table {
struct list_head list;
const char *dev_id;
struct gpiod_lookup table[];
};
/*
* Helper for lookup tables with just one single lookup for a device.
*/
#define GPIO_LOOKUP_SINGLE(_name, _dev_id, _key, _chip_hwnum, _con_id, _flags) \
static struct gpiod_lookup_table _name = { \
.dev_id = _dev_id, \
.table = { \
GPIO_LOOKUP(_key, _chip_hwnum, _con_id, _flags), \
{}, \
}, \
}
/*
* Simple definition of a single GPIO under a con_id
*/
#define GPIO_LOOKUP(_key, _chip_hwnum, _con_id, _flags) \
GPIO_LOOKUP_IDX(_key, _chip_hwnum, _con_id, 0, _flags)
/*
* Use this macro if you need to have several GPIOs under the same con_id.
* Each GPIO needs to use a different index and can be accessed using
* gpiod_get_index()
*/
#define GPIO_LOOKUP_IDX(_key, _chip_hwnum, _con_id, _idx, _flags) \
(struct gpiod_lookup) { \
.key = _key, \
.chip_hwnum = _chip_hwnum, \
.con_id = _con_id, \
.idx = _idx, \
.flags = _flags, \
}
#ifdef CONFIG_GPIOLIB
void gpiod_add_lookup_table(struct gpiod_lookup_table *table);
void gpiod_add_lookup_tables(struct gpiod_lookup_table **tables, size_t n);
void gpiod_remove_lookup_table(struct gpiod_lookup_table *table);
#else /* ! CONFIG_GPIOLIB */
static inline
void gpiod_add_lookup_table(struct gpiod_lookup_table *table) {}
static inline
void gpiod_add_lookup_tables(struct gpiod_lookup_table **tables, size_t n) {}
static inline
void gpiod_remove_lookup_table(struct gpiod_lookup_table *table) {}
#endif /* CONFIG_GPIOLIB */
#endif /* __LINUX_GPIO_MACHINE_H */
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: GPL-2.0+
#ifndef __LINUX_GPIO_PROPERTY_H
#define __LINUX_GPIO_PROPERTY_H
#include <linux/property.h>
struct software_node;
#define PROPERTY_ENTRY_GPIO(_name_, _chip_node_, _idx_, _flags_) \
PROPERTY_ENTRY_REF(_name_, _chip_node_, _idx_, _flags_)
extern const struct software_node swnode_gpio_undefined;
#endif /* __LINUX_GPIO_PROPERTY_H */
@@ -0,0 +1,117 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _LINUX_GPIO_REGMAP_H
#define _LINUX_GPIO_REGMAP_H
struct device;
struct fwnode_handle;
struct gpio_regmap;
struct gpio_chip;
struct irq_domain;
struct regmap;
#define GPIO_REGMAP_ADDR_ZERO ((unsigned int)(-1))
#define GPIO_REGMAP_ADDR(addr) ((addr) ? : GPIO_REGMAP_ADDR_ZERO)
/**
* struct gpio_regmap_config - Description of a generic regmap gpio_chip.
* @parent: The parent device
* @regmap: The regmap used to access the registers
* given, the name of the device is used
* @fwnode: (Optional) The firmware node.
* If not given, the fwnode of the parent is used.
* @label: (Optional) Descriptive name for GPIO controller.
* If not given, the name of the device is used.
* @ngpio: (Optional) Number of GPIOs
* @names: (Optional) Array of names for gpios
* @reg_dat_base: (Optional) (in) register base address
* @reg_set_base: (Optional) set register base address
* @reg_clr_base: (Optional) clear register base address
* @reg_dir_in_base: (Optional) in setting register base address
* @reg_dir_out_base: (Optional) out setting register base address
* @reg_stride: (Optional) May be set if the registers (of the
* same type, dat, set, etc) are not consecutive.
* @ngpio_per_reg: (Optional) Number of GPIOs per register
* @irq_domain: (Optional) IRQ domain if the controller is
* interrupt-capable
* @reg_mask_xlate: (Optional) Translates base address and GPIO
* offset to a register/bitmask pair. If not
* given the default gpio_regmap_simple_xlate()
* is used.
* @fixed_direction_output:
* (Optional) Bitmap representing the fixed direction of
* the GPIO lines. Useful when there are GPIO lines with a
* fixed direction mixed together in the same register.
* @drvdata: (Optional) Pointer to driver specific data which is
* not used by gpio-remap but is provided "as is" to the
* driver callback(s).
* @init_valid_mask: (Optional) Routine to initialize @valid_mask, to be used
* if not all GPIOs are valid.
* @regmap_irq_chip: (Optional) Pointer on an regmap_irq_chip structure. If
* set, a regmap-irq device will be created and the IRQ
* domain will be set accordingly.
* @regmap_irq_line: (Optional) The IRQ the device uses to signal interrupts.
* @regmap_irq_flags: (Optional) The IRQF_ flags to use for the interrupt.
*
* The ->reg_mask_xlate translates a given base address and GPIO offset to
* register and mask pair. The base address is one of the given register
* base addresses in this structure.
*
* Although all register base addresses are marked as optional, there are
* several rules:
* 1. if you only have @reg_dat_base set, then it is input-only
* 2. if you only have @reg_set_base set, then it is output-only
* 3. if you have either @reg_dir_in_base or @reg_dir_out_base set, then
* you have to set both @reg_dat_base and @reg_set_base
* 4. if you have @reg_set_base set, you may also set @reg_clr_base to have
* two different registers for setting and clearing the output. This is
* also valid for the output-only case.
* 5. @reg_dir_in_base and @reg_dir_out_base are exclusive; is there really
* hardware which has redundant registers?
*
* Note: All base addresses may have the special value %GPIO_REGMAP_ADDR_ZERO
* which forces the address to the value 0.
*/
struct gpio_regmap_config {
struct device *parent;
struct regmap *regmap;
struct fwnode_handle *fwnode;
const char *label;
int ngpio;
const char *const *names;
unsigned int reg_dat_base;
unsigned int reg_set_base;
unsigned int reg_clr_base;
unsigned int reg_dir_in_base;
unsigned int reg_dir_out_base;
int reg_stride;
int ngpio_per_reg;
struct irq_domain *irq_domain;
unsigned long *fixed_direction_output;
#ifdef CONFIG_REGMAP_IRQ
struct regmap_irq_chip *regmap_irq_chip;
int regmap_irq_line;
unsigned long regmap_irq_flags;
#endif
int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int base,
unsigned int offset, unsigned int *reg,
unsigned int *mask);
int (*init_valid_mask)(struct gpio_chip *gc,
unsigned long *valid_mask,
unsigned int ngpios);
void *drvdata;
};
struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config);
void gpio_regmap_unregister(struct gpio_regmap *gpio);
struct gpio_regmap *devm_gpio_regmap_register(struct device *dev,
const struct gpio_regmap_config *config);
void *gpio_regmap_get_drvdata(struct gpio_regmap *gpio);
#endif /* _LINUX_GPIO_REGMAP_H */