0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/bug.h>
0011 #include <linux/io-pgtable.h>
0012 #include <linux/kernel.h>
0013 #include <linux/types.h>
0014
0015 static const struct io_pgtable_init_fns *
0016 io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] = {
0017 #ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE
0018 [ARM_32_LPAE_S1] = &io_pgtable_arm_32_lpae_s1_init_fns,
0019 [ARM_32_LPAE_S2] = &io_pgtable_arm_32_lpae_s2_init_fns,
0020 [ARM_64_LPAE_S1] = &io_pgtable_arm_64_lpae_s1_init_fns,
0021 [ARM_64_LPAE_S2] = &io_pgtable_arm_64_lpae_s2_init_fns,
0022 [ARM_MALI_LPAE] = &io_pgtable_arm_mali_lpae_init_fns,
0023 [APPLE_DART] = &io_pgtable_apple_dart_init_fns,
0024 #endif
0025 #ifdef CONFIG_IOMMU_IO_PGTABLE_ARMV7S
0026 [ARM_V7S] = &io_pgtable_arm_v7s_init_fns,
0027 #endif
0028 #ifdef CONFIG_AMD_IOMMU
0029 [AMD_IOMMU_V1] = &io_pgtable_amd_iommu_v1_init_fns,
0030 #endif
0031 };
0032
0033 struct io_pgtable_ops *alloc_io_pgtable_ops(enum io_pgtable_fmt fmt,
0034 struct io_pgtable_cfg *cfg,
0035 void *cookie)
0036 {
0037 struct io_pgtable *iop;
0038 const struct io_pgtable_init_fns *fns;
0039
0040 if (fmt >= IO_PGTABLE_NUM_FMTS)
0041 return NULL;
0042
0043 fns = io_pgtable_init_table[fmt];
0044 if (!fns)
0045 return NULL;
0046
0047 iop = fns->alloc(cfg, cookie);
0048 if (!iop)
0049 return NULL;
0050
0051 iop->fmt = fmt;
0052 iop->cookie = cookie;
0053 iop->cfg = *cfg;
0054
0055 return &iop->ops;
0056 }
0057 EXPORT_SYMBOL_GPL(alloc_io_pgtable_ops);
0058
0059
0060
0061
0062
0063 void free_io_pgtable_ops(struct io_pgtable_ops *ops)
0064 {
0065 struct io_pgtable *iop;
0066
0067 if (!ops)
0068 return;
0069
0070 iop = io_pgtable_ops_to_pgtable(ops);
0071 io_pgtable_tlb_flush_all(iop);
0072 io_pgtable_init_table[iop->fmt]->free(iop);
0073 }
0074 EXPORT_SYMBOL_GPL(free_io_pgtable_ops);