drivers/gpio/gpio-pmic-eic-sprd.c
Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-pmic-eic-sprd.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpio/gpio-pmic-eic-sprd.c- Extension
.c- Size
- 10381 bytes
- Lines
- 382
- 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.
- 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/gpio/driver.hlinux/interrupt.hlinux/kernel.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/regmap.h
Detected Declarations
struct sprd_pmic_eicfunction sprd_pmic_eic_updatefunction sprd_pmic_eic_readfunction sprd_pmic_eic_requestfunction sprd_pmic_eic_freefunction sprd_pmic_eic_getfunction sprd_pmic_eic_direction_inputfunction sprd_pmic_eic_set_debouncefunction sprd_pmic_eic_set_configfunction sprd_pmic_eic_irq_maskfunction sprd_pmic_eic_irq_unmaskfunction sprd_pmic_eic_irq_set_typefunction sprd_pmic_eic_bus_lockfunction sprd_pmic_eic_bus_sync_unlockfunction sprd_pmic_eic_toggle_triggerfunction sprd_pmic_eic_irq_handlerfunction for_each_set_bitfunction sprd_pmic_eic_probe
Annotated Snippet
struct sprd_pmic_eic {
struct gpio_chip chip;
struct regmap *map;
u32 offset;
u8 reg[CACHE_NR_REGS];
struct mutex buslock;
int irq;
};
static void sprd_pmic_eic_update(struct gpio_chip *chip, unsigned int offset,
u16 reg, unsigned int val)
{
struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);
u32 shift = SPRD_PMIC_EIC_BIT(offset);
regmap_update_bits(pmic_eic->map, pmic_eic->offset + reg,
BIT(shift), val << shift);
}
static int sprd_pmic_eic_read(struct gpio_chip *chip, unsigned int offset,
u16 reg)
{
struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);
u32 value;
int ret;
ret = regmap_read(pmic_eic->map, pmic_eic->offset + reg, &value);
if (ret)
return ret;
return !!(value & BIT(SPRD_PMIC_EIC_BIT(offset)));
}
static int sprd_pmic_eic_request(struct gpio_chip *chip, unsigned int offset)
{
sprd_pmic_eic_update(chip, offset, SPRD_PMIC_EIC_DMSK, 1);
return 0;
}
static void sprd_pmic_eic_free(struct gpio_chip *chip, unsigned int offset)
{
sprd_pmic_eic_update(chip, offset, SPRD_PMIC_EIC_DMSK, 0);
}
static int sprd_pmic_eic_get(struct gpio_chip *chip, unsigned int offset)
{
return sprd_pmic_eic_read(chip, offset, SPRD_PMIC_EIC_DATA);
}
static int sprd_pmic_eic_direction_input(struct gpio_chip *chip,
unsigned int offset)
{
/* EICs are always input, nothing need to do here. */
return 0;
}
static int sprd_pmic_eic_set_debounce(struct gpio_chip *chip,
unsigned int offset,
unsigned int debounce)
{
struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);
u32 reg, value;
int ret;
reg = SPRD_PMIC_EIC_CTRL0 + SPRD_PMIC_EIC_BIT(offset) * 0x4;
ret = regmap_read(pmic_eic->map, pmic_eic->offset + reg, &value);
if (ret)
return ret;
value &= ~SPRD_PMIC_EIC_DBNC_MASK;
value |= (debounce / 1000) & SPRD_PMIC_EIC_DBNC_MASK;
return regmap_write(pmic_eic->map, pmic_eic->offset + reg, value);
}
static int sprd_pmic_eic_set_config(struct gpio_chip *chip, unsigned int offset,
unsigned long config)
{
unsigned long param = pinconf_to_config_param(config);
u32 arg = pinconf_to_config_argument(config);
if (param == PIN_CONFIG_INPUT_DEBOUNCE)
return sprd_pmic_eic_set_debounce(chip, offset, arg);
return -ENOTSUPP;
}
static void sprd_pmic_eic_irq_mask(struct irq_data *data)
{
struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct sprd_pmic_eic *pmic_eic = gpiochip_get_data(chip);
Annotation
- Immediate include surface: `linux/gpio/driver.h`, `linux/interrupt.h`, `linux/kernel.h`, `linux/module.h`, `linux/of.h`, `linux/platform_device.h`, `linux/regmap.h`.
- Detected declarations: `struct sprd_pmic_eic`, `function sprd_pmic_eic_update`, `function sprd_pmic_eic_read`, `function sprd_pmic_eic_request`, `function sprd_pmic_eic_free`, `function sprd_pmic_eic_get`, `function sprd_pmic_eic_direction_input`, `function sprd_pmic_eic_set_debounce`, `function sprd_pmic_eic_set_config`, `function sprd_pmic_eic_irq_mask`.
- 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.
- 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.