drivers/gpio/gpio-ich.c
Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-ich.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpio/gpio-ich.c- Extension
.c- Size
- 12318 bytes
- Lines
- 489
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitops.hlinux/gpio/driver.hlinux/ioport.hlinux/mfd/lpc_ich.hlinux/module.hlinux/platform_device.h
Detected Declarations
struct ichx_descenum GPIO_REGfunction ichx_write_bitfunction ichx_read_bitfunction ichx_gpio_check_availablefunction ichx_gpio_get_directionfunction ichx_gpio_direction_inputfunction ichx_gpio_direction_outputfunction ichx_gpio_getfunction ich6_gpio_getfunction ichx_gpio_requestfunction ich6_gpio_requestfunction ichx_gpio_setfunction ichx_gpiolib_setupfunction ichx_gpio_request_regionsfunction ichx_gpio_probe
Annotated Snippet
struct ichx_desc {
/* Max GPIO pins the chipset can have */
uint ngpio;
/* chipset registers */
const u8 (*regs)[3];
const u8 *reglen;
/* GPO_BLINK is available on this chipset */
bool have_blink;
/* Whether the chipset has GPIO in GPE0_STS in the PM IO region */
bool uses_gpe0;
/* USE_SEL is bogus on some chipsets, eg 3100 */
u32 use_sel_ignore[3];
/* Some chipsets have quirks, let these use their own request/get */
int (*request)(struct gpio_chip *chip, unsigned int offset);
int (*get)(struct gpio_chip *chip, unsigned int offset);
/*
* Some chipsets don't let reading output values on GPIO_LVL register
* this option allows driver caching written output values
*/
bool use_outlvl_cache;
};
static struct {
spinlock_t lock;
struct device *dev;
struct gpio_chip chip;
struct resource *gpio_base; /* GPIO IO base */
struct resource *pm_base; /* Power Management IO base */
struct ichx_desc *desc; /* Pointer to chipset-specific description */
u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */
u8 use_gpio; /* Which GPIO groups are usable */
int outlvl_cache[3]; /* cached output values */
} ichx_priv;
static int modparam_gpiobase = -1; /* dynamic */
module_param_named(gpiobase, modparam_gpiobase, int, 0444);
MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, which is the default.");
static int ichx_write_bit(int reg, unsigned int nr, int val, int verify)
{
unsigned long flags;
u32 data, tmp;
int reg_nr = nr / 32;
int bit = nr & 0x1f;
spin_lock_irqsave(&ichx_priv.lock, flags);
if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
data = ichx_priv.outlvl_cache[reg_nr];
else
data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
if (val)
data |= BIT(bit);
else
data &= ~BIT(bit);
ICHX_WRITE(data, ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
ichx_priv.outlvl_cache[reg_nr] = data;
tmp = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
spin_unlock_irqrestore(&ichx_priv.lock, flags);
return (verify && data != tmp) ? -EPERM : 0;
}
static int ichx_read_bit(int reg, unsigned int nr)
{
unsigned long flags;
u32 data;
int reg_nr = nr / 32;
int bit = nr & 0x1f;
spin_lock_irqsave(&ichx_priv.lock, flags);
data = ICHX_READ(ichx_priv.desc->regs[reg][reg_nr],
ichx_priv.gpio_base);
if (reg == GPIO_LVL && ichx_priv.desc->use_outlvl_cache)
data = ichx_priv.outlvl_cache[reg_nr] | data;
Annotation
- Immediate include surface: `linux/bitops.h`, `linux/gpio/driver.h`, `linux/ioport.h`, `linux/mfd/lpc_ich.h`, `linux/module.h`, `linux/platform_device.h`.
- Detected declarations: `struct ichx_desc`, `enum GPIO_REG`, `function ichx_write_bit`, `function ichx_read_bit`, `function ichx_gpio_check_available`, `function ichx_gpio_get_direction`, `function ichx_gpio_direction_input`, `function ichx_gpio_direction_output`, `function ichx_gpio_get`, `function ich6_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.