drivers/gpio/gpio-virtio.c
Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-virtio.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpio/gpio-virtio.c- Extension
.c- Size
- 17607 bytes
- Lines
- 674
- 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.
- 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/completion.hlinux/dma-mapping.hlinux/err.hlinux/gpio/driver.hlinux/io.hlinux/kernel.hlinux/module.hlinux/mutex.hlinux/spinlock.hlinux/virtio_config.huapi/linux/virtio_gpio.huapi/linux/virtio_ids.h
Detected Declarations
struct virtio_gpio_linestruct vgpio_irq_linestruct virtio_gpiofunction _virtio_gpio_reqfunction virtio_gpio_reqfunction virtio_gpio_freefunction virtio_gpio_get_directionfunction virtio_gpio_direction_inputfunction virtio_gpio_direction_outputfunction virtio_gpio_getfunction virtio_gpio_setfunction virtio_gpio_irq_preparefunction virtio_gpio_irq_enablefunction virtio_gpio_irq_disablefunction virtio_gpio_irq_maskfunction virtio_gpio_irq_unmaskfunction virtio_gpio_irq_set_typefunction virtio_gpio_irq_bus_lockfunction virtio_gpio_irq_bus_sync_unlockfunction ignore_irqfunction virtio_gpio_event_vqfunction virtio_gpio_request_vqfunction virtio_gpio_free_vqsfunction virtio_gpio_alloc_vqsfunction virtio_gpio_probefunction virtio_gpio_remove
Annotated Snippet
struct virtio_gpio_line {
struct mutex lock; /* Protects line operation */
struct completion completion;
unsigned int rxlen;
__dma_from_device_group_begin();
struct virtio_gpio_request req;
struct virtio_gpio_response res;
__dma_from_device_group_end();
};
struct vgpio_irq_line {
u8 type;
bool disabled;
bool masked;
bool queued;
bool update_pending;
bool queue_pending;
__dma_from_device_group_begin();
struct virtio_gpio_irq_request ireq;
struct virtio_gpio_irq_response ires;
__dma_from_device_group_end();
};
struct virtio_gpio {
struct virtio_device *vdev;
struct mutex lock; /* Protects virtqueue operation */
struct gpio_chip gc;
struct virtio_gpio_line *lines;
struct virtqueue *request_vq;
/* irq support */
struct virtqueue *event_vq;
struct mutex irq_lock; /* Protects irq operation */
raw_spinlock_t eventq_lock; /* Protects queuing of the buffer */
struct vgpio_irq_line *irq_lines;
};
static int _virtio_gpio_req(struct virtio_gpio *vgpio, u16 type, u16 gpio,
u8 txvalue, u8 *rxvalue, void *response, u32 rxlen)
{
struct virtio_gpio_line *line = &vgpio->lines[gpio];
struct virtio_gpio_request *req = &line->req;
struct virtio_gpio_response *res = response;
struct scatterlist *sgs[2], req_sg, res_sg;
struct device *dev = &vgpio->vdev->dev;
int ret;
/*
* Prevent concurrent requests for the same line since we have
* pre-allocated request/response buffers for each GPIO line. Moreover
* Linux always accesses a GPIO line sequentially, so this locking shall
* always go through without any delays.
*/
mutex_lock(&line->lock);
req->type = cpu_to_le16(type);
req->gpio = cpu_to_le16(gpio);
req->value = cpu_to_le32(txvalue);
sg_init_one(&req_sg, req, sizeof(*req));
sg_init_one(&res_sg, res, rxlen);
sgs[0] = &req_sg;
sgs[1] = &res_sg;
line->rxlen = 0;
reinit_completion(&line->completion);
/*
* Virtqueue callers need to ensure they don't call its APIs with other
* virtqueue operations at the same time.
*/
mutex_lock(&vgpio->lock);
ret = virtqueue_add_sgs(vgpio->request_vq, sgs, 1, 1, line, GFP_KERNEL);
if (ret) {
dev_err(dev, "failed to add request to vq\n");
mutex_unlock(&vgpio->lock);
goto out;
}
virtqueue_kick(vgpio->request_vq);
mutex_unlock(&vgpio->lock);
wait_for_completion(&line->completion);
if (unlikely(res->status != VIRTIO_GPIO_STATUS_OK)) {
dev_err(dev, "GPIO request failed: %d\n", gpio);
ret = -EINVAL;
Annotation
- Immediate include surface: `linux/completion.h`, `linux/dma-mapping.h`, `linux/err.h`, `linux/gpio/driver.h`, `linux/io.h`, `linux/kernel.h`, `linux/module.h`, `linux/mutex.h`.
- Detected declarations: `struct virtio_gpio_line`, `struct vgpio_irq_line`, `struct virtio_gpio`, `function _virtio_gpio_req`, `function virtio_gpio_req`, `function virtio_gpio_free`, `function virtio_gpio_get_direction`, `function virtio_gpio_direction_input`, `function virtio_gpio_direction_output`, `function virtio_gpio_get`.
- Atlas domain: Driver Families / drivers/gpio.
- 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.