device_bind_driver 收到绑定device和driver

来源:互联网 发布:tCL网络电视怎么使用 编辑:程序博客网 时间:2024/05/22 15:00
在调用phy_device_create的时候会动态申请一个phy_device *dev,然后给这个dev 赋值
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;

    /* We allocate the device, and initialize the default values */
    dev = kzalloc(sizeof(*dev), GFP_KERNEL);
    if (!dev)
        return ERR_PTR(-ENOMEM);

    mdiodev = &dev->mdio;
    mdiodev->dev.release = phy_device_release;
    mdiodev->dev.parent = &bus->dev;
    mdiodev->dev.bus = &mdio_bus_type;
    mdiodev->bus = bus;
    mdiodev->pm_ops = MDIO_BUS_PHY_PM_OPS;
    mdiodev->bus_match = phy_bus_match;
    mdiodev->addr = addr;
    mdiodev->flags = MDIO_DEVICE_FLAG_PHY;
    mdiodev->device_free = phy_mdio_device_free;
    mdiodev->device_remove = phy_mdio_device_remove;

    dev->speed = 0;
    dev->duplex = -1;
    dev->pause = 0;
    dev->asym_pause = 0;
    dev->link = 1;
    dev->interface = PHY_INTERFACE_MODE_GMII;

    dev->autoneg = AUTONEG_ENABLE;

    dev->is_c45 = is_c45;
    dev->phy_id = phy_id;
    if (c45_ids)
        dev->c45_ids = *c45_ids;
    dev->irq = bus->irq[addr];
//注意这里的name #define PHY_ID_FMT "%s:%02x"

    dev_set_name(&mdiodev->dev, PHY_ID_FMT, bus->id, addr);

    dev->state = PHY_DOWN;
}

注意这里的device是动态生成的,其driver并没有走platfrom driver和device 匹配的原则,而是手动调用device_bind_driver来将device和driver 绑定在一起。
int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
              u32 flags, phy_interface_t interface)
{
    struct module *ndev_owner = dev->dev.parent->driver->owner;
    struct mii_bus *bus = phydev->mdio.bus;
    struct device *d = &phydev->mdio.dev;
    int err;

    if (!d->driver) {
        if (phydev->is_c45)
            d->driver =
                &genphy_driver[GENPHY_DRV_10G].mdiodrv.driver;
        else
            d->driver =
                &genphy_driver[GENPHY_DRV_1G].mdiodrv.driver;

        err = d->driver->probe(d);
        if (err >= 0)
            err = device_bind_driver(d);

        if (err)
            goto error;
    }
使用device_bind_driver 绑定的时候,一定要设置d->driver 这个变量