关键结构体定义
struct phy_device {
struct mdio_device mdio;}
struct phy_driver {
struct mdio_driver_common mdiodrv;
}
struct mdio_driver_common {
struct device_driver driver;
int flags;
};
1.1 总线匹配函数
struct bus_type mdio_bus_type = {
.name = "mdio_bus",
.match = mdio_bus_match,
.uevent = mdio_uevent,
};static int mdio_bus_match(struct device *dev, struct device_driver *drv)
{
struct mdio_device *mdio = to_mdio_device(dev);if (of_driver_match_device(dev, drv)) //不会执行
return 1;if (mdio->bus_match)
return mdio->bus_match(dev, drv); //参考phy_device_create 调用return 0;
}struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
bool is_c45, struct phy_c45_device_ids *c45_ids)
{
struct phy_device *dev;
struct mdio_device *mdiodev;
mdiodev = &dev->mdio;
mdiodev->dev.parent = &bus->dev;
mdiodev->dev.bus = &mdio_bus_type;
mdiodev->dev.type = &mdio_bus_phy_type;
mdiodev->bus = bus;
mdiodev->bus_match = phy_bus_match; 匹配函数最终调用phy_bus_match
mdiodev->addr = addr;
......
}
1.2. 匹配函数phy_bus_match
static int phy_bus_match(struct device *dev, struct device_driver *drv)
{
struct phy_device *phydev = to_phy_device(dev);
struct phy_driver *phydrv = to_phy_driver(drv);
const int num_ids = ARRAY_SIZE(phydev->c45_ids.device_ids);
int i;if (!(phydrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY))
return 0;if (phydrv->match_phy_device)
return phydrv->match_phy_device(phydev);if (phydev->is_c45) {
for (i = 1; i < num_ids; i++) {
if (!(phydev->c45_ids.devices_in_package & (1 << i)))
continue;if ((phydrv->phy_id & phydrv->phy_id_mask) ==
(phydev->c45_ids.device_ids[i] &
phydrv->phy_id_mask))
return 1;
}
return 0;
} else {
return (phydrv->phy_id & phydrv->phy_id_mask) ==
(phydev->phy_id & phydrv->phy_id_mask); //根据读取的phy_id 与phy_driver 匹配
}
}
2.1 phy的probe 分析
根据 phy_driver_register 函数,确定探测函数为phy_probe
int phy_driver_register(struct phy_driver *new_driver, struct module *owner)
{
int retval;new_driver->mdiodrv.flags |= MDIO_DEVICE_IS_PHY;
new_driver->mdiodrv.driver.name = new_driver->name;
new_driver->mdiodrv.driver.bus = &mdio_bus_type;
new_driver->mdiodrv.driver.probe = phy_probe;//kernel 驱动模型,匹配后会调用probe 函数调用
new_driver->mdiodrv.driver.remove = phy_remove;
new_driver->mdiodrv.driver.owner = owner;return 0;
}
2.2 phy_probe 分析
如果phy_driver 如果存在.probe ,会执行(一般不存在)
static int phy_probe(struct device *dev)
{
struct phy_device *phydev = to_phy_device(dev);
struct device_driver *drv = phydev->mdio.dev.driver;
struct phy_driver *phydrv = to_phy_driver(drv);
int err = 0;phydev->drv = phydrv;
.......
phydev->state = PHY_READY;if (phydev->drv->probe) {
/* Deassert the reset signal */
phy_device_reset(phydev, 0);err = phydev->drv->probe(phydev);
if (err) {
/* Assert the reset signal */
phy_device_reset(phydev, 1);
}
}mutex_unlock(&phydev->lock);
return err;
}