Chinaunix首页 | 论坛 | 博客
  • 博客访问: 825529
  • 博文数量: 264
  • 博客积分: 592
  • 博客等级: 中士
  • 技术积分: 1574
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-24 22:02
文章分类

全部博文(264)

文章存档

2019年(2)

2018年(1)

2017年(1)

2016年(4)

2015年(14)

2014年(57)

2013年(88)

2012年(97)

分类: LINUX

2012-12-09 17:47:30

 

8 of_platform总线上gianfar设备驱动添加,并绑定设备e0024000.ethernete0025000.ethernet

/driver/net/gianfar.c

module_init(gfar_init);

gfar_init à of_register_platform_driver(&gfar_driver) à of_register_driver à driver_register à bus_add_driver à driver_attach

遍历整个of_platform总线,寻找与之相匹配的设备

driver_attach à __driver_attach à driver_match_device

drivermatch_table里的信息和dev_nod中的做比较,若符合就进入driverprobe,也就是gfar_probe

现在设备e0024000.ethernete0025000.ethernet都有了他们自己的驱动。

到这步,of_platform上的gianfar设备和mdio设备都有其各自的驱动,mdio总线上的phy设备和tbi-phy设备都有了其驱动程序,但是phy设备和gianfar设备之间还没有任何联系,phygianfar都没有初始化。现在要调用相应的驱动去初始化各个设备,连接gianfarphy

9 gianfar_probe 初始化gianfar设备,填充devpriv结构体。其中gfar_of_init 会从of结构中读出priv->phy_node

10 phy的初始化,phy gianfar的连接

/net/ipv4/ipconfig.c

late_initcall(ip_auto_config)

ip_auto_config à ic_open_devs à dev_change_flags à __dev_change_flags à __dev_open à ops->ndo_open à gfar_enet_open

gfar设备的打开函数中会去初始化phy,并connect to gianfar

u gfar_enet_open à init_phy

static int init_phy(struct net_device *dev)

{

interface = gfar_get_interface(dev);

/*PHY连接和初始化*/

priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link, 0,

/*配置TBI-PHY*/

if (interface == PHY_INTERFACE_MODE_SGMII)

gfar_configure_serdes(dev);

. . . . .

return 0;

}

u of_phy_connect函数

priv->phy_node是从of结构中读出的phy的信息,还不是真正的phy,所以这里要在mdio_bus_type总线上再找一次匹配的phy。若找到phy_device *phy指针就不为空。

struct phy_device *of_phy_connect(struct net_device *dev,

struct device_node *phy_np,

void (*hndlr)(struct net_device *), u32 flags,

phy_interface_t iface)

{

/*mdio总线上找到和of tree上读出的phy_node相匹配的phy设备*/

struct phy_device *phy = of_phy_find_device(phy_np);

if (!phy)

return NULL;

/*phy的初始化和phy的某些操作*/

return phy_connect_direct(dev, phy, hndlr, flags, iface) ? NULL : phy;

}

u phy_connect_direct函数

int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,

void (*handler)(struct net_device *), u32 flags,

phy_interface_t interface)

{

int rc;

/*phy 连接和初始化*/

rc = phy_attach_direct(dev, phydev, flags, interface);

if (rc)

return rc;

/*挂载PHY状态改变后修改gianfar驱动寄存器的回调函数*/

phy_prepare_link(phydev, handler);

/*PHY的状态机开启*/

phy_start_machine(phydev, NULL);

if (phydev->irq > 0)

{

/*PHY中断的开启*/

phy_start_interrupts(phydev);

}

return 0;

}

u phy_attach_direct函数

int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,

u32 flags, phy_interface_t interface)

{

struct device *d = &phydev->dev;

/* 如何该phy没有驱动,就使用genphy的驱动 */

if (NULL == d->driver) {

int err;

d->driver = &genphy_driver.driver;

err = d->driver->probe(d);

if (err >= 0)

err = device_bind_driver(d);

if (err)

return err;

}

/*如果phy已经和gianfar连接 返回*/

if (phydev->attached_dev) {

dev_err(&dev->dev, "PHY already attached/n");

return -EBUSY;

}

/*连接phygianfar*/

phydev->attached_dev = dev;

phydev->dev_flags = flags;

phydev->interface = interface;

/*使用phy的驱动中的初始化函数去初始化phy设备。*/

return phy_init_hw(phydev);

}

到这里,所有的gianfarphytbi-phy设备都已经注册,驱动已经加载,gianfarphy已经连接,并初始化完成。

阅读(2010) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~