0051-drivers-of-add-support-for-custom-reserved-memory-dr.patch 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. From fc9e25ed9db2fcfbf16a9cbbf5a1f449da78f1d9 Mon Sep 17 00:00:00 2001
  2. From: Marek Szyprowski <[email protected]>
  3. Date: Fri, 28 Feb 2014 14:42:49 +0100
  4. Subject: [PATCH 051/182] drivers: of: add support for custom reserved memory
  5. drivers
  6. Add support for custom reserved memory drivers. Call their init() function
  7. for each reserved region and prepare for using operations provided by them
  8. with by the reserved_mem->ops array.
  9. Based on previous code provided by Josh Cartwright <[email protected]>
  10. Signed-off-by: Marek Szyprowski <[email protected]>
  11. Signed-off-by: Grant Likely <[email protected]>
  12. ---
  13. drivers/of/of_reserved_mem.c | 29 +++++++++++++++++++++++++++++
  14. include/asm-generic/vmlinux.lds.h | 11 +++++++++++
  15. include/linux/of_reserved_mem.h | 32 ++++++++++++++++++++++++++++++++
  16. 3 files changed, 72 insertions(+)
  17. --- a/drivers/of/of_reserved_mem.c
  18. +++ b/drivers/of/of_reserved_mem.c
  19. @@ -170,6 +170,33 @@ static int __init __reserved_mem_alloc_s
  20. return 0;
  21. }
  22. +static const struct of_device_id __rmem_of_table_sentinel
  23. + __used __section(__reservedmem_of_table_end);
  24. +
  25. +/**
  26. + * res_mem_init_node() - call region specific reserved memory init code
  27. + */
  28. +static int __init __reserved_mem_init_node(struct reserved_mem *rmem)
  29. +{
  30. + extern const struct of_device_id __reservedmem_of_table[];
  31. + const struct of_device_id *i;
  32. +
  33. + for (i = __reservedmem_of_table; i < &__rmem_of_table_sentinel; i++) {
  34. + reservedmem_of_init_fn initfn = i->data;
  35. + const char *compat = i->compatible;
  36. +
  37. + if (!of_flat_dt_is_compatible(rmem->fdt_node, compat))
  38. + continue;
  39. +
  40. + if (initfn(rmem, rmem->fdt_node, rmem->name) == 0) {
  41. + pr_info("Reserved memory: initialized node %s, compatible id %s\n",
  42. + rmem->name, compat);
  43. + return 0;
  44. + }
  45. + }
  46. + return -ENOENT;
  47. +}
  48. +
  49. /**
  50. * fdt_init_reserved_mem - allocate and init all saved reserved memory regions
  51. */
  52. @@ -184,5 +211,7 @@ void __init fdt_init_reserved_mem(void)
  53. if (rmem->size == 0)
  54. err = __reserved_mem_alloc_size(node, rmem->name,
  55. &rmem->base, &rmem->size);
  56. + if (err == 0)
  57. + __reserved_mem_init_node(rmem);
  58. }
  59. }
  60. --- a/include/asm-generic/vmlinux.lds.h
  61. +++ b/include/asm-generic/vmlinux.lds.h
  62. @@ -177,6 +177,16 @@
  63. #define CLK_OF_TABLES()
  64. #endif
  65. +#ifdef CONFIG_OF_RESERVED_MEM
  66. +#define RESERVEDMEM_OF_TABLES() \
  67. + . = ALIGN(8); \
  68. + VMLINUX_SYMBOL(__reservedmem_of_table) = .; \
  69. + *(__reservedmem_of_table) \
  70. + *(__reservedmem_of_table_end)
  71. +#else
  72. +#define RESERVEDMEM_OF_TABLES()
  73. +#endif
  74. +
  75. #ifdef CONFIG_SMP
  76. #define CPU_METHOD_OF_TABLES() . = ALIGN(8); \
  77. VMLINUX_SYMBOL(__cpu_method_of_table_begin) = .; \
  78. @@ -510,6 +520,7 @@
  79. TRACE_SYSCALLS() \
  80. MEM_DISCARD(init.rodata) \
  81. CLK_OF_TABLES() \
  82. + RESERVEDMEM_OF_TABLES() \
  83. CLKSRC_OF_TABLES() \
  84. CPU_METHOD_OF_TABLES() \
  85. KERNEL_DTB() \
  86. --- a/include/linux/of_reserved_mem.h
  87. +++ b/include/linux/of_reserved_mem.h
  88. @@ -1,21 +1,53 @@
  89. #ifndef __OF_RESERVED_MEM_H
  90. #define __OF_RESERVED_MEM_H
  91. +struct device;
  92. +struct of_phandle_args;
  93. +struct reserved_mem_ops;
  94. +
  95. struct reserved_mem {
  96. const char *name;
  97. unsigned long fdt_node;
  98. + const struct reserved_mem_ops *ops;
  99. phys_addr_t base;
  100. phys_addr_t size;
  101. + void *priv;
  102. +};
  103. +
  104. +struct reserved_mem_ops {
  105. + void (*device_init)(struct reserved_mem *rmem,
  106. + struct device *dev);
  107. + void (*device_release)(struct reserved_mem *rmem,
  108. + struct device *dev);
  109. };
  110. +typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem,
  111. + unsigned long node, const char *uname);
  112. +
  113. #ifdef CONFIG_OF_RESERVED_MEM
  114. void fdt_init_reserved_mem(void);
  115. void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
  116. phys_addr_t base, phys_addr_t size);
  117. +
  118. +#define RESERVEDMEM_OF_DECLARE(name, compat, init) \
  119. + static const struct of_device_id __reservedmem_of_table_##name \
  120. + __used __section(__reservedmem_of_table) \
  121. + = { .compatible = compat, \
  122. + .data = (init == (reservedmem_of_init_fn)NULL) ? \
  123. + init : init }
  124. +
  125. #else
  126. static inline void fdt_init_reserved_mem(void) { }
  127. static inline void fdt_reserved_mem_save_node(unsigned long node,
  128. const char *uname, phys_addr_t base, phys_addr_t size) { }
  129. +
  130. +#define RESERVEDMEM_OF_DECLARE(name, compat, init) \
  131. + static const struct of_device_id __reservedmem_of_table_##name \
  132. + __attribute__((unused)) \
  133. + = { .compatible = compat, \
  134. + .data = (init == (reservedmem_of_init_fn)NULL) ? \
  135. + init : init }
  136. +
  137. #endif
  138. #endif /* __OF_RESERVED_MEM_H */