.. | .. |
---|
31 | 31 | #include <linux/module.h> |
---|
32 | 32 | #include <linux/pm_runtime.h> |
---|
33 | 33 | #include <linux/rockchip/cpu.h> |
---|
| 34 | +#include <linux/iommu.h> |
---|
34 | 35 | #include <asm/cacheflush.h> |
---|
35 | 36 | #include "iep_drv.h" |
---|
36 | 37 | #include "hw_iep_reg.h" |
---|
.. | .. |
---|
870 | 871 | .fops = &iep_fops, |
---|
871 | 872 | }; |
---|
872 | 873 | |
---|
873 | | -static struct device* rockchip_get_sysmmu_device_by_compatible( |
---|
874 | | - const char *compt) |
---|
875 | | -{ |
---|
876 | | - struct device_node *dn = NULL; |
---|
877 | | - struct platform_device *pd = NULL; |
---|
878 | | - struct device *ret = NULL; |
---|
879 | | - |
---|
880 | | - dn = of_find_compatible_node(NULL, NULL, compt); |
---|
881 | | - if (!dn) { |
---|
882 | | - printk("can't find device node %s \r\n", compt); |
---|
883 | | - return NULL; |
---|
884 | | - } |
---|
885 | | - |
---|
886 | | - pd = of_find_device_by_node(dn); |
---|
887 | | - if (!pd) { |
---|
888 | | - printk("can't find platform device in device node %s \r\n", |
---|
889 | | - compt); |
---|
890 | | - return NULL; |
---|
891 | | - } |
---|
892 | | - ret = &pd->dev; |
---|
893 | | - |
---|
894 | | - return ret; |
---|
895 | | - |
---|
896 | | -} |
---|
897 | | -#ifdef CONFIG_IOMMU_API |
---|
898 | | -static inline void platform_set_sysmmu(struct device *iommu, |
---|
899 | | - struct device *dev) |
---|
900 | | -{ |
---|
901 | | - dev->archdata.iommu = iommu; |
---|
902 | | -} |
---|
903 | | -#else |
---|
904 | | -static inline void platform_set_sysmmu(struct device *iommu, |
---|
905 | | - struct device *dev) |
---|
906 | | -{ |
---|
907 | | -} |
---|
908 | | -#endif |
---|
909 | | - |
---|
910 | | -static int iep_sysmmu_fault_handler(struct device *dev, |
---|
911 | | - enum rk_iommu_inttype itype, |
---|
912 | | - unsigned long pgtable_base, |
---|
913 | | - unsigned long fault_addr, unsigned int status) |
---|
| 874 | +static int iep_sysmmu_fault_handler(struct iommu_domain *domain, |
---|
| 875 | + struct device *iommu_dev, |
---|
| 876 | + unsigned long iova, int status, void *arg) |
---|
914 | 877 | { |
---|
915 | 878 | struct iep_reg *reg = list_entry(iep_service.running.next, |
---|
916 | 879 | struct iep_reg, status_link); |
---|
917 | 880 | if (reg != NULL) { |
---|
918 | 881 | struct iep_mem_region *mem, *n; |
---|
919 | 882 | int i = 0; |
---|
920 | | - pr_info("iep, fault addr 0x%08x\n", (u32)fault_addr); |
---|
| 883 | + pr_info("iep, fault addr 0x%08x\n", (u32)iova); |
---|
921 | 884 | list_for_each_entry_safe(mem, n, |
---|
922 | 885 | ®->mem_region_list, |
---|
923 | 886 | reg_lnk) { |
---|
.. | .. |
---|
944 | 907 | struct platform_device *sub_dev = NULL; |
---|
945 | 908 | struct device_node *sub_np = NULL; |
---|
946 | 909 | u32 iommu_en = 0; |
---|
947 | | - struct device *mmu_dev = NULL; |
---|
| 910 | + struct iommu_domain *domain; |
---|
| 911 | + |
---|
948 | 912 | of_property_read_u32(np, "iommu_enabled", &iommu_en); |
---|
949 | 913 | |
---|
950 | 914 | data = devm_kzalloc(&pdev->dev, sizeof(*data), |
---|
.. | .. |
---|
1081 | 1045 | if (sub_np) { |
---|
1082 | 1046 | sub_dev = of_find_device_by_node(sub_np); |
---|
1083 | 1047 | iep_service.iommu_dev = &sub_dev->dev; |
---|
| 1048 | + domain = iommu_get_domain_for_dev(&pdev->dev); |
---|
| 1049 | + iommu_set_fault_handler(domain, iep_sysmmu_fault_handler, data); |
---|
1084 | 1050 | } |
---|
1085 | 1051 | |
---|
1086 | | - if (!iep_service.iommu_dev) { |
---|
1087 | | - mmu_dev = rockchip_get_sysmmu_device_by_compatible( |
---|
1088 | | - IEP_IOMMU_COMPATIBLE_NAME); |
---|
1089 | | - |
---|
1090 | | - if (mmu_dev) { |
---|
1091 | | - platform_set_sysmmu(mmu_dev, &pdev->dev); |
---|
1092 | | - } |
---|
1093 | | - |
---|
1094 | | - rockchip_iovmm_set_fault_handler(&pdev->dev, |
---|
1095 | | - iep_sysmmu_fault_handler); |
---|
1096 | | - |
---|
1097 | | - iep_service.iommu_dev = mmu_dev; |
---|
1098 | | - } |
---|
1099 | 1052 | of_property_read_u32(np, "allocator", (u32 *)&iep_service.alloc_type); |
---|
1100 | 1053 | iep_power_on(); |
---|
1101 | 1054 | iep_service.iommu_info = iep_iommu_info_create(data->dev, |
---|
.. | .. |
---|
1194 | 1147 | return single_open(file, proc_iep_show, NULL); |
---|
1195 | 1148 | } |
---|
1196 | 1149 | |
---|
1197 | | -static const struct file_operations proc_iep_fops = { |
---|
1198 | | - .open = proc_iep_open, |
---|
1199 | | - .read = seq_read, |
---|
1200 | | - .llseek = seq_lseek, |
---|
1201 | | - .release = single_release, |
---|
| 1150 | +static const struct proc_ops proc_iep_fops = { |
---|
| 1151 | + .proc_open = proc_iep_open, |
---|
| 1152 | + .proc_read = seq_read, |
---|
| 1153 | + .proc_lseek = seq_lseek, |
---|
| 1154 | + .proc_release = single_release, |
---|
1202 | 1155 | }; |
---|
1203 | 1156 | |
---|
1204 | 1157 | static int __init iep_proc_init(void) |
---|