Commit f618c4703a14672d27bc2ca5d132a844363d6f5f

Authored by Marek Szyprowski
Committed by Grant Likely
1 parent 3f0c820664

drivers: of: add support for custom reserved memory drivers

Add support for custom reserved memory drivers. Call their init() function
for each reserved region and prepare for using operations provided by them
with by the reserved_mem->ops array.

Based on previous code provided by Josh Cartwright <joshc@codeaurora.org>

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Grant Likely <grant.likely@linaro.org>

Showing 3 changed files with 72 additions and 0 deletions Side-by-side Diff

drivers/of/of_reserved_mem.c
... ... @@ -170,7 +170,34 @@
170 170 return 0;
171 171 }
172 172  
  173 +static const struct of_device_id __rmem_of_table_sentinel
  174 + __used __section(__reservedmem_of_table_end);
  175 +
173 176 /**
  177 + * res_mem_init_node() - call region specific reserved memory init code
  178 + */
  179 +static int __init __reserved_mem_init_node(struct reserved_mem *rmem)
  180 +{
  181 + extern const struct of_device_id __reservedmem_of_table[];
  182 + const struct of_device_id *i;
  183 +
  184 + for (i = __reservedmem_of_table; i < &__rmem_of_table_sentinel; i++) {
  185 + reservedmem_of_init_fn initfn = i->data;
  186 + const char *compat = i->compatible;
  187 +
  188 + if (!of_flat_dt_is_compatible(rmem->fdt_node, compat))
  189 + continue;
  190 +
  191 + if (initfn(rmem, rmem->fdt_node, rmem->name) == 0) {
  192 + pr_info("Reserved memory: initialized node %s, compatible id %s\n",
  193 + rmem->name, compat);
  194 + return 0;
  195 + }
  196 + }
  197 + return -ENOENT;
  198 +}
  199 +
  200 +/**
174 201 * fdt_init_reserved_mem - allocate and init all saved reserved memory regions
175 202 */
176 203 void __init fdt_init_reserved_mem(void)
... ... @@ -184,6 +211,8 @@
184 211 if (rmem->size == 0)
185 212 err = __reserved_mem_alloc_size(node, rmem->name,
186 213 &rmem->base, &rmem->size);
  214 + if (err == 0)
  215 + __reserved_mem_init_node(rmem);
187 216 }
188 217 }
include/asm-generic/vmlinux.lds.h
... ... @@ -167,6 +167,16 @@
167 167 #define CLK_OF_TABLES()
168 168 #endif
169 169  
  170 +#ifdef CONFIG_OF_RESERVED_MEM
  171 +#define RESERVEDMEM_OF_TABLES() \
  172 + . = ALIGN(8); \
  173 + VMLINUX_SYMBOL(__reservedmem_of_table) = .; \
  174 + *(__reservedmem_of_table) \
  175 + *(__reservedmem_of_table_end)
  176 +#else
  177 +#define RESERVEDMEM_OF_TABLES()
  178 +#endif
  179 +
170 180 #define KERNEL_DTB() \
171 181 STRUCT_ALIGN(); \
172 182 VMLINUX_SYMBOL(__dtb_start) = .; \
... ... @@ -490,6 +500,7 @@
490 500 TRACE_SYSCALLS() \
491 501 MEM_DISCARD(init.rodata) \
492 502 CLK_OF_TABLES() \
  503 + RESERVEDMEM_OF_TABLES() \
493 504 CLKSRC_OF_TABLES() \
494 505 KERNEL_DTB() \
495 506 IRQCHIP_OF_MATCH_TABLE()
include/linux/of_reserved_mem.h
1 1 #ifndef __OF_RESERVED_MEM_H
2 2 #define __OF_RESERVED_MEM_H
3 3  
  4 +struct device;
  5 +struct of_phandle_args;
  6 +struct reserved_mem_ops;
  7 +
4 8 struct reserved_mem {
5 9 const char *name;
6 10 unsigned long fdt_node;
  11 + const struct reserved_mem_ops *ops;
7 12 phys_addr_t base;
8 13 phys_addr_t size;
  14 + void *priv;
9 15 };
10 16  
  17 +struct reserved_mem_ops {
  18 + void (*device_init)(struct reserved_mem *rmem,
  19 + struct device *dev);
  20 + void (*device_release)(struct reserved_mem *rmem,
  21 + struct device *dev);
  22 +};
  23 +
  24 +typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem,
  25 + unsigned long node, const char *uname);
  26 +
11 27 #ifdef CONFIG_OF_RESERVED_MEM
12 28 void fdt_init_reserved_mem(void);
13 29 void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
14 30 phys_addr_t base, phys_addr_t size);
  31 +
  32 +#define RESERVEDMEM_OF_DECLARE(name, compat, init) \
  33 + static const struct of_device_id __reservedmem_of_table_##name \
  34 + __used __section(__reservedmem_of_table) \
  35 + = { .compatible = compat, \
  36 + .data = (init == (reservedmem_of_init_fn)NULL) ? \
  37 + init : init }
  38 +
15 39 #else
16 40 static inline void fdt_init_reserved_mem(void) { }
17 41 static inline void fdt_reserved_mem_save_node(unsigned long node,
18 42 const char *uname, phys_addr_t base, phys_addr_t size) { }
  43 +
  44 +#define RESERVEDMEM_OF_DECLARE(name, compat, init) \
  45 + static const struct of_device_id __reservedmem_of_table_##name \
  46 + __attribute__((unused)) \
  47 + = { .compatible = compat, \
  48 + .data = (init == (reservedmem_of_init_fn)NULL) ? \
  49 + init : init }
  50 +
19 51 #endif
20 52  
21 53 #endif /* __OF_RESERVED_MEM_H */