資源描述:
《linux下smi總線驅(qū)動(dòng)》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫(kù)。
1、Linux下SMI總線驅(qū)動(dòng)韓大衛(wèi)@吉林師范大學(xué)剖析某類(lèi)總線接口的芯片在linux里用戶層對(duì)其的調(diào)用辦法,較快捷的辦法是直接找到該總線控制器的驅(qū)動(dòng)程序,從其提供的軟件接口展開(kāi)逐層向上推及。現(xiàn)跟大家分享一下linux下octeon處理器的SMI總線控制器的驅(qū)動(dòng)(其架構(gòu)完全符合platform設(shè)備驅(qū)動(dòng)的通過(guò)架構(gòu))。附錄里有用戶層訪問(wèn)SMI總線設(shè)備,如marvellPHY芯片88E1111/1340/1340S的源程序。下面為caviumocteon的SMI總線驅(qū)動(dòng)源代碼的大致內(nèi)容:drivers/net/phy/mdio-octeon.cstaticint__initocteon_
2、mdiobus_mod_init(void){//將octeon_mdiobus_driver作為一個(gè)platform類(lèi)型的driver注冊(cè)到內(nèi)核returnplatform_driver_register(&octeon_mdiobus_driver);}module_init(octeon_mdiobus_mod_init);staticstructplatform_driverocteon_mdiobus_driver={.driver={.name="mdio-octeon",.owner=THIS_MODULE,.of_match_table=octeon_mdio
3、bus_match,},.probe=octeon_mdiobus_probe,.remove=__exit_p(octeon_mdiobus_remove),};staticint__initocteon_mdiobus_probe(structplatform_device*pdev){structocteon_mdiobus*bus;structresource*res_mem;unioncvmx_smix_ensmi_en;interr=-ENOENT;//申請(qǐng)并初始化一段內(nèi)存填充數(shù)據(jù)結(jié)構(gòu)structocteon_mdiobusbus=devm_kzalloc(&pd
4、ev->dev,sizeof(*bus),GFP_KERNEL);if(!bus)return-ENOMEM;/*獲取IO內(nèi)存資源的描述,這個(gè)資料描述是uboot通過(guò)讀取解析并處理uboot里的dts文件后得到的,在linux啟動(dòng)后,便可通過(guò)platform_get_resource()來(lái)獲取,成功獲取后,后面會(huì)向內(nèi)核申請(qǐng)使用這段IO內(nèi)存,另外,dts文件關(guān)于IO地址等資料的描述是按照CPUdatasheet上的信息來(lái)寫(xiě)的。*/res_mem=platform_get_resource(pdev,IORESOURCE_MEM,0);if(res_mem==NULL){dev_
5、err(&pdev->dev,"foundnomemoryresource");err=-ENXIO;gotofail_region;}/*通過(guò)res_mem來(lái)得到地址首地址和地址長(zhǎng)度,這個(gè)start是我在uboot的dts文件里描述的“smi0:mdio@1180000001800{compatible="cavium,octeon-3860-mdio";#address-cells=<1>;#size-cells=<0>;reg=<0x118000x000018000x00x40>;“首地址0x1180000001800,長(zhǎng)度為0x40/*bus->mdio_phys
6、=res_mem->start;bus->regsize=resource_size(res_mem);/*將bus->mdio_phys,regsize打印出來(lái)分別為:0x1800和0x40*///調(diào)用include/linux/ioport.h里提供的API向內(nèi)核申請(qǐng)使用這段IO內(nèi)存if(!devm_request_mem_region(&pdev->dev,bus->mdio_phys,bus->regsize,res_mem->name)){dev_err(&pdev->dev,"request_mem_regionfailed");gotofail_region
7、;}//將這段IO內(nèi)存映射為內(nèi)存地址,此時(shí)的register_base即可被內(nèi)核空間直接使用bus->register_base=(u64)ioremap(bus->mdio_phys,bus->regsize);/*將bus->register_base打印出來(lái)為0x1800,但是這個(gè)地址是存在內(nèi)存中的,上面的bus->mdio_phys的0x1800是存在于IO內(nèi)存中的*///mdiobus_alloc()封裝了kzalloc,作用是申請(qǐng)一段大小為sizeof(structmii_bus)的內(nèi)存bu