drivers/gpio/gpio-shared-proxy.c
Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-shared-proxy.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpio/gpio-shared-proxy.c- Extension
.c- Size
- 8930 bytes
- Lines
- 344
- Domain
- Driver Families
- Bucket
- drivers/gpio
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- 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/auxiliary_bus.hlinux/cleanup.hlinux/device.hlinux/err.hlinux/gpio/consumer.hlinux/gpio/driver.hlinux/mod_devicetable.hlinux/module.hlinux/string_choices.hlinux/types.hgpiolib-shared.h
Detected Declarations
struct gpio_shared_proxy_datafunction gpio_shared_proxy_set_unlockedfunction gpio_shared_proxy_requestfunction gpio_shared_proxy_freefunction gpio_shared_proxy_set_configfunction gpio_shared_proxy_direction_inputfunction gpio_shared_proxy_direction_outputfunction gpio_shared_proxy_getfunction gpio_shared_proxy_get_cansleepfunction gpio_shared_proxy_do_setfunction gpio_shared_proxy_setfunction gpio_shared_proxy_set_cansleepfunction gpio_shared_proxy_get_directionfunction gpio_shared_proxy_to_irqfunction gpio_shared_proxy_probe
Annotated Snippet
struct gpio_shared_proxy_data {
struct gpio_chip gc;
struct gpio_shared_desc *shared_desc;
struct device *dev;
bool voted_high;
};
static int
gpio_shared_proxy_set_unlocked(struct gpio_shared_proxy_data *proxy,
int (*set_func)(struct gpio_desc *desc, int value),
int value)
{
struct gpio_shared_desc *shared_desc = proxy->shared_desc;
struct gpio_desc *desc = shared_desc->desc;
int ret = 0;
gpio_shared_lockdep_assert(shared_desc);
if (value) {
/* User wants to set value to high. */
if (proxy->voted_high)
/* Already voted for high, nothing to do. */
goto out;
/* Haven't voted for high yet. */
if (!shared_desc->highcnt) {
/*
* Current value is low, need to actually set value
* to high.
*/
ret = set_func(desc, 1);
if (ret)
goto out;
}
shared_desc->highcnt++;
proxy->voted_high = true;
goto out;
}
/* Desired value is low. */
if (!proxy->voted_high)
/* We didn't vote for high, nothing to do. */
goto out;
/* We previously voted for high. */
if (shared_desc->highcnt == 1) {
/* This is the last remaining vote for high, set value to low. */
ret = set_func(desc, 0);
if (ret)
goto out;
}
shared_desc->highcnt--;
proxy->voted_high = false;
out:
if (shared_desc->highcnt)
dev_dbg(proxy->dev,
"Voted for value '%s', effective value is 'high', number of votes for 'high': %u\n",
str_high_low(value), shared_desc->highcnt);
else
dev_dbg(proxy->dev, "Voted for value 'low', effective value is 'low'\n");
return ret;
}
static int gpio_shared_proxy_request(struct gpio_chip *gc, unsigned int offset)
{
struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
struct gpio_shared_desc *shared_desc = proxy->shared_desc;
guard(gpio_shared_desc_lock)(shared_desc);
proxy->shared_desc->usecnt++;
dev_dbg(proxy->dev, "Shared GPIO requested, number of users: %u\n",
proxy->shared_desc->usecnt);
return 0;
}
static void gpio_shared_proxy_free(struct gpio_chip *gc, unsigned int offset)
{
struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
struct gpio_shared_desc *shared_desc = proxy->shared_desc;
int ret;
guard(gpio_shared_desc_lock)(shared_desc);
Annotation
- Immediate include surface: `linux/auxiliary_bus.h`, `linux/cleanup.h`, `linux/device.h`, `linux/err.h`, `linux/gpio/consumer.h`, `linux/gpio/driver.h`, `linux/mod_devicetable.h`, `linux/module.h`.
- Detected declarations: `struct gpio_shared_proxy_data`, `function gpio_shared_proxy_set_unlocked`, `function gpio_shared_proxy_request`, `function gpio_shared_proxy_free`, `function gpio_shared_proxy_set_config`, `function gpio_shared_proxy_direction_input`, `function gpio_shared_proxy_direction_output`, `function gpio_shared_proxy_get`, `function gpio_shared_proxy_get_cansleep`, `function gpio_shared_proxy_do_set`.
- Atlas domain: Driver Families / drivers/gpio.
- Implementation status: source implementation candidate.
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.