drivers/gpio/gpiolib.c
Source file repositories/reference/linux-study-clean/drivers/gpio/gpiolib.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpio/gpiolib.c- Extension
.c- Size
- 150887 bytes
- Lines
- 5549
- Domain
- Driver Families
- Bucket
- drivers/gpio
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/acpi.hlinux/array_size.hlinux/bitmap.hlinux/cleanup.hlinux/compat.hlinux/debugfs.hlinux/device.hlinux/err.hlinux/errno.hlinux/file.hlinux/fs.hlinux/fwnode.hlinux/idr.hlinux/interrupt.hlinux/irq.hlinux/irqdesc.hlinux/kernel.hlinux/list.hlinux/lockdep.hlinux/module.hlinux/nospec.hlinux/of.hlinux/pinctrl/consumer.hlinux/seq_file.hlinux/slab.hlinux/srcu.hlinux/string.hlinux/string_choices.hlinux/gpio.hlinux/gpio/driver.hlinux/gpio/machine.huapi/linux/gpio.h
Detected Declarations
struct gpiolib_seq_privfunction gpio_bus_matchfunction desc_free_labelfunction desc_set_labelfunction scoped_guardfunction gpio_device_get_descfunction desc_to_gpiofunction gpiod_hwgpiofunction gpiod_to_gpio_devicefunction gpio_device_get_basefunction gpio_device_get_labelfunction gpio_device_get_chipfunction gpiochip_find_base_unlockedfunction list_for_each_entry_srcufunction validate_descfunction gpiod_is_equalfunction gpiochip_get_directionfunction gpiod_cansleepfunction gpiod_is_single_endedfunction rangefunction list_for_each_entry_safefunction list_for_each_entry_srcufunction for_each_gpio_descfunction gpiochip_set_desc_namesfunction gpiochip_set_namesfunction gpiochip_free_maskfunction gpiochip_count_reserved_rangesfunction gpiochip_apply_reserved_rangesfunction gpiochip_init_valid_maskfunction gpiochip_free_valid_maskfunction gpiochip_add_pin_rangesfunction gpiochip_line_is_validfunction gpiod_free_irqsfunction free_irqfunction gpiochip_free_remaining_irqsfunction gpiodev_releasefunction gpiolib_cdev_registerfunction gpiochip_add_hogfunction gpiochip_hog_linesfunction device_for_each_child_node_scopedfunction gpiochip_setup_devsfunction list_for_each_entry_srcufunction gpiochip_set_datafunction gpiochip_get_datafunction gpiochip_get_ngpiosfunction gpiochip_add_data_with_keyfunction scoped_guardfunction gpiochip_remove
Annotated Snippet
static int gpio_bus_match(struct device *dev, const struct device_driver *drv)
{
struct fwnode_handle *fwnode = dev_fwnode(dev);
/*
* Only match if the fwnode doesn't already have a proper struct device
* created for it.
*/
if (fwnode && fwnode->dev != dev)
return 0;
return 1;
}
static const struct bus_type gpio_bus_type = {
.name = "gpio",
.match = gpio_bus_match,
};
/*
* At the end we want all GPIOs to be dynamically allocated from 0.
* However, some legacy drivers still perform fixed allocation.
* Until they are all fixed, leave 0-512 space for them.
*/
#define GPIO_DYNAMIC_BASE 512
/*
* Define the maximum of the possible GPIO in the global numberspace.
* While the GPIO base and numbers are positive, we limit it with signed
* maximum as a lot of code is using negative values for special cases.
*/
#define GPIO_DYNAMIC_MAX INT_MAX
/*
* Number of GPIOs to use for the fast path in set array
*/
#define FASTPATH_NGPIO CONFIG_GPIOLIB_FASTPATH_LIMIT
static DEFINE_MUTEX(gpio_lookup_lock);
static LIST_HEAD(gpio_lookup_list);
static LIST_HEAD(gpio_devices);
/* Protects the GPIO device list against concurrent modifications. */
static DEFINE_MUTEX(gpio_devices_lock);
/* Ensures coherence during read-only accesses to the list of GPIO devices. */
DEFINE_STATIC_SRCU(gpio_devices_srcu);
const char *const gpio_suffixes[] = { "gpios", "gpio", NULL };
static void gpiochip_free_hogs(struct gpio_chip *gc);
static int gpiochip_add_irqchip(struct gpio_chip *gc,
struct lock_class_key *lock_key,
struct lock_class_key *request_key);
static void gpiochip_irqchip_remove(struct gpio_chip *gc);
static int gpiochip_irqchip_init_hw(struct gpio_chip *gc);
static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gc);
static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gc);
static bool gpiolib_initialized __ro_after_init;
const char *gpiod_get_label(struct gpio_desc *desc)
{
struct gpio_desc_label *label;
unsigned long flags;
flags = READ_ONCE(desc->flags);
label = srcu_dereference_check(desc->label, &desc->gdev->desc_srcu,
srcu_read_lock_held(&desc->gdev->desc_srcu));
if (test_bit(GPIOD_FLAG_USED_AS_IRQ, &flags))
return label ? label->str : "interrupt";
if (!test_bit(GPIOD_FLAG_REQUESTED, &flags))
return NULL;
return label ? label->str : NULL;
}
static void desc_free_label(struct rcu_head *rh)
{
kfree(container_of(rh, struct gpio_desc_label, rh));
}
static int desc_set_label(struct gpio_desc *desc, const char *label)
{
struct gpio_desc_label *new = NULL, *old;
size_t len;
if (label) {
len = strlen(label);
new = kzalloc_flex(*new, str, len + 1);
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/array_size.h`, `linux/bitmap.h`, `linux/cleanup.h`, `linux/compat.h`, `linux/debugfs.h`, `linux/device.h`, `linux/err.h`.
- Detected declarations: `struct gpiolib_seq_priv`, `function gpio_bus_match`, `function desc_free_label`, `function desc_set_label`, `function scoped_guard`, `function gpio_device_get_desc`, `function desc_to_gpio`, `function gpiod_hwgpio`, `function gpiod_to_gpio_device`, `function gpio_device_get_base`.
- Atlas domain: Driver Families / drivers/gpio.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.