drivers/pinctrl/nuvoton/pinctrl-wpcm450.c
Source file repositories/reference/linux-study-clean/drivers/pinctrl/nuvoton/pinctrl-wpcm450.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pinctrl/nuvoton/pinctrl-wpcm450.c- Extension
.c- Size
- 36386 bytes
- Lines
- 1168
- Domain
- Driver Families
- Bucket
- drivers/pinctrl
- 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/device.hlinux/gpio/driver.hlinux/gpio/generic.hlinux/interrupt.hlinux/irq.hlinux/mfd/syscon.hlinux/module.hlinux/mod_devicetable.hlinux/platform_device.hlinux/property.hlinux/regmap.hlinux/pinctrl/pinconf.hlinux/pinctrl/pinconf-generic.hlinux/pinctrl/pinctrl.hlinux/pinctrl/pinmux.h../core.h
Detected Declarations
struct wpcm450_pinctrlstruct wpcm450_bankstruct wpcm450_gpiostruct wpcm450_pinctrlstruct wpcm450_bankstruct wpcm450_pincfgfunction wpcm450_gpio_irq_bitnumfunction wpcm450_irq_bitnum_to_gpiofunction wpcm450_gpio_irq_ackfunction wpcm450_gpio_irq_maskfunction wpcm450_gpio_irq_unmaskfunction wpcm450_gpio_fix_evpolfunction wpcm450_gpio_fix_evpolfunction for_each_set_bitfunction wpcm450_gpio_set_irq_typefunction wpcm450_gpio_irqhandlerfunction wpcm450_update_mfselfunction wpcm450_setfuncfunction wpcm450_get_groups_countfunction wpcm450_get_group_pinsfunction wpcm450_dt_free_mapfunction wpcm450_get_functions_countfunction wpcm450_get_function_groupsfunction wpcm450_pinmux_set_muxfunction debounce_bitnumfunction wpcm450_config_getfunction wpcm450_config_set_onefunction wpcm450_config_setfunction wpcm450_gpio_set_configfunction wpcm450_gpio_add_pin_rangesfunction wpcm450_gpio_registerfunction for_each_gpiochip_nodefunction wpcm450_pinctrl_probe
Annotated Snippet
struct wpcm450_gpio {
struct gpio_generic_chip chip;
struct wpcm450_pinctrl *pctrl;
const struct wpcm450_bank *bank;
};
struct wpcm450_pinctrl {
struct pinctrl_dev *pctldev;
struct device *dev;
struct irq_domain *domain;
struct regmap *gcr_regmap;
void __iomem *gpio_base;
struct wpcm450_gpio gpio_bank[WPCM450_NUM_BANKS];
unsigned long both_edges;
/*
* This spin lock protects registers and struct wpcm450_pinctrl fields
* against concurrent access.
*/
raw_spinlock_t lock;
};
struct wpcm450_bank {
/* Range of GPIOs in this port */
u8 base;
u8 length;
/* Register offsets (0 = register doesn't exist in this port) */
u8 cfg0, cfg1, cfg2;
u8 blink;
u8 dataout, datain;
/* Interrupt bit mapping */
u8 first_irq_bit; /* First bit in GPEVST that belongs to this bank */
u8 num_irqs; /* Number of IRQ-capable GPIOs in this bank */
u8 first_irq_gpio; /* First IRQ-capable GPIO in this bank */
};
static const struct wpcm450_bank wpcm450_banks[WPCM450_NUM_BANKS] = {
/* range cfg0 cfg1 cfg2 blink out in IRQ map */
{ 0, 16, 0x14, 0x18, 0, 0, 0x1c, 0x20, 0, 16, 0 },
{ 16, 16, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 16, 2, 8 },
{ 32, 16, 0x3c, 0x40, 0x44, 0, 0x48, 0x4c, 0, 0, 0 },
{ 48, 16, 0x50, 0x54, 0x58, 0, 0x5c, 0x60, 0, 0, 0 },
{ 64, 16, 0x64, 0x68, 0x6c, 0, 0x70, 0x74, 0, 0, 0 },
{ 80, 16, 0x78, 0x7c, 0x80, 0, 0x84, 0x88, 0, 0, 0 },
{ 96, 18, 0, 0, 0, 0, 0, 0x8c, 0, 0, 0 },
{ 114, 14, 0x90, 0x94, 0x98, 0, 0x9c, 0xa0, 0, 0, 0 },
};
static int wpcm450_gpio_irq_bitnum(struct wpcm450_gpio *gpio, struct irq_data *d)
{
const struct wpcm450_bank *bank = gpio->bank;
int hwirq = irqd_to_hwirq(d);
if (hwirq < bank->first_irq_gpio)
return -EINVAL;
if (hwirq - bank->first_irq_gpio >= bank->num_irqs)
return -EINVAL;
return hwirq - bank->first_irq_gpio + bank->first_irq_bit;
}
static int wpcm450_irq_bitnum_to_gpio(struct wpcm450_gpio *gpio, int bitnum)
{
const struct wpcm450_bank *bank = gpio->bank;
if (bitnum < bank->first_irq_bit)
return -EINVAL;
if (bitnum - bank->first_irq_bit > bank->num_irqs)
return -EINVAL;
return bitnum - bank->first_irq_bit + bank->first_irq_gpio;
}
static void wpcm450_gpio_irq_ack(struct irq_data *d)
{
struct wpcm450_gpio *gpio = gpiochip_get_data(irq_data_get_irq_chip_data(d));
struct wpcm450_pinctrl *pctrl = gpio->pctrl;
unsigned long flags;
int bit;
bit = wpcm450_gpio_irq_bitnum(gpio, d);
if (bit < 0)
return;
raw_spin_lock_irqsave(&pctrl->lock, flags);
iowrite32(BIT(bit), pctrl->gpio_base + WPCM450_GPEVST);
Annotation
- Immediate include surface: `linux/device.h`, `linux/gpio/driver.h`, `linux/gpio/generic.h`, `linux/interrupt.h`, `linux/irq.h`, `linux/mfd/syscon.h`, `linux/module.h`, `linux/mod_devicetable.h`.
- Detected declarations: `struct wpcm450_pinctrl`, `struct wpcm450_bank`, `struct wpcm450_gpio`, `struct wpcm450_pinctrl`, `struct wpcm450_bank`, `struct wpcm450_pincfg`, `function wpcm450_gpio_irq_bitnum`, `function wpcm450_irq_bitnum_to_gpio`, `function wpcm450_gpio_irq_ack`, `function wpcm450_gpio_irq_mask`.
- Atlas domain: Driver Families / drivers/pinctrl.
- 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.