drivers/gpio/gpio-tb10x.c
Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-tb10x.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpio/gpio-tb10x.c- Extension
.c- Size
- 6341 bytes
- Lines
- 228
- 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.
- 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/bitops.hlinux/gpio/driver.hlinux/gpio/generic.hlinux/interrupt.hlinux/io.hlinux/irq.hlinux/irqdomain.hlinux/kernel.hlinux/module.hlinux/of.hlinux/of_platform.hlinux/pinctrl/consumer.hlinux/platform_device.hlinux/slab.h
Detected Declarations
struct tb10x_gpiofunction tb10x_reg_readfunction tb10x_gpio_to_irqfunction tb10x_gpio_irq_set_typefunction tb10x_gpio_irq_cascadefunction tb10x_gpio_probefunction tb10x_gpio_remove
Annotated Snippet
struct tb10x_gpio {
void __iomem *base;
struct irq_domain *domain;
int irq;
struct gpio_generic_chip chip;
};
static inline u32 tb10x_reg_read(struct tb10x_gpio *gpio, unsigned int offs)
{
return ioread32(gpio->base + offs);
}
static int tb10x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct tb10x_gpio *tb10x_gpio = gpiochip_get_data(chip);
return irq_create_mapping(tb10x_gpio->domain, offset);
}
static int tb10x_gpio_irq_set_type(struct irq_data *data, unsigned int type)
{
if ((type & IRQF_TRIGGER_MASK) != IRQ_TYPE_EDGE_BOTH) {
pr_err("Only (both) edge triggered interrupts supported.\n");
return -EINVAL;
}
irqd_set_trigger_type(data, type);
return IRQ_SET_MASK_OK;
}
static irqreturn_t tb10x_gpio_irq_cascade(int irq, void *data)
{
struct tb10x_gpio *tb10x_gpio = data;
u32 r = tb10x_reg_read(tb10x_gpio, OFFSET_TO_REG_CHANGE);
u32 m = tb10x_reg_read(tb10x_gpio, OFFSET_TO_REG_INT_EN);
const unsigned long bits = r & m;
int i;
for_each_set_bit(i, &bits, 32)
generic_handle_domain_irq(tb10x_gpio->domain, i);
return IRQ_HANDLED;
}
static int tb10x_gpio_probe(struct platform_device *pdev)
{
struct gpio_generic_chip_config config;
struct tb10x_gpio *tb10x_gpio;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
int ret = -EBUSY;
u32 ngpio;
if (!np)
return -EINVAL;
if (of_property_read_u32(np, "abilis,ngpio", &ngpio))
return -EINVAL;
tb10x_gpio = devm_kzalloc(dev, sizeof(*tb10x_gpio), GFP_KERNEL);
if (tb10x_gpio == NULL)
return -ENOMEM;
tb10x_gpio->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(tb10x_gpio->base))
return PTR_ERR(tb10x_gpio->base);
tb10x_gpio->chip.gc.label =
devm_kasprintf(dev, GFP_KERNEL, "%pOF", pdev->dev.of_node);
if (!tb10x_gpio->chip.gc.label)
return -ENOMEM;
/*
* Initialize generic GPIO with one single register for reading and setting
* the lines, no special set or clear registers and a data direction register
* wher 1 means "output".
*/
config = (struct gpio_generic_chip_config) {
.dev = dev,
.sz = 4,
.dat = tb10x_gpio->base + OFFSET_TO_REG_DATA,
.dirout = tb10x_gpio->base + OFFSET_TO_REG_DDR,
};
ret = gpio_generic_chip_init(&tb10x_gpio->chip, &config);
if (ret) {
dev_err(dev, "unable to init generic GPIO\n");
return ret;
}
Annotation
- Immediate include surface: `linux/bitops.h`, `linux/gpio/driver.h`, `linux/gpio/generic.h`, `linux/interrupt.h`, `linux/io.h`, `linux/irq.h`, `linux/irqdomain.h`, `linux/kernel.h`.
- Detected declarations: `struct tb10x_gpio`, `function tb10x_reg_read`, `function tb10x_gpio_to_irq`, `function tb10x_gpio_irq_set_type`, `function tb10x_gpio_irq_cascade`, `function tb10x_gpio_probe`, `function tb10x_gpio_remove`.
- Atlas domain: Driver Families / drivers/gpio.
- Implementation status: source implementation candidate.
- 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.