io-pgtable.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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. extern struct io_pgtable_init_fns io_pgtable_arm_32_lpae_s1_init_fns;
  25. extern struct io_pgtable_init_fns io_pgtable_arm_32_lpae_s2_init_fns;
  26. extern struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s1_init_fns;
  27. extern struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s2_init_fns;
  28. static const struct io_pgtable_init_fns *
  29. io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] =
  30. {
  31. #ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE
  32. [ARM_32_LPAE_S1] = &io_pgtable_arm_32_lpae_s1_init_fns,
  33. [ARM_32_LPAE_S2] = &io_pgtable_arm_32_lpae_s2_init_fns,
  34. [ARM_64_LPAE_S1] = &io_pgtable_arm_64_lpae_s1_init_fns,
  35. [ARM_64_LPAE_S2] = &io_pgtable_arm_64_lpae_s2_init_fns,
  36. #endif
  37. };
  38. struct io_pgtable_ops *alloc_io_pgtable_ops(enum io_pgtable_fmt fmt,
  39. struct io_pgtable_cfg *cfg,
  40. void *cookie)
  41. {
  42. struct io_pgtable *iop;
  43. const struct io_pgtable_init_fns *fns;
  44. if (fmt >= IO_PGTABLE_NUM_FMTS)
  45. return NULL;
  46. fns = io_pgtable_init_table[fmt];
  47. if (!fns)
  48. return NULL;
  49. iop = fns->alloc(cfg, cookie);
  50. if (!iop)
  51. return NULL;
  52. iop->fmt = fmt;
  53. iop->cookie = cookie;
  54. iop->cfg = *cfg;
  55. return &iop->ops;
  56. }
  57. /*
  58. * It is the IOMMU driver's responsibility to ensure that the page table
  59. * is no longer accessible to the walker by this point.
  60. */
  61. void free_io_pgtable_ops(struct io_pgtable_ops *ops)
  62. {
  63. struct io_pgtable *iop;
  64. if (!ops)
  65. return;
  66. iop = container_of(ops, struct io_pgtable, ops);
  67. iop->cfg.tlb->tlb_flush_all(iop->cookie);
  68. io_pgtable_init_table[iop->fmt]->free(iop);
  69. }