驅動定義:
static struct platform_driver arm_smmu_driver = {
.driver = {
.name = "arm-smmu-v3",
.of_match_table = arm_smmu_of_match,
.suppress_bind_attrs = true,
},
.probe = arm_smmu_device_probe,
.remove = arm_smmu_device_remove,
.shutdown = arm_smmu_device_shutdown,
};
註冊爲platform_driver,對"arm,smmu-v3"設備識別並驅動其初始化,設備參數參考arm,smmu-v3.txt
smmu@2b400000 {
compatible = "arm,smmu-v3";
reg = <0x0 0x2b400000 0x0 0x20000>;
interrupts = <GIC_SPI 74 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 75 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 77 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 79 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "eventq", "priq", "cmdq-sync", "gerror";
dma-coherent;
#iommu-cells = <1>;
msi-parent = <&its 0xff0000>;
};
probe過程:
調用函數arm_smmu_device_probe進行probe,首先devm_kzalloc分配struct arm_smmu_device結構,調用arm_smmu_device_dt_probe對dts參數進行解析來初始化smmu結構,具體參數如上面所示,解析過程不再詳細展開。
接着判斷是否bypass,然後通過platform_get_resource獲取到smmu的io資源信息,合法性檢查之後對其進行ioremap並將虛擬地址記錄在smmu->base中。通過platform_get_irq_byname_optional解析irq並記錄。
至此基本的參數解析過程已經完成,緊接着根據參數進行硬件的初始化,通過函數arm_smmu_device_hw_probe完成。arm_smmu_init_structures用於完成smmu對應的結構,初始化完成後將smmu信息設置爲platform device的private driver。至此開始reset設備,如設定bypass模式,清空數據等,然後將其添加到iommu系統中以供其他模塊調用,同時將arm_smmu_ops賦值給iommu,通過iommu_device_register進行註冊。最後是通過arm_smmu_set_bus_ops,對支持的bus設置iommu操作方法結構,均設置爲arm_smmu_ops。
重點需要分析的就是arm_smmu_ops,也就是smmu提供給外界設置其功能的接口。