io-pgtable.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. * Generic page table allocator for IOMMUs.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. * Copyright (C) 2014 ARM Limited
  17. *
  18. * Author: Will Deacon <will.deacon@arm.com>
  19. */
  20. #include <linux/bug.h>
  21. #include <linux/kernel.h>
  22. #include <linux/types.h>
  23. #include "io-pgtable.h"
  24. static const struct io_pgtable_init_fns *
  25. io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] =
  26. {
  27. #ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE
  28. [ARM_32_LPAE_S1] = &io_pgtable_arm_32_lpae_s1_init_fns,
  29. [ARM_32_LPAE_S2] = &io_pgtable_arm_32_lpae_s2_init_fns,
  30. [ARM_64_LPAE_S1] = &io_pgtable_arm_64_lpae_s1_init_fns,
  31. [ARM_64_LPAE_S2] = &io_pgtable_arm_64_lpae_s2_init_fns,
  32. #endif
  33. #ifdef CONFIG_IOMMU_IO_PGTABLE_ARMV7S
  34. [ARM_V7S] = &io_pgtable_arm_v7s_init_fns,
  35. #endif
  36. };
  37. struct io_pgtable_ops *alloc_io_pgtable_ops(enum io_pgtable_fmt fmt,
  38. struct io_pgtable_cfg *cfg,
  39. void *cookie)
  40. {
  41. struct io_pgtable *iop;
  42. const struct io_pgtable_init_fns *fns;
  43. if (fmt >= IO_PGTABLE_NUM_FMTS)
  44. return NULL;
  45. fns = io_pgtable_init_table[fmt];
  46. if (!fns)
  47. return NULL;
  48. iop = fns->alloc(cfg, cookie);
  49. if (!iop)
  50. return NULL;
  51. iop->fmt = fmt;
  52. iop->cookie = cookie;
  53. iop->cfg = *cfg;
  54. return &iop->ops;
  55. }
  56. /*
  57. * It is the IOMMU driver's responsibility to ensure that the page table
  58. * is no longer accessible to the walker by this point.
  59. */
  60. void free_io_pgtable_ops(struct io_pgtable_ops *ops)
  61. {
  62. struct io_pgtable *iop;
  63. if (!ops)
  64. return;
  65. iop = container_of(ops, struct io_pgtable, ops);
  66. iop->cfg.tlb->tlb_flush_all(iop->cookie);
  67. io_pgtable_init_table[iop->fmt]->free(iop);
  68. }