Linux下SMI总线驱动 韩大卫@吉林师范大学 剖析某类总线接口的芯片在linux里用户层对其的调用办法,较快捷的办法是直接找到该总线控制器的驱动程序,从其提供的软件接口展开逐层向上推及。现跟大家分享一下linux下octeon 处理器的SMI总线控制器的驱动(其架构完全符合platform设备驱动的通过架构)。附录里有用户层访问SMI总线设备,如marvell PHY芯片88E1111/1340/1340S的源程序。 下面为cavium octeon的SMI总线驱动源代码的大致内容: drivers/net/phy/mdio-octeon.c static int __init octeon_mdiobus_mod_init(void) { //将octeon_mdiobus_driver 作为一个platform类型的driver 注册到内核 return platform_driver_register(&octeon_mdiobus_driver); } module_init(octeon_mdiobus_mod_init); static struct platform_driver octeon_mdiobus_driver = { .driver = { .name = "mdio-octeon", .owner = THIS_MODULE, .of_match_table = octeon_mdiobus_match, }, .probe = octeon_mdiobus_probe, .remove = __exit_p(octeon_mdiobus_remove), }; static int __init octeon_mdiobus_probe(struct platform_device *pdev) { struct octeon_mdiobus *bus; struct resource *res_mem; union cvmx_smix_en smi_en; int err = -ENOENT; //申请并初始化一段内存填充数据结构 struct octeon_mdiobus bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL); if (!bus) return -ENOMEM; /*获取IO内存资源的描述,这个资料描述是uboot通过读取解析并处理uboot里的dts文件后得到的,在linux启动后,便可通过platform_get_resource()来获取,成功获取后,后面会向内核申请使用这段IO内存,另外, dts文件关于IO地址等资料的描述是按照CPU datasheet上的信息来写的。 */ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res_mem == NULL) { dev_err(&pdev->dev, "found no memory resource\n"); err = -ENXIO; goto fail_region; } /*通过res_mem来得到地址首地址和地址长度, 这个start 是我在uboot的dts文件里描述的 “ smi0: mdio@1180000001800 { compatible = "cavium,octeon-3860-mdio"; #address-cells = <1>; #size-cells = <0>; reg = <0x11800 0x00001800 0x0 0x40>; “ 首地址 0x1180000001800, 长度为0x40 /* bus->mdio_phys = res_mem->start; bus->regsize = resource_size(res_mem); /*将bus->mdio_phys, regsize打印出来分别为: 0x1800 和0x40 */ //调用include/linux/ioport.h 里提供的API 向内核申请使用这段IO内存 if (!devm_request_mem_region(&pdev->dev, bus->mdio_phys, bus->regsize, res_mem->name)) { dev_err(&pdev->dev, "request_mem_region failed\n"); goto fail_region; } //将这段IO内存映射为内存地址,此时的register_base即可被内核空间直接使用 bus->register_base = (u64)ioremap(bus->mdio_phys, bus->regsize); /* 将bus->register_base 打印出来 为0x1800 ,但是这个地址是存在内存中的,上面的bus->mdio_phys的0x1800是存在于IO内存中的*/ //mdiobus_alloc()封装了kzalloc, 作用是申请一段大小为sizeof(struct mii_bus)的内存 bus->mii_bus = mdiobus_alloc()
Linux下SMI总线驱动
最新推荐文章于 2024-08-18 18:50:53 发布