Implementing a PHY provider
Platform (or other) driver that owns PHY registers and exports **struct rt_phye**.
Minimal template
struct my_phy {
struct rt_phye phye;
void __iomem *regs;
};
static rt_err_t my_phy_power_on(struct rt_phye *phye)
{
}
static rt_err_t my_phy_set_mode(struct rt_phye *phye,
enum rt_phye_mode mode, int submode)
{
return RT_EOK;
}
static const struct rt_phye_ops my_phy_ops = {
.power_on = my_phy_power_on,
.power_off = my_phy_power_off,
.set_mode = my_phy_set_mode,
.ofw_parse = my_phy_ofw_parse,
};
static rt_err_t my_phy_probe(struct rt_platform_device *pdev)
{
p->phye.dev = &pdev->parent;
p->phye.ops = &my_phy_ops;
return rt_phye_register(&p->phye);
}
rt_err_t rt_clk_prepare_enable(struct rt_clk *clk)
Prepare and enable clock.
Definition: clk.c:663
rt_weak void * rt_calloc(rt_size_t count, rt_size_t size)
This function will contiguously allocate enough space for count objects that are size bytes of memory...
Definition: kservice.c:1210
#define rt_container_of(ptr, type, member)
Definition: rtservice.h:36
Clock handle - represents a consumer reference to a clock.
Definition: clk.h:144
Probe checklist
- **
rt_dm_dev_iomap** / clocks / resets / regulators per TRM
- Fill **
rt_phye_ops** — only implement needed ops
- **
phye->dev = &pdev->parent**
- **
rt_phye_register(&phye)** — binds **rt_ofw_data** for consumers
- Do not call **
set_mode** for a specific host here — consumers select mode
<tt>ofw_parse</tt>
static rt_err_t my_phy_ofw_parse(struct rt_phye *phye,
struct rt_ofw_cell_args *args)
{
return RT_EOK;
}
Return error if cells are invalid — consumer **get** fails and host **probe** aborts.
Unregister
**remove**: **rt_phye_unregister** then free resources. Fails if consumers still hold references (**-RT_EBUSY**).
BSP placement
SoC-specific drivers often live under **SOC_DM_PHYE_DIR** (Kconfig **osource**). Enable in menuconfig alongside **RT_USING_PHYE**.
Pitfalls
| Issue | Mitigation |
Forgot **rt_phye_register** | **rt_ofw_data** NULL — consumer sees missing PHY |
Mode in **probe** | Host may need different mode — use **set_mode** from consumer |
| Shared PHY | Refcount in core helps; exclusive mux still needs driver policy |
See also