301-v5.16-soc-qcom-smem-Support-reserved-memory-description.patch 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. From b5af64fceb04dc298c5e69c517b4d83893ff060b Mon Sep 17 00:00:00 2001
  2. From: Bjorn Andersson <[email protected]>
  3. Date: Thu, 30 Sep 2021 11:21:10 -0700
  4. Subject: [PATCH 1/1] soc: qcom: smem: Support reserved-memory description
  5. Practically all modern Qualcomm platforms has a single reserved-memory
  6. region for SMEM. So rather than having to describe SMEM in the form of a
  7. node with a reference to a reserved-memory node, allow the SMEM device
  8. to be instantiated directly from the reserved-memory node.
  9. The current means of falling back to dereferencing the "memory-region"
  10. is kept as a fallback, if it's determined that the SMEM node is a
  11. reserved-memory node.
  12. The "qcom,smem" compatible is added to the reserved_mem_matches list, to
  13. allow the reserved-memory device to be probed.
  14. In order to retain the readability of the code, the resolution of
  15. resources is split from the actual ioremapping.
  16. Signed-off-by: Bjorn Andersson <[email protected]>
  17. Acked-by: Rob Herring <[email protected]>
  18. Reviewed-by: Vladimir Zapolskiy <[email protected]>
  19. Link: https://lore.kernel.org/r/[email protected]
  20. ---
  21. drivers/of/platform.c | 1 +
  22. drivers/soc/qcom/smem.c | 57 ++++++++++++++++++++++++++++-------------
  23. 2 files changed, 40 insertions(+), 18 deletions(-)
  24. --- a/drivers/of/platform.c
  25. +++ b/drivers/of/platform.c
  26. @@ -509,6 +509,7 @@ EXPORT_SYMBOL_GPL(of_platform_default_po
  27. static const struct of_device_id reserved_mem_matches[] = {
  28. { .compatible = "qcom,rmtfs-mem" },
  29. { .compatible = "qcom,cmd-db" },
  30. + { .compatible = "qcom,smem" },
  31. { .compatible = "ramoops" },
  32. { .compatible = "nvmem-rmem" },
  33. {}
  34. --- a/drivers/soc/qcom/smem.c
  35. +++ b/drivers/soc/qcom/smem.c
  36. @@ -9,6 +9,7 @@
  37. #include <linux/module.h>
  38. #include <linux/of.h>
  39. #include <linux/of_address.h>
  40. +#include <linux/of_reserved_mem.h>
  41. #include <linux/platform_device.h>
  42. #include <linux/sizes.h>
  43. #include <linux/slab.h>
  44. @@ -240,7 +241,7 @@ static const u8 SMEM_INFO_MAGIC[] = { 0x
  45. * @size: size of the memory region
  46. */
  47. struct smem_region {
  48. - u32 aux_base;
  49. + phys_addr_t aux_base;
  50. void __iomem *virt_base;
  51. size_t size;
  52. };
  53. @@ -499,7 +500,7 @@ static void *qcom_smem_get_global(struct
  54. for (i = 0; i < smem->num_regions; i++) {
  55. region = &smem->regions[i];
  56. - if (region->aux_base == aux_base || !aux_base) {
  57. + if ((u32)region->aux_base == aux_base || !aux_base) {
  58. if (size != NULL)
  59. *size = le32_to_cpu(entry->size);
  60. return region->virt_base + le32_to_cpu(entry->offset);
  61. @@ -664,7 +665,7 @@ phys_addr_t qcom_smem_virt_to_phys(void
  62. if (p < region->virt_base + region->size) {
  63. u64 offset = p - region->virt_base;
  64. - return (phys_addr_t)region->aux_base + offset;
  65. + return region->aux_base + offset;
  66. }
  67. }
  68. @@ -863,12 +864,12 @@ qcom_smem_enumerate_partitions(struct qc
  69. return 0;
  70. }
  71. -static int qcom_smem_map_memory(struct qcom_smem *smem, struct device *dev,
  72. - const char *name, int i)
  73. +static int qcom_smem_resolve_mem(struct qcom_smem *smem, const char *name,
  74. + struct smem_region *region)
  75. {
  76. + struct device *dev = smem->dev;
  77. struct device_node *np;
  78. struct resource r;
  79. - resource_size_t size;
  80. int ret;
  81. np = of_parse_phandle(dev->of_node, name, 0);
  82. @@ -881,13 +882,9 @@ static int qcom_smem_map_memory(struct q
  83. of_node_put(np);
  84. if (ret)
  85. return ret;
  86. - size = resource_size(&r);
  87. - smem->regions[i].virt_base = devm_ioremap_wc(dev, r.start, size);
  88. - if (!smem->regions[i].virt_base)
  89. - return -ENOMEM;
  90. - smem->regions[i].aux_base = (u32)r.start;
  91. - smem->regions[i].size = size;
  92. + region->aux_base = r.start;
  93. + region->size = resource_size(&r);
  94. return 0;
  95. }
  96. @@ -895,12 +892,14 @@ static int qcom_smem_map_memory(struct q
  97. static int qcom_smem_probe(struct platform_device *pdev)
  98. {
  99. struct smem_header *header;
  100. + struct reserved_mem *rmem;
  101. struct qcom_smem *smem;
  102. size_t array_size;
  103. int num_regions;
  104. int hwlock_id;
  105. u32 version;
  106. int ret;
  107. + int i;
  108. num_regions = 1;
  109. if (of_find_property(pdev->dev.of_node, "qcom,rpm-msg-ram", NULL))
  110. @@ -914,13 +913,35 @@ static int qcom_smem_probe(struct platfo
  111. smem->dev = &pdev->dev;
  112. smem->num_regions = num_regions;
  113. - ret = qcom_smem_map_memory(smem, &pdev->dev, "memory-region", 0);
  114. - if (ret)
  115. - return ret;
  116. -
  117. - if (num_regions > 1 && (ret = qcom_smem_map_memory(smem, &pdev->dev,
  118. - "qcom,rpm-msg-ram", 1)))
  119. - return ret;
  120. + rmem = of_reserved_mem_lookup(pdev->dev.of_node);
  121. + if (rmem) {
  122. + smem->regions[0].aux_base = rmem->base;
  123. + smem->regions[0].size = rmem->size;
  124. + } else {
  125. + /*
  126. + * Fall back to the memory-region reference, if we're not a
  127. + * reserved-memory node.
  128. + */
  129. + ret = qcom_smem_resolve_mem(smem, "memory-region", &smem->regions[0]);
  130. + if (ret)
  131. + return ret;
  132. + }
  133. +
  134. + if (num_regions > 1) {
  135. + ret = qcom_smem_resolve_mem(smem, "qcom,rpm-msg-ram", &smem->regions[1]);
  136. + if (ret)
  137. + return ret;
  138. + }
  139. +
  140. + for (i = 0; i < num_regions; i++) {
  141. + smem->regions[i].virt_base = devm_ioremap_wc(&pdev->dev,
  142. + smem->regions[i].aux_base,
  143. + smem->regions[i].size);
  144. + if (!smem->regions[i].virt_base) {
  145. + dev_err(&pdev->dev, "failed to remap %pa\n", &smem->regions[i].aux_base);
  146. + return -ENOMEM;
  147. + }
  148. + }
  149. header = smem->regions[0].virt_base;
  150. if (le32_to_cpu(header->initialized) != 1 ||