drivers/gpio/gpio-eic-sprd.c
Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-eic-sprd.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpio/gpio-eic-sprd.c- Extension
.c- Size
- 20911 bytes
- Lines
- 738
- 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/bitops.hlinux/gpio/driver.hlinux/interrupt.hlinux/kernel.hlinux/module.hlinux/notifier.hlinux/platform_device.hlinux/property.hlinux/spinlock.h
Detected Declarations
struct sprd_eicstruct sprd_eic_variant_dataenum sprd_eic_typefunction sprd_eic_updatefunction sprd_eic_readfunction sprd_eic_requestfunction sprd_eic_freefunction sprd_eic_getfunction sprd_eic_direction_inputfunction sprd_eic_setfunction sprd_eic_set_debouncefunction sprd_eic_set_configfunction sprd_eic_irq_maskfunction sprd_eic_irq_unmaskfunction sprd_eic_irq_ackfunction sprd_eic_irq_set_typefunction sprd_eic_toggle_triggerfunction sprd_eic_handle_one_typefunction for_each_set_bitfunction sprd_eic_irq_handlerfunction sprd_eic_irq_notifyfunction sprd_eic_unregister_notifierfunction sprd_eic_probe
Annotated Snippet
struct sprd_eic {
struct gpio_chip chip;
struct notifier_block irq_nb;
void __iomem *base[SPRD_EIC_MAX_BANK];
enum sprd_eic_type type;
spinlock_t lock;
int irq;
};
static ATOMIC_NOTIFIER_HEAD(sprd_eic_irq_notifier);
static struct sprd_eic *to_sprd_eic(struct notifier_block *nb)
{
return container_of(nb, struct sprd_eic, irq_nb);
}
struct sprd_eic_variant_data {
enum sprd_eic_type type;
};
static const char *sprd_eic_label_name[SPRD_EIC_MAX] = {
"eic-debounce", "eic-latch", "eic-async",
"eic-sync",
};
static const struct sprd_eic_variant_data sc9860_eic_dbnc_data = {
.type = SPRD_EIC_DEBOUNCE,
};
static const struct sprd_eic_variant_data sc9860_eic_latch_data = {
.type = SPRD_EIC_LATCH,
};
static const struct sprd_eic_variant_data sc9860_eic_async_data = {
.type = SPRD_EIC_ASYNC,
};
static const struct sprd_eic_variant_data sc9860_eic_sync_data = {
.type = SPRD_EIC_SYNC,
};
static inline void __iomem *sprd_eic_offset_base(struct sprd_eic *sprd_eic,
unsigned int bank)
{
if (bank >= SPRD_EIC_MAX_BANK)
return NULL;
return sprd_eic->base[bank];
}
static void sprd_eic_update(struct gpio_chip *chip, unsigned int offset,
u16 reg, unsigned int val)
{
struct sprd_eic *sprd_eic = gpiochip_get_data(chip);
void __iomem *base =
sprd_eic_offset_base(sprd_eic, offset / SPRD_EIC_PER_BANK_NR);
unsigned long flags;
u32 tmp;
spin_lock_irqsave(&sprd_eic->lock, flags);
tmp = readl_relaxed(base + reg);
if (val)
tmp |= BIT(SPRD_EIC_BIT(offset));
else
tmp &= ~BIT(SPRD_EIC_BIT(offset));
writel_relaxed(tmp, base + reg);
spin_unlock_irqrestore(&sprd_eic->lock, flags);
}
static int sprd_eic_read(struct gpio_chip *chip, unsigned int offset, u16 reg)
{
struct sprd_eic *sprd_eic = gpiochip_get_data(chip);
void __iomem *base =
sprd_eic_offset_base(sprd_eic, offset / SPRD_EIC_PER_BANK_NR);
return !!(readl_relaxed(base + reg) & BIT(SPRD_EIC_BIT(offset)));
}
static int sprd_eic_request(struct gpio_chip *chip, unsigned int offset)
{
sprd_eic_update(chip, offset, SPRD_EIC_DBNC_DMSK, 1);
return 0;
}
static void sprd_eic_free(struct gpio_chip *chip, unsigned int offset)
{
sprd_eic_update(chip, offset, SPRD_EIC_DBNC_DMSK, 0);
}
Annotation
- Immediate include surface: `linux/bitops.h`, `linux/gpio/driver.h`, `linux/interrupt.h`, `linux/kernel.h`, `linux/module.h`, `linux/notifier.h`, `linux/platform_device.h`, `linux/property.h`.
- Detected declarations: `struct sprd_eic`, `struct sprd_eic_variant_data`, `enum sprd_eic_type`, `function sprd_eic_update`, `function sprd_eic_read`, `function sprd_eic_request`, `function sprd_eic_free`, `function sprd_eic_get`, `function sprd_eic_direction_input`, `function sprd_eic_set`.
- 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.