#include <linux/anon_inodes.h>
#include <linux/atomic.h>
#include <linux/bitmap.h>
#include <linux/build_bug.h>
#include <linux/cdev.h>
#include <linux/cleanup.h>
#include <linux/compat.h>
#include <linux/compiler.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/file.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/hte.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/kernel.h>
#include <linux/kfifo.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/overflow.h>
#include <linux/pinctrl/consumer.h>
#include <linux/poll.h>
#include <linux/rbtree.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/timekeeping.h>
#include <linux/uaccess.h>
#include <linux/workqueue.h>
#include <uapi/linux/gpio.h>
#include "gpiolib.h"
#include "gpiolib-cdev.h"
static_assert(…);
static_assert(…);
static_assert(…);
static_assert(…);
static_assert(…);
static_assert(…);
static_assert(…);
static_assert(…);
static_assert(…);
static_assert(…);
#ifdef CONFIG_GPIO_CDEV_V1
struct linehandle_state { … };
#define GPIOHANDLE_REQUEST_VALID_FLAGS …
#define GPIOHANDLE_REQUEST_DIRECTION_FLAGS …
static int linehandle_validate_flags(u32 flags)
{ … }
static void linehandle_flags_to_desc_flags(u32 lflags, unsigned long *flagsp)
{ … }
static long linehandle_set_config(struct linehandle_state *lh,
void __user *ip)
{ … }
static long linehandle_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{ … }
#ifdef CONFIG_COMPAT
static long linehandle_ioctl_compat(struct file *file, unsigned int cmd,
unsigned long arg)
{ … }
#endif
static void linehandle_free(struct linehandle_state *lh)
{ … }
static int linehandle_release(struct inode *inode, struct file *file)
{ … }
static const struct file_operations linehandle_fileops = …;
static int linehandle_create(struct gpio_device *gdev, void __user *ip)
{ … }
#endif
struct line { … };
static struct rb_root supinfo_tree = …;
static DEFINE_SPINLOCK(supinfo_lock);
struct linereq { … };
static void supinfo_insert(struct line *line)
{ … }
static void supinfo_erase(struct line *line)
{ … }
static struct line *supinfo_find(struct gpio_desc *desc)
{ … }
static void supinfo_to_lineinfo(struct gpio_desc *desc,
struct gpio_v2_line_info *info)
{ … }
static inline bool line_has_supinfo(struct line *line)
{ … }
static void line_set_debounce_period(struct line *line,
unsigned int debounce_period_us)
{ … }
#define GPIO_V2_LINE_BIAS_FLAGS …
#define GPIO_V2_LINE_DIRECTION_FLAGS …
#define GPIO_V2_LINE_DRIVE_FLAGS …
#define GPIO_V2_LINE_EDGE_FLAGS …
#define GPIO_V2_LINE_FLAG_EDGE_BOTH …
#define GPIO_V2_LINE_VALID_FLAGS …
#define GPIO_V2_LINE_EDGE_DETECTOR_FLAGS …
static int linereq_unregistered_notify(struct notifier_block *nb,
unsigned long action, void *data)
{ … }
static void linereq_put_event(struct linereq *lr,
struct gpio_v2_line_event *le)
{ … }
static u64 line_event_timestamp(struct line *line)
{ … }
static u32 line_event_id(int level)
{ … }
static inline char *make_irq_label(const char *orig)
{ … }
static inline void free_irq_label(const char *label)
{ … }
#ifdef CONFIG_HTE
static enum hte_return process_hw_ts_thread(void *p)
{ … }
static enum hte_return process_hw_ts(struct hte_ts_data *ts, void *p)
{ … }
static int hte_edge_setup(struct line *line, u64 eflags)
{ … }
#else
static int hte_edge_setup(struct line *line, u64 eflags)
{
return 0;
}
#endif
static irqreturn_t edge_irq_thread(int irq, void *p)
{ … }
static irqreturn_t edge_irq_handler(int irq, void *p)
{ … }
static bool debounced_value(struct line *line)
{ … }
static irqreturn_t debounce_irq_handler(int irq, void *p)
{ … }
static void debounce_work_func(struct work_struct *work)
{ … }
static int debounce_setup(struct line *line, unsigned int debounce_period_us)
{ … }
static bool gpio_v2_line_config_debounced(struct gpio_v2_line_config *lc,
unsigned int line_idx)
{ … }
static u32 gpio_v2_line_config_debounce_period(struct gpio_v2_line_config *lc,
unsigned int line_idx)
{ … }
static void edge_detector_stop(struct line *line)
{ … }
static int edge_detector_fifo_init(struct linereq *req)
{ … }
static int edge_detector_setup(struct line *line,
struct gpio_v2_line_config *lc,
unsigned int line_idx, u64 edflags)
{ … }
static int edge_detector_update(struct line *line,
struct gpio_v2_line_config *lc,
unsigned int line_idx, u64 edflags)
{ … }
static u64 gpio_v2_line_config_flags(struct gpio_v2_line_config *lc,
unsigned int line_idx)
{ … }
static int gpio_v2_line_config_output_value(struct gpio_v2_line_config *lc,
unsigned int line_idx)
{ … }
static int gpio_v2_line_flags_validate(u64 flags)
{ … }
static int gpio_v2_line_config_validate(struct gpio_v2_line_config *lc,
unsigned int num_lines)
{ … }
static void gpio_v2_line_config_flags_to_desc_flags(u64 flags,
unsigned long *flagsp)
{ … }
static long linereq_get_values(struct linereq *lr, void __user *ip)
{ … }
static long linereq_set_values(struct linereq *lr, void __user *ip)
{ … }
static long linereq_set_config(struct linereq *lr, void __user *ip)
{ … }
static long linereq_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{ … }
#ifdef CONFIG_COMPAT
static long linereq_ioctl_compat(struct file *file, unsigned int cmd,
unsigned long arg)
{ … }
#endif
static __poll_t linereq_poll(struct file *file,
struct poll_table_struct *wait)
{ … }
static ssize_t linereq_read(struct file *file, char __user *buf,
size_t count, loff_t *f_ps)
{ … }
static void linereq_free(struct linereq *lr)
{ … }
static int linereq_release(struct inode *inode, struct file *file)
{ … }
#ifdef CONFIG_PROC_FS
static void linereq_show_fdinfo(struct seq_file *out, struct file *file)
{ … }
#endif
static const struct file_operations line_fileops = …;
static int linereq_create(struct gpio_device *gdev, void __user *ip)
{ … }
#ifdef CONFIG_GPIO_CDEV_V1
struct lineevent_state { … };
#define GPIOEVENT_REQUEST_VALID_FLAGS …
static __poll_t lineevent_poll(struct file *file,
struct poll_table_struct *wait)
{ … }
static int lineevent_unregistered_notify(struct notifier_block *nb,
unsigned long action, void *data)
{ … }
struct compat_gpioeevent_data { … };
static ssize_t lineevent_read(struct file *file, char __user *buf,
size_t count, loff_t *f_ps)
{ … }
static void lineevent_free(struct lineevent_state *le)
{ … }
static int lineevent_release(struct inode *inode, struct file *file)
{ … }
static long lineevent_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{ … }
#ifdef CONFIG_COMPAT
static long lineevent_ioctl_compat(struct file *file, unsigned int cmd,
unsigned long arg)
{ … }
#endif
static const struct file_operations lineevent_fileops = …;
static irqreturn_t lineevent_irq_thread(int irq, void *p)
{ … }
static irqreturn_t lineevent_irq_handler(int irq, void *p)
{ … }
static int lineevent_create(struct gpio_device *gdev, void __user *ip)
{ … }
static void gpio_v2_line_info_to_v1(struct gpio_v2_line_info *info_v2,
struct gpioline_info *info_v1)
{ … }
static void gpio_v2_line_info_changed_to_v1(
struct gpio_v2_line_info_changed *lic_v2,
struct gpioline_info_changed *lic_v1)
{ … }
#endif
static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
struct gpio_v2_line_info *info)
{ … }
struct gpio_chardev_data { … };
static int chipinfo_get(struct gpio_chardev_data *cdev, void __user *ip)
{ … }
#ifdef CONFIG_GPIO_CDEV_V1
static int lineinfo_ensure_abi_version(struct gpio_chardev_data *cdata,
unsigned int version)
{ … }
static int lineinfo_get_v1(struct gpio_chardev_data *cdev, void __user *ip,
bool watch)
{ … }
#endif
static int lineinfo_get(struct gpio_chardev_data *cdev, void __user *ip,
bool watch)
{ … }
static int lineinfo_unwatch(struct gpio_chardev_data *cdev, void __user *ip)
{ … }
static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{ … }
#ifdef CONFIG_COMPAT
static long gpio_ioctl_compat(struct file *file, unsigned int cmd,
unsigned long arg)
{ … }
#endif
static int lineinfo_changed_notify(struct notifier_block *nb,
unsigned long action, void *data)
{ … }
static int gpio_device_unregistered_notify(struct notifier_block *nb,
unsigned long action, void *data)
{ … }
static __poll_t lineinfo_watch_poll(struct file *file,
struct poll_table_struct *pollt)
{ … }
static ssize_t lineinfo_watch_read(struct file *file, char __user *buf,
size_t count, loff_t *off)
{ … }
static int gpio_chrdev_open(struct inode *inode, struct file *file)
{ … }
static int gpio_chrdev_release(struct inode *inode, struct file *file)
{ … }
static const struct file_operations gpio_fileops = …;
int gpiolib_cdev_register(struct gpio_device *gdev, dev_t devt)
{ … }
void gpiolib_cdev_unregister(struct gpio_device *gdev)
{ … }