#define pr_fmt(fmt) …
#include <linux/array_size.h>
#include <linux/atomic.h>
#include <linux/bitmap.h>
#include <linux/cleanup.h>
#include <linux/completion.h>
#include <linux/configfs.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/irq_work.h>
#include <linux/limits.h>
#include <linux/list.h>
#include <linux/lockdep.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/notifier.h>
#include <linux/of.h>
#include <linux/overflow.h>
#include <linux/platform_device.h>
#include <linux/printk.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/string_helpers.h>
#include <linux/types.h>
#define GPIO_VIRTUSER_NAME_BUF_LEN …
static DEFINE_IDA(gpio_virtuser_ida);
static struct dentry *gpio_virtuser_dbg_root;
struct gpio_virtuser_attr_data { … };
struct gpio_virtuser_line_array_data { … };
struct gpio_virtuser_line_data { … };
struct gpio_virtuser_dbgfs_attr_descr { … };
struct gpio_virtuser_irq_work_context { … };
static struct gpio_virtuser_irq_work_context *
to_gpio_virtuser_irq_work_context(struct irq_work *work)
{ … }
static void
gpio_virtuser_init_irq_work_context(struct gpio_virtuser_irq_work_context *ctx)
{ … }
static void
gpio_virtuser_irq_work_queue_sync(struct gpio_virtuser_irq_work_context *ctx)
{ … }
static void gpio_virtuser_dbgfs_emit_value_array(char *buf,
unsigned long *values,
size_t num_values)
{ … }
static void gpio_virtuser_get_value_array_atomic(struct irq_work *work)
{ … }
static int gpio_virtuser_get_array_value(struct gpio_descs *descs,
unsigned long *values, bool atomic)
{ … }
static ssize_t gpio_virtuser_value_array_do_read(struct file *file,
char __user *user_buf,
size_t size, loff_t *ppos,
bool atomic)
{ … }
static int gpio_virtuser_dbgfs_parse_value_array(const char *buf,
size_t len,
unsigned long *values)
{ … }
static void gpio_virtuser_set_value_array_atomic(struct irq_work *work)
{ … }
static int gpio_virtuser_set_array_value(struct gpio_descs *descs,
unsigned long *values, bool atomic)
{ … }
static ssize_t gpio_virtuser_value_array_do_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos,
bool atomic)
{ … }
static ssize_t gpio_virtuser_value_array_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static ssize_t gpio_virtuser_value_array_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations gpio_virtuser_value_array_fops = …;
static ssize_t
gpio_virtuser_value_array_atomic_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static ssize_t
gpio_virtuser_value_array_atomic_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations gpio_virtuser_value_array_atomic_fops = …;
static void gpio_virtuser_do_get_direction_atomic(struct irq_work *work)
{ … }
static int gpio_virtuser_get_direction_atomic(struct gpio_desc *desc)
{ … }
static ssize_t gpio_virtuser_direction_do_read(struct file *file,
char __user *user_buf,
size_t size, loff_t *ppos,
bool atomic)
{ … }
static int gpio_virtuser_set_direction(struct gpio_desc *desc, int dir, int val)
{ … }
static void gpio_virtuser_do_set_direction_atomic(struct irq_work *work)
{ … }
static int gpio_virtuser_set_direction_atomic(struct gpio_desc *desc,
int dir, int val)
{ … }
static ssize_t gpio_virtuser_direction_do_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos,
bool atomic)
{ … }
static ssize_t gpio_virtuser_direction_read(struct file *file,
char __user *user_buf,
size_t size, loff_t *ppos)
{ … }
static ssize_t gpio_virtuser_direction_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations gpio_virtuser_direction_fops = …;
static ssize_t gpio_virtuser_direction_atomic_read(struct file *file,
char __user *user_buf,
size_t size, loff_t *ppos)
{ … }
static ssize_t gpio_virtuser_direction_atomic_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations gpio_virtuser_direction_atomic_fops = …;
static int gpio_virtuser_value_get(void *data, u64 *val)
{ … }
static int gpio_virtuser_value_set(void *data, u64 val)
{ … }
DEFINE_DEBUGFS_ATTRIBUTE(…);
static void gpio_virtuser_get_value_atomic(struct irq_work *work)
{ … }
static int gpio_virtuser_value_atomic_get(void *data, u64 *val)
{ … }
static void gpio_virtuser_set_value_atomic(struct irq_work *work)
{ … }
static int gpio_virtuser_value_atomic_set(void *data, u64 val)
{ … }
DEFINE_DEBUGFS_ATTRIBUTE(…);
static int gpio_virtuser_debounce_get(void *data, u64 *val)
{ … }
static int gpio_virtuser_debounce_set(void *data, u64 val)
{ … }
DEFINE_DEBUGFS_ATTRIBUTE(…);
static ssize_t gpio_virtuser_consumer_read(struct file *file,
char __user *user_buf,
size_t size, loff_t *ppos)
{ … }
static ssize_t gpio_virtuser_consumer_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{ … }
static const struct file_operations gpio_virtuser_consumer_fops = …;
static int gpio_virtuser_interrupts_get(void *data, u64 *val)
{ … }
static irqreturn_t gpio_virtuser_irq_handler(int irq, void *data)
{ … }
static int gpio_virtuser_interrupts_set(void *data, u64 val)
{ … }
DEFINE_DEBUGFS_ATTRIBUTE(…);
static const struct gpio_virtuser_dbgfs_attr_descr
gpio_virtuser_line_array_dbgfs_attrs[] = …;
static const struct gpio_virtuser_dbgfs_attr_descr
gpio_virtuser_line_dbgfs_attrs[] = …;
static int gpio_virtuser_create_debugfs_attrs(
const struct gpio_virtuser_dbgfs_attr_descr *attr,
size_t num_attrs, struct dentry *parent, void *data)
{ … }
static int gpio_virtuser_dbgfs_init_line_array_attrs(struct device *dev,
struct gpio_descs *descs,
const char *id,
struct dentry *dbgfs_entry)
{ … }
static int gpio_virtuser_dbgfs_init_line_attrs(struct device *dev,
struct gpio_desc *desc,
const char *id,
unsigned int index,
struct dentry *dbgfs_entry)
{ … }
static void gpio_virtuser_debugfs_remove(void *data)
{ … }
static int gpio_virtuser_prop_is_gpio(struct property *prop)
{ … }
static int gpio_virtuser_count_ids(struct device *dev)
{ … }
static int gpio_virtuser_get_ids(struct device *dev, const char **ids,
int num_ids)
{ … }
static int gpio_virtuser_probe(struct platform_device *pdev)
{ … }
static const struct of_device_id gpio_virtuser_of_match[] = …;
MODULE_DEVICE_TABLE(of, gpio_virtuser_of_match);
static struct platform_driver gpio_virtuser_driver = …;
struct gpio_virtuser_device { … };
static int gpio_virtuser_bus_notifier_call(struct notifier_block *nb,
unsigned long action, void *data)
{ … }
static struct gpio_virtuser_device *
to_gpio_virtuser_device(struct config_item *item)
{ … }
static bool
gpio_virtuser_device_is_live(struct gpio_virtuser_device *dev)
{ … }
struct gpio_virtuser_lookup { … };
static struct gpio_virtuser_lookup *
to_gpio_virtuser_lookup(struct config_item *item)
{ … }
struct gpio_virtuser_lookup_entry { … };
static struct gpio_virtuser_lookup_entry *
to_gpio_virtuser_lookup_entry(struct config_item *item)
{ … }
static ssize_t
gpio_virtuser_lookup_entry_config_key_show(struct config_item *item, char *page)
{ … }
static ssize_t
gpio_virtuser_lookup_entry_config_key_store(struct config_item *item,
const char *page, size_t count)
{ … }
CONFIGFS_ATTR(…);
static ssize_t
gpio_virtuser_lookup_entry_config_offset_show(struct config_item *item,
char *page)
{ … }
static ssize_t
gpio_virtuser_lookup_entry_config_offset_store(struct config_item *item,
const char *page, size_t count)
{ … }
CONFIGFS_ATTR(…);
static enum gpio_lookup_flags
gpio_virtuser_lookup_get_flags(struct config_item *item)
{ … }
static ssize_t
gpio_virtuser_lookup_entry_config_drive_show(struct config_item *item, char *page)
{ … }
static ssize_t
gpio_virtuser_lookup_entry_config_drive_store(struct config_item *item,
const char *page, size_t count)
{ … }
CONFIGFS_ATTR(…);
static ssize_t
gpio_virtuser_lookup_entry_config_pull_show(struct config_item *item, char *page)
{ … }
static ssize_t
gpio_virtuser_lookup_entry_config_pull_store(struct config_item *item,
const char *page, size_t count)
{ … }
CONFIGFS_ATTR(…);
static ssize_t
gpio_virtuser_lookup_entry_config_active_low_show(struct config_item *item,
char *page)
{ … }
static ssize_t
gpio_virtuser_lookup_entry_config_active_low_store(struct config_item *item,
const char *page,
size_t count)
{ … }
CONFIGFS_ATTR(…);
static ssize_t
gpio_virtuser_lookup_entry_config_transitory_show(struct config_item *item,
char *page)
{ … }
static ssize_t
gpio_virtuser_lookup_entry_config_transitory_store(struct config_item *item,
const char *page,
size_t count)
{ … }
CONFIGFS_ATTR(…);
static struct configfs_attribute *gpio_virtuser_lookup_entry_config_attrs[] = …;
static ssize_t
gpio_virtuser_device_config_dev_name_show(struct config_item *item,
char *page)
{ … }
CONFIGFS_ATTR_RO(…);
static ssize_t gpio_virtuser_device_config_live_show(struct config_item *item,
char *page)
{ … }
static size_t
gpio_virtuser_get_lookup_count(struct gpio_virtuser_device *dev)
{ … }
static int
gpio_virtuser_make_lookup_table(struct gpio_virtuser_device *dev)
{ … }
static struct fwnode_handle *
gpio_virtuser_make_device_swnode(struct gpio_virtuser_device *dev)
{ … }
static int
gpio_virtuser_device_activate(struct gpio_virtuser_device *dev)
{ … }
static void
gpio_virtuser_device_deactivate(struct gpio_virtuser_device *dev)
{ … }
static ssize_t
gpio_virtuser_device_config_live_store(struct config_item *item,
const char *page, size_t count)
{ … }
CONFIGFS_ATTR(…);
static struct configfs_attribute *gpio_virtuser_device_config_attrs[] = …;
static void
gpio_virtuser_lookup_entry_config_group_release(struct config_item *item)
{ … }
static struct
configfs_item_operations gpio_virtuser_lookup_entry_config_item_ops = …;
static const struct
config_item_type gpio_virtuser_lookup_entry_config_group_type = …;
static struct config_group *
gpio_virtuser_make_lookup_entry_group(struct config_group *group,
const char *name)
{ … }
static void gpio_virtuser_lookup_config_group_release(struct config_item *item)
{ … }
static struct configfs_item_operations gpio_virtuser_lookup_config_item_ops = …;
static struct
configfs_group_operations gpio_virtuser_lookup_config_group_ops = …;
static const struct config_item_type gpio_virtuser_lookup_config_group_type = …;
static struct config_group *
gpio_virtuser_make_lookup_group(struct config_group *group, const char *name)
{ … }
static void gpio_virtuser_device_config_group_release(struct config_item *item)
{ … }
static struct configfs_item_operations gpio_virtuser_device_config_item_ops = …;
static struct configfs_group_operations gpio_virtuser_device_config_group_ops = …;
static const struct config_item_type gpio_virtuser_device_config_group_type = …;
static struct config_group *
gpio_virtuser_config_make_device_group(struct config_group *group,
const char *name)
{ … }
static struct configfs_group_operations gpio_virtuser_config_group_ops = …;
static const struct config_item_type gpio_virtuser_config_type = …;
static struct configfs_subsystem gpio_virtuser_config_subsys = …;
static int __init gpio_virtuser_init(void)
{ … }
module_init(…) …;
static void __exit gpio_virtuser_exit(void)
{ … }
module_exit(gpio_virtuser_exit);
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;