drivers/gpio/gpio-siox.c
Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-siox.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpio/gpio-siox.c- Extension
.c- Size
- 6432 bytes
- Lines
- 272
- 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/module.hlinux/siox.hlinux/gpio/driver.hlinux/of.h
Detected Declarations
struct gpio_siox_ddatafunction gpio_siox_set_datafunction gpio_siox_get_datafunction gpio_siox_irq_ackfunction gpio_siox_irq_maskfunction gpio_siox_irq_unmaskfunction gpio_siox_irq_set_typefunction gpio_siox_getfunction gpio_siox_setfunction gpio_siox_direction_inputfunction gpio_siox_direction_outputfunction gpio_siox_get_directionfunction gpio_siox_probe
Annotated Snippet
struct gpio_siox_ddata {
struct gpio_chip gchip;
struct mutex lock;
u8 setdata[1];
u8 getdata[3];
raw_spinlock_t irqlock;
u32 irq_enable;
u32 irq_status;
u32 irq_type[20];
};
/*
* Note that this callback only sets the value that is clocked out in the next
* cycle.
*/
static int gpio_siox_set_data(struct siox_device *sdevice, u8 status, u8 buf[])
{
struct gpio_siox_ddata *ddata = dev_get_drvdata(&sdevice->dev);
mutex_lock(&ddata->lock);
buf[0] = ddata->setdata[0];
mutex_unlock(&ddata->lock);
return 0;
}
static int gpio_siox_get_data(struct siox_device *sdevice, const u8 buf[])
{
struct gpio_siox_ddata *ddata = dev_get_drvdata(&sdevice->dev);
size_t offset;
u32 trigger;
mutex_lock(&ddata->lock);
raw_spin_lock_irq(&ddata->irqlock);
for (offset = 0; offset < 12; ++offset) {
unsigned int bitpos = 11 - offset;
unsigned int gpiolevel = buf[bitpos / 8] & (1 << bitpos % 8);
unsigned int prev_level =
ddata->getdata[bitpos / 8] & (1 << (bitpos % 8));
u32 irq_type = ddata->irq_type[offset];
if (gpiolevel) {
if ((irq_type & IRQ_TYPE_LEVEL_HIGH) ||
((irq_type & IRQ_TYPE_EDGE_RISING) && !prev_level))
ddata->irq_status |= 1 << offset;
} else {
if ((irq_type & IRQ_TYPE_LEVEL_LOW) ||
((irq_type & IRQ_TYPE_EDGE_FALLING) && prev_level))
ddata->irq_status |= 1 << offset;
}
}
trigger = ddata->irq_status & ddata->irq_enable;
raw_spin_unlock_irq(&ddata->irqlock);
ddata->getdata[0] = buf[0];
ddata->getdata[1] = buf[1];
ddata->getdata[2] = buf[2];
mutex_unlock(&ddata->lock);
for (offset = 0; offset < 12; ++offset) {
if (trigger & (1 << offset)) {
struct irq_domain *irqdomain = ddata->gchip.irq.domain;
unsigned int irq = irq_find_mapping(irqdomain, offset);
/*
* Conceptually handle_nested_irq should call the flow
* handler of the irq chip. But it doesn't, so we have
* to clean the irq_status here.
*/
raw_spin_lock_irq(&ddata->irqlock);
ddata->irq_status &= ~(1 << offset);
raw_spin_unlock_irq(&ddata->irqlock);
handle_nested_irq(irq);
}
}
return 0;
}
static void gpio_siox_irq_ack(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct gpio_siox_ddata *ddata = gpiochip_get_data(gc);
Annotation
- Immediate include surface: `linux/module.h`, `linux/siox.h`, `linux/gpio/driver.h`, `linux/of.h`.
- Detected declarations: `struct gpio_siox_ddata`, `function gpio_siox_set_data`, `function gpio_siox_get_data`, `function gpio_siox_irq_ack`, `function gpio_siox_irq_mask`, `function gpio_siox_irq_unmask`, `function gpio_siox_irq_set_type`, `function gpio_siox_get`, `function gpio_siox_set`, `function gpio_siox_direction_input`.
- 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.