drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c
Source file repositories/reference/linux-study-clean/drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c- Extension
.c- Size
- 10689 bytes
- Lines
- 374
- 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.
- 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/export.hlinux/of.hlinux/of_address.hlinux/of_device.hlinux/pinctrl/pinctrl.hlinux/platform_device.hlinux/slab.hpinctrl-sunxi.h
Detected Declarations
function SUNXI_FUNCTION_IRQ_BANKfunction namesfunction functionsfunction groupfunction of_property_for_each_stringfunction fill_pin_functionfunction sunxi_pinctrl_dt_table_init
Annotated Snippet
if (pins_per_bank[i] < 10) {
/* 4 bytes for "PXy\0" */
name_size += pins_per_bank[i] * 4;
} else {
/* 4 bytes for each "PXy\0" */
name_size += 10 * 4;
/* 5 bytes for each "PXyy\0" */
name_size += (pins_per_bank[i] - 10) * 5;
}
}
if (desc->npins == 0) {
dev_err(dev, "no ports defined\n");
return ERR_PTR(-EINVAL);
}
pins = devm_kcalloc(dev, desc->npins, sizeof(*pins), GFP_KERNEL);
if (!pins)
return ERR_PTR(-ENOMEM);
/* Allocate memory to store the name for every pin. */
pin_names = devm_kmalloc(dev, name_size, GFP_KERNEL);
if (!pin_names)
return ERR_PTR(-ENOMEM);
/* Fill the pins array with the name and the number for each pin. */
cur_name = pin_names;
cur_pin = pins;
for (i = 0; i < SUNXI_PINCTRL_MAX_BANKS; i++) {
for (j = 0; j < pins_per_bank[i]; j++, cur_pin++) {
int nchars = sprintf(cur_name, "P%c%d",
port_base + 'A' + i, j);
cur_pin->pin.number = (port_base + i) * PINS_PER_BANK + j;
cur_pin->pin.name = cur_name;
cur_name += nchars + 1;
}
}
return pins;
}
/*
* Work out the number of functions for each pin. This will visit every
* child node of the pinctrl DT node to find all advertised functions.
* Provide memory to hold the per-function information and assign it to
* the pin table.
* Fill in the GPIO in/out functions already (that every pin has), also add
* an "irq" function at the end, for those pins in IRQ-capable ports.
* We do not fill in the extra functions (those describe in DT nodes) yet.
* We (ab)use the "variant" member in each pin to keep track of the number of
* extra functions needed. At the end this will get reset to 2, so that we
* can add extra function later, after the two GPIO functions.
*/
static int prepare_function_table(struct device *dev, struct device_node *pnode,
struct sunxi_desc_pin *pins, int npins,
unsigned pin_base, const u8 *irq_bank_muxes)
{
struct device_node *node;
struct property *prop;
struct sunxi_desc_function *func;
int num_funcs, irq_bank, last_bank, i;
/*
* We need at least three functions per pin:
* - one for GPIO in
* - one for GPIO out
* - one for the sentinel signalling the end of the list
*/
num_funcs = 3 * npins;
/*
* Add a function for each pin in a bank supporting interrupts.
* We temporarily (ab)use the variant field to store the number of
* functions per pin. This will be cleaned back to 0 before we hand
* over the whole structure to the generic sunxi pinctrl setup code.
*/
for (i = 0; i < npins; i++) {
struct sunxi_desc_pin *pin = &pins[i];
int bank = (pin->pin.number - pin_base) / PINS_PER_BANK;
if (irq_bank_muxes[bank]) {
pin->variant++;
num_funcs++;
}
}
/*
* Go over each pin group (every child of the pinctrl DT node) and
Annotation
- Immediate include surface: `linux/export.h`, `linux/of.h`, `linux/of_address.h`, `linux/of_device.h`, `linux/pinctrl/pinctrl.h`, `linux/platform_device.h`, `linux/slab.h`, `pinctrl-sunxi.h`.
- Detected declarations: `function SUNXI_FUNCTION_IRQ_BANK`, `function names`, `function functions`, `function group`, `function of_property_for_each_string`, `function fill_pin_function`, `function sunxi_pinctrl_dt_table_init`.
- Atlas domain: Driver Families / drivers/pinctrl.
- Implementation status: source implementation candidate.
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.