drivers/net/mdio/mdio-mux-meson-g12a.c
Source file repositories/reference/linux-study-clean/drivers/net/mdio/mdio-mux-meson-g12a.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/mdio/mdio-mux-meson-g12a.c- Extension
.c- Size
- 9021 bytes
- Lines
- 362
- 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/bitfield.hlinux/delay.hlinux/clk.hlinux/clk-provider.hlinux/device.hlinux/io.hlinux/iopoll.hlinux/mdio-mux.hlinux/module.hlinux/phy.hlinux/platform_device.h
Detected Declarations
struct g12a_mdio_muxstruct g12a_ephy_pllfunction g12a_ephy_pll_recalc_ratefunction g12a_ephy_pll_enablefunction g12a_ephy_pll_disablefunction g12a_ephy_pll_is_enabledfunction g12a_ephy_pll_initfunction g12a_enable_internal_mdiofunction g12a_enable_external_mdiofunction g12a_mdio_switch_fnfunction g12a_ephy_glue_clk_registerfunction g12a_mdio_mux_probefunction g12a_mdio_mux_remove
Annotated Snippet
struct g12a_mdio_mux {
void __iomem *regs;
void *mux_handle;
struct clk *pll;
};
struct g12a_ephy_pll {
void __iomem *base;
struct clk_hw hw;
};
#define g12a_ephy_pll_to_dev(_hw) \
container_of(_hw, struct g12a_ephy_pll, hw)
static unsigned long g12a_ephy_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct g12a_ephy_pll *pll = g12a_ephy_pll_to_dev(hw);
u32 val, m, n;
val = readl(pll->base + ETH_PLL_CTL0);
m = FIELD_GET(PLL_CTL0_M, val);
n = FIELD_GET(PLL_CTL0_N, val);
return parent_rate * m / n;
}
static int g12a_ephy_pll_enable(struct clk_hw *hw)
{
struct g12a_ephy_pll *pll = g12a_ephy_pll_to_dev(hw);
u32 val = readl(pll->base + ETH_PLL_CTL0);
/* Apply both enable an reset */
val |= PLL_CTL0_RST | PLL_CTL0_EN;
writel(val, pll->base + ETH_PLL_CTL0);
/* Clear the reset to let PLL lock */
val &= ~PLL_CTL0_RST;
writel(val, pll->base + ETH_PLL_CTL0);
/* Poll on the digital lock instead of the usual analog lock
* This is done because bit 31 is unreliable on some SoC. Bit
* 31 may indicate that the PLL is not lock even though the clock
* is actually running
*/
return readl_poll_timeout(pll->base + ETH_PLL_CTL0, val,
val & PLL_CTL0_LOCK_DIG, 0, PLL_LOCK_TIMEOUT);
}
static void g12a_ephy_pll_disable(struct clk_hw *hw)
{
struct g12a_ephy_pll *pll = g12a_ephy_pll_to_dev(hw);
u32 val;
val = readl(pll->base + ETH_PLL_CTL0);
val &= ~PLL_CTL0_EN;
val |= PLL_CTL0_RST;
writel(val, pll->base + ETH_PLL_CTL0);
}
static int g12a_ephy_pll_is_enabled(struct clk_hw *hw)
{
struct g12a_ephy_pll *pll = g12a_ephy_pll_to_dev(hw);
unsigned int val;
val = readl(pll->base + ETH_PLL_CTL0);
return (val & PLL_CTL0_LOCK_DIG) ? 1 : 0;
}
static int g12a_ephy_pll_init(struct clk_hw *hw)
{
struct g12a_ephy_pll *pll = g12a_ephy_pll_to_dev(hw);
/* Apply PLL HW settings */
writel(0x29c0040a, pll->base + ETH_PLL_CTL0);
writel(0x927e0000, pll->base + ETH_PLL_CTL1);
writel(0xac5f49e5, pll->base + ETH_PLL_CTL2);
writel(0x00000000, pll->base + ETH_PLL_CTL3);
writel(0x00000000, pll->base + ETH_PLL_CTL4);
writel(0x20200000, pll->base + ETH_PLL_CTL5);
writel(0x0000c002, pll->base + ETH_PLL_CTL6);
writel(0x00000023, pll->base + ETH_PLL_CTL7);
return 0;
}
static const struct clk_ops g12a_ephy_pll_ops = {
.recalc_rate = g12a_ephy_pll_recalc_rate,
.is_enabled = g12a_ephy_pll_is_enabled,
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/delay.h`, `linux/clk.h`, `linux/clk-provider.h`, `linux/device.h`, `linux/io.h`, `linux/iopoll.h`, `linux/mdio-mux.h`.
- Detected declarations: `struct g12a_mdio_mux`, `struct g12a_ephy_pll`, `function g12a_ephy_pll_recalc_rate`, `function g12a_ephy_pll_enable`, `function g12a_ephy_pll_disable`, `function g12a_ephy_pll_is_enabled`, `function g12a_ephy_pll_init`, `function g12a_enable_internal_mdio`, `function g12a_enable_external_mdio`, `function g12a_mdio_switch_fn`.
- 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.