drivers/staging/greybus/gpio.c
Source file repositories/reference/linux-study-clean/drivers/staging/greybus/gpio.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/staging/greybus/gpio.c- Extension
.c- Size
- 15487 bytes
- Lines
- 626
- Domain
- Driver Families
- Bucket
- drivers/staging
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/kernel.hlinux/module.hlinux/slab.hlinux/irq.hlinux/irqdomain.hlinux/gpio/driver.hlinux/mutex.hlinux/greybus.hgbphy.h
Detected Declarations
struct gb_gpio_linestruct gb_gpio_controllerfunction gb_gpio_line_count_operationfunction gb_gpio_activate_operationfunction gb_gpio_deactivate_operationfunction gb_gpio_get_direction_operationfunction gb_gpio_direction_in_operationfunction gb_gpio_direction_out_operationfunction gb_gpio_get_value_operationfunction gb_gpio_set_value_operationfunction gb_gpio_set_debounce_operationfunction _gb_gpio_irq_maskfunction _gb_gpio_irq_unmaskfunction _gb_gpio_irq_set_typefunction gb_gpio_irq_maskfunction gb_gpio_irq_unmaskfunction gb_gpio_irq_set_typefunction gb_gpio_irq_bus_lockfunction gb_gpio_irq_bus_sync_unlockfunction gb_gpio_request_handlerfunction gb_gpio_requestfunction gb_gpio_freefunction gb_gpio_get_directionfunction gb_gpio_direction_inputfunction gb_gpio_direction_outputfunction gb_gpio_getfunction gb_gpio_setfunction gb_gpio_set_configfunction gb_gpio_controller_setupfunction gb_gpio_probefunction gb_gpio_remove
Annotated Snippet
struct gb_gpio_line {
/* The following has to be an array of line_max entries */
/* --> make them just a flags field */
u8 active: 1,
direction: 1, /* 0 = output, 1 = input */
value: 1; /* 0 = low, 1 = high */
u16 debounce_usec;
u8 irq_type;
bool irq_type_pending;
bool masked;
bool masked_pending;
};
struct gb_gpio_controller {
struct gbphy_device *gbphy_dev;
struct gb_connection *connection;
u8 line_max; /* max line number */
struct gb_gpio_line *lines;
struct gpio_chip chip;
struct irq_chip irqc;
struct mutex irq_lock;
};
static struct gpio_chip *irq_data_to_gpio_chip(struct irq_data *d)
{
return d->domain->host_data;
}
static int gb_gpio_line_count_operation(struct gb_gpio_controller *ggc)
{
struct gb_gpio_line_count_response response;
int ret;
ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_LINE_COUNT,
NULL, 0, &response, sizeof(response));
if (!ret)
ggc->line_max = response.count;
return ret;
}
static int gb_gpio_activate_operation(struct gb_gpio_controller *ggc, u8 which)
{
struct gb_gpio_activate_request request;
struct gbphy_device *gbphy_dev = ggc->gbphy_dev;
int ret;
ret = gbphy_runtime_get_sync(gbphy_dev);
if (ret)
return ret;
request.which = which;
ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_ACTIVATE,
&request, sizeof(request), NULL, 0);
if (ret) {
gbphy_runtime_put_autosuspend(gbphy_dev);
return ret;
}
ggc->lines[which].active = true;
return 0;
}
static void gb_gpio_deactivate_operation(struct gb_gpio_controller *ggc,
u8 which)
{
struct gbphy_device *gbphy_dev = ggc->gbphy_dev;
struct device *dev = &gbphy_dev->dev;
struct gb_gpio_deactivate_request request;
int ret;
request.which = which;
ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_DEACTIVATE,
&request, sizeof(request), NULL, 0);
if (ret) {
dev_err(dev, "failed to deactivate gpio %u\n", which);
goto out_pm_put;
}
ggc->lines[which].active = false;
out_pm_put:
gbphy_runtime_put_autosuspend(gbphy_dev);
}
static int gb_gpio_get_direction_operation(struct gb_gpio_controller *ggc,
u8 which)
{
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/slab.h`, `linux/irq.h`, `linux/irqdomain.h`, `linux/gpio/driver.h`, `linux/mutex.h`, `linux/greybus.h`.
- Detected declarations: `struct gb_gpio_line`, `struct gb_gpio_controller`, `function gb_gpio_line_count_operation`, `function gb_gpio_activate_operation`, `function gb_gpio_deactivate_operation`, `function gb_gpio_get_direction_operation`, `function gb_gpio_direction_in_operation`, `function gb_gpio_direction_out_operation`, `function gb_gpio_get_value_operation`, `function gb_gpio_set_value_operation`.
- Atlas domain: Driver Families / drivers/staging.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.