drivers/gpio/gpio-mpc8xxx.c
Source file repositories/reference/linux-study-clean/drivers/gpio/gpio-mpc8xxx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpio/gpio-mpc8xxx.c- Extension
.c- Size
- 14179 bytes
- Lines
- 512
- 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/acpi.hlinux/bitops.hlinux/gpio/driver.hlinux/gpio/generic.hlinux/init.hlinux/interrupt.hlinux/io.hlinux/irq.hlinux/kernel.hlinux/mod_devicetable.hlinux/platform_device.hlinux/pm.hlinux/pm_runtime.hlinux/property.hlinux/slab.hlinux/spinlock.h
Detected Declarations
struct mpc8xxx_gpio_chipstruct mpc8xxx_gpio_devtypefunction mpc_pin2maskfunction mpc8572_gpio_getfunction mpc5121_gpio_dir_outfunction mpc5125_gpio_dir_outfunction mpc8xxx_gpio_to_irqfunction mpc8xxx_gpio_irq_cascadefunction mpc8xxx_irq_unmaskfunction mpc8xxx_irq_maskfunction mpc8xxx_irq_ackfunction mpc8xxx_irq_set_typefunction mpc512x_irq_set_typefunction mpc8xxx_gpio_irq_mapfunction mpc8xxx_probefunction device_is_compatiblefunction mpc8xxx_removefunction mpc8xxx_suspendfunction mpc8xxx_resumefunction mpc8xxx_init
Annotated Snippet
struct mpc8xxx_gpio_chip {
struct gpio_generic_chip chip;
void __iomem *regs;
raw_spinlock_t lock;
int (*direction_output)(struct gpio_chip *chip,
unsigned offset, int value);
struct irq_domain *irq;
int irqn;
};
/*
* This hardware has a big endian bit assignment such that GPIO line 0 is
* connected to bit 31, line 1 to bit 30 ... line 31 to bit 0.
* This inline helper give the right bitmask for a certain line.
*/
static inline u32 mpc_pin2mask(unsigned int offset)
{
return BIT(31 - offset);
}
/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
* defined as output cannot be determined by reading GPDAT register,
* so we use shadow data register instead. The status of input pins
* is determined by reading GPDAT register.
*/
static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
{
u32 val;
struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc);
u32 out_mask, out_shadow;
out_mask = gpio_generic_read_reg(&mpc8xxx_gc->chip,
mpc8xxx_gc->regs + GPIO_DIR);
val = gpio_generic_read_reg(&mpc8xxx_gc->chip,
mpc8xxx_gc->regs + GPIO_DAT) & ~out_mask;
out_shadow = mpc8xxx_gc->chip.sdata & out_mask;
return !!((val | out_shadow) & mpc_pin2mask(gpio));
}
static int mpc5121_gpio_dir_out(struct gpio_chip *gc,
unsigned int gpio, int val)
{
struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc);
/* GPIO 28..31 are input only on MPC5121 */
if (gpio >= 28)
return -EINVAL;
return mpc8xxx_gc->direction_output(gc, gpio, val);
}
static int mpc5125_gpio_dir_out(struct gpio_chip *gc,
unsigned int gpio, int val)
{
struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc);
/* GPIO 0..3 are input only on MPC5125 */
if (gpio <= 3)
return -EINVAL;
return mpc8xxx_gc->direction_output(gc, gpio, val);
}
static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
{
struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc);
if (mpc8xxx_gc->irq && offset < MPC8XXX_GPIO_PINS)
return irq_create_mapping(mpc8xxx_gc->irq, offset);
else
return -ENXIO;
}
static irqreturn_t mpc8xxx_gpio_irq_cascade(int irq, void *data)
{
struct mpc8xxx_gpio_chip *mpc8xxx_gc = data;
unsigned long mask;
int i;
mask = gpio_generic_read_reg(&mpc8xxx_gc->chip,
mpc8xxx_gc->regs + GPIO_IER) &
gpio_generic_read_reg(&mpc8xxx_gc->chip,
mpc8xxx_gc->regs + GPIO_IMR);
for_each_set_bit(i, &mask, 32)
generic_handle_domain_irq(mpc8xxx_gc->irq, 31 - i);
return IRQ_HANDLED;
}
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/bitops.h`, `linux/gpio/driver.h`, `linux/gpio/generic.h`, `linux/init.h`, `linux/interrupt.h`, `linux/io.h`, `linux/irq.h`.
- Detected declarations: `struct mpc8xxx_gpio_chip`, `struct mpc8xxx_gpio_devtype`, `function mpc_pin2mask`, `function mpc8572_gpio_get`, `function mpc5121_gpio_dir_out`, `function mpc5125_gpio_dir_out`, `function mpc8xxx_gpio_to_irq`, `function mpc8xxx_gpio_irq_cascade`, `function mpc8xxx_irq_unmask`, `function mpc8xxx_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.