ARM架构SMMU驱动详解

驱动定义:

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 = ,
                             ,
                             ,
                             ;
                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提供给外界设置其功能的接口。

你可能感兴趣的:(Linux,ARM)