drivers/net/mdio/mdio-mux-mmioreg.c
Source file repositories/reference/linux-study-clean/drivers/net/mdio/mdio-mux-mmioreg.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/mdio/mdio-mux-mmioreg.c- Extension
.c- Size
- 4716 bytes
- Lines
- 191
- Domain
- Driver Families
- Bucket
- drivers/net
- 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/device.hlinux/mdio-mux.hlinux/module.hlinux/of_address.hlinux/of_mdio.hlinux/phy.hlinux/platform_device.h
Detected Declarations
struct mdio_mux_mmioreg_statefunction mdio_mux_mmioreg_switch_fnfunction mdio_mux_mmioreg_probefunction mdio_mux_mmioreg_remove
Annotated Snippet
struct mdio_mux_mmioreg_state {
void *mux_handle;
phys_addr_t phys;
unsigned int iosize;
unsigned int mask;
};
/*
* MDIO multiplexing switch function
*
* This function is called by the mdio-mux layer when it thinks the mdio bus
* multiplexer needs to switch.
*
* 'current_child' is the current value of the mux register (masked via
* s->mask).
*
* 'desired_child' is the value of the 'reg' property of the target child MDIO
* node.
*
* The first time this function is called, current_child == -1.
*
* If current_child == desired_child, then the mux is already set to the
* correct bus.
*/
static int mdio_mux_mmioreg_switch_fn(int current_child, int desired_child,
void *data)
{
struct mdio_mux_mmioreg_state *s = data;
if (current_child ^ desired_child) {
void __iomem *p = ioremap(s->phys, s->iosize);
if (!p)
return -ENOMEM;
switch (s->iosize) {
case sizeof(uint8_t): {
uint8_t x, y;
x = ioread8(p);
y = (x & ~s->mask) | desired_child;
if (x != y) {
iowrite8((x & ~s->mask) | desired_child, p);
pr_debug("%s: %02x -> %02x\n", __func__, x, y);
}
break;
}
case sizeof(uint16_t): {
uint16_t x, y;
x = ioread16(p);
y = (x & ~s->mask) | desired_child;
if (x != y) {
iowrite16((x & ~s->mask) | desired_child, p);
pr_debug("%s: %04x -> %04x\n", __func__, x, y);
}
break;
}
case sizeof(uint32_t): {
uint32_t x, y;
x = ioread32(p);
y = (x & ~s->mask) | desired_child;
if (x != y) {
iowrite32((x & ~s->mask) | desired_child, p);
pr_debug("%s: %08x -> %08x\n", __func__, x, y);
}
break;
}
}
iounmap(p);
}
return 0;
}
static int mdio_mux_mmioreg_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct mdio_mux_mmioreg_state *s;
struct resource res;
const __be32 *iprop;
int len, ret;
dev_dbg(&pdev->dev, "probing node %pOF\n", np);
s = devm_kzalloc(&pdev->dev, sizeof(*s), GFP_KERNEL);
Annotation
- Immediate include surface: `linux/device.h`, `linux/mdio-mux.h`, `linux/module.h`, `linux/of_address.h`, `linux/of_mdio.h`, `linux/phy.h`, `linux/platform_device.h`.
- Detected declarations: `struct mdio_mux_mmioreg_state`, `function mdio_mux_mmioreg_switch_fn`, `function mdio_mux_mmioreg_probe`, `function mdio_mux_mmioreg_remove`.
- Atlas domain: Driver Families / drivers/net.
- 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.