mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
Merge remote-tracking branch 'lsk/v3.10/topic/libfdt' into linux-linaro-lsk
Conflicts: drivers/of/fdt.c
This commit is contained in:
@@ -40,7 +40,7 @@ struct machine_desc * __init setup_machine_fdt(void *dt)
|
||||
const char *model, *compat;
|
||||
void *clk;
|
||||
char manufacturer[16];
|
||||
unsigned long len;
|
||||
int len;
|
||||
|
||||
/* check device tree validity */
|
||||
if (be32_to_cpu(devtree->magic) != OF_DT_HEADER)
|
||||
|
||||
@@ -212,7 +212,7 @@ struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
|
||||
}
|
||||
if (!mdesc_best) {
|
||||
const char *prop;
|
||||
long size;
|
||||
int size;
|
||||
|
||||
early_print("\nError: unrecognized/unsupported "
|
||||
"device tree compatible list:\n[ ");
|
||||
|
||||
@@ -53,7 +53,7 @@ static int __init vexpress_dt_find_scu(unsigned long node,
|
||||
{
|
||||
if (of_flat_dt_match(node, vexpress_dt_cortex_a9_match)) {
|
||||
phys_addr_t phys_addr;
|
||||
__be32 *reg = of_get_flat_dt_prop(node, "reg", NULL);
|
||||
const __be32 *reg = of_get_flat_dt_prop(node, "reg", NULL);
|
||||
|
||||
if (WARN_ON(!reg))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -116,8 +116,8 @@ device_initcall(s5p_mfc_memory_init);
|
||||
int __init s5p_fdt_find_mfc_mem(unsigned long node, const char *uname,
|
||||
int depth, void *data)
|
||||
{
|
||||
__be32 *prop;
|
||||
unsigned long len;
|
||||
const __be32 *prop;
|
||||
int len;
|
||||
struct s5p_mfc_dt_meminfo *mfc_mem = data;
|
||||
|
||||
if (!data)
|
||||
|
||||
@@ -52,13 +52,13 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EARLY_PRINTK
|
||||
static char *stdout;
|
||||
static const char *stdout;
|
||||
|
||||
static int __init early_init_dt_scan_chosen_serial(unsigned long node,
|
||||
const char *uname, int depth, void *data)
|
||||
{
|
||||
unsigned long l;
|
||||
char *p;
|
||||
int l;
|
||||
const char *p;
|
||||
|
||||
pr_debug("%s: depth: %d, uname: %s\n", __func__, depth, uname);
|
||||
|
||||
@@ -89,7 +89,7 @@ static int __init early_init_dt_scan_chosen_serial(unsigned long node,
|
||||
(strncmp(p, "xlnx,opb-uartlite", 17) == 0) ||
|
||||
(strncmp(p, "xlnx,axi-uartlite", 17) == 0) ||
|
||||
(strncmp(p, "xlnx,mdm", 8) == 0)) {
|
||||
unsigned int *addrp;
|
||||
const unsigned int *addrp;
|
||||
|
||||
*(u32 *)data = UARTLITE;
|
||||
|
||||
|
||||
@@ -55,9 +55,9 @@ int crash_mem_ranges;
|
||||
int __init early_init_dt_scan_fw_dump(unsigned long node,
|
||||
const char *uname, int depth, void *data)
|
||||
{
|
||||
__be32 *sections;
|
||||
const __be32 *sections;
|
||||
int i, num_sections;
|
||||
unsigned long size;
|
||||
int size;
|
||||
const int *token;
|
||||
|
||||
if (depth != 1 || strcmp(uname, "rtas") != 0)
|
||||
|
||||
@@ -162,7 +162,7 @@ static struct ibm_pa_feature {
|
||||
{CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0},
|
||||
};
|
||||
|
||||
static void __init scan_features(unsigned long node, unsigned char *ftrs,
|
||||
static void __init scan_features(unsigned long node, const unsigned char *ftrs,
|
||||
unsigned long tablelen,
|
||||
struct ibm_pa_feature *fp,
|
||||
unsigned long ft_size)
|
||||
@@ -201,8 +201,8 @@ static void __init scan_features(unsigned long node, unsigned char *ftrs,
|
||||
|
||||
static void __init check_cpu_pa_features(unsigned long node)
|
||||
{
|
||||
unsigned char *pa_ftrs;
|
||||
unsigned long tablelen;
|
||||
const unsigned char *pa_ftrs;
|
||||
int tablelen;
|
||||
|
||||
pa_ftrs = of_get_flat_dt_prop(node, "ibm,pa-features", &tablelen);
|
||||
if (pa_ftrs == NULL)
|
||||
@@ -215,7 +215,7 @@ static void __init check_cpu_pa_features(unsigned long node)
|
||||
#ifdef CONFIG_PPC_STD_MMU_64
|
||||
static void __init check_cpu_slb_size(unsigned long node)
|
||||
{
|
||||
u32 *slb_size_ptr;
|
||||
const __be32 *slb_size_ptr;
|
||||
|
||||
slb_size_ptr = of_get_flat_dt_prop(node, "slb-size", NULL);
|
||||
if (slb_size_ptr != NULL) {
|
||||
@@ -256,7 +256,7 @@ static struct feature_property {
|
||||
static inline void identical_pvr_fixup(unsigned long node)
|
||||
{
|
||||
unsigned int pvr;
|
||||
char *model = of_get_flat_dt_prop(node, "model", NULL);
|
||||
const char *model = of_get_flat_dt_prop(node, "model", NULL);
|
||||
|
||||
/*
|
||||
* Since 440GR(x)/440EP(x) processors have the same pvr,
|
||||
@@ -294,11 +294,11 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
|
||||
const char *uname, int depth,
|
||||
void *data)
|
||||
{
|
||||
char *type = of_get_flat_dt_prop(node, "device_type", NULL);
|
||||
const u32 *prop;
|
||||
const u32 *intserv;
|
||||
const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
|
||||
const __be32 *prop;
|
||||
const __be32 *intserv;
|
||||
int i, nthreads;
|
||||
unsigned long len;
|
||||
int len;
|
||||
int found = -1;
|
||||
int found_thread = 0;
|
||||
|
||||
@@ -389,7 +389,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
|
||||
int __init early_init_dt_scan_chosen_ppc(unsigned long node, const char *uname,
|
||||
int depth, void *data)
|
||||
{
|
||||
unsigned long *lprop;
|
||||
const unsigned long *lprop; /* All these set by kernel, so no need to convert endian */
|
||||
|
||||
/* Use common scan routine to determine if this is the chosen node */
|
||||
if (early_init_dt_scan_chosen(node, uname, depth, data) == 0)
|
||||
@@ -440,8 +440,9 @@ int __init early_init_dt_scan_chosen_ppc(unsigned long node, const char *uname,
|
||||
*/
|
||||
static int __init early_init_dt_scan_drconf_memory(unsigned long node)
|
||||
{
|
||||
__be32 *dm, *ls, *usm;
|
||||
unsigned long l, n, flags;
|
||||
const __be32 *dm, *ls, *usm;
|
||||
int l;
|
||||
unsigned long n, flags;
|
||||
u64 base, size, memblock_size;
|
||||
unsigned int is_kexec_kdump = 0, rngs;
|
||||
|
||||
|
||||
@@ -1135,7 +1135,7 @@ void __init rtas_initialize(void)
|
||||
int __init early_init_dt_scan_rtas(unsigned long node,
|
||||
const char *uname, int depth, void *data)
|
||||
{
|
||||
u32 *basep, *entryp, *sizep;
|
||||
const u32 *basep, *entryp, *sizep;
|
||||
|
||||
if (depth != 1 || strcmp(uname, "rtas") != 0)
|
||||
return 0;
|
||||
|
||||
@@ -250,9 +250,9 @@ static int __init htab_dt_scan_seg_sizes(unsigned long node,
|
||||
const char *uname, int depth,
|
||||
void *data)
|
||||
{
|
||||
char *type = of_get_flat_dt_prop(node, "device_type", NULL);
|
||||
u32 *prop;
|
||||
unsigned long size = 0;
|
||||
const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
|
||||
const __be32 *prop;
|
||||
int size = 0;
|
||||
|
||||
/* We are scanning "cpu" nodes only */
|
||||
if (type == NULL || strcmp(type, "cpu") != 0)
|
||||
@@ -306,9 +306,9 @@ static int __init htab_dt_scan_page_sizes(unsigned long node,
|
||||
const char *uname, int depth,
|
||||
void *data)
|
||||
{
|
||||
char *type = of_get_flat_dt_prop(node, "device_type", NULL);
|
||||
u32 *prop;
|
||||
unsigned long size = 0;
|
||||
const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
|
||||
const __be32 *prop;
|
||||
int size = 0;
|
||||
|
||||
/* We are scanning "cpu" nodes only */
|
||||
if (type == NULL || strcmp(type, "cpu") != 0)
|
||||
@@ -389,9 +389,9 @@ static int __init htab_dt_scan_page_sizes(unsigned long node,
|
||||
static int __init htab_dt_scan_hugepage_blocks(unsigned long node,
|
||||
const char *uname, int depth,
|
||||
void *data) {
|
||||
char *type = of_get_flat_dt_prop(node, "device_type", NULL);
|
||||
unsigned long *addr_prop;
|
||||
u32 *page_count_prop;
|
||||
const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
|
||||
const __be64 *addr_prop;
|
||||
const __be32 *page_count_prop;
|
||||
unsigned int expected_pages;
|
||||
long unsigned int phys_addr;
|
||||
long unsigned int block_size;
|
||||
@@ -533,8 +533,8 @@ static int __init htab_dt_scan_pftsize(unsigned long node,
|
||||
const char *uname, int depth,
|
||||
void *data)
|
||||
{
|
||||
char *type = of_get_flat_dt_prop(node, "device_type", NULL);
|
||||
u32 *prop;
|
||||
const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
|
||||
const __be32 *prop;
|
||||
|
||||
/* We are scanning "cpu" nodes only */
|
||||
if (type == NULL || strcmp(type, "cpu") != 0)
|
||||
|
||||
@@ -199,8 +199,8 @@ static void __init efika_setup_arch(void)
|
||||
|
||||
static int __init efika_probe(void)
|
||||
{
|
||||
char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
|
||||
"model", NULL);
|
||||
const char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
|
||||
"model", NULL);
|
||||
|
||||
if (model == NULL)
|
||||
return 0;
|
||||
|
||||
@@ -574,8 +574,8 @@ chrp_init2(void)
|
||||
|
||||
static int __init chrp_probe(void)
|
||||
{
|
||||
char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(),
|
||||
"device_type", NULL);
|
||||
const char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(),
|
||||
"device_type", NULL);
|
||||
if (dtype == NULL)
|
||||
return 0;
|
||||
if (strcmp(dtype, "chrp"))
|
||||
|
||||
@@ -35,8 +35,8 @@ static unsigned int opal_irq_count;
|
||||
int __init early_init_dt_scan_opal(unsigned long node,
|
||||
const char *uname, int depth, void *data)
|
||||
{
|
||||
const void *basep, *entryp;
|
||||
unsigned long basesz, entrysz;
|
||||
const void *basep, *entryp, *sizep;
|
||||
int basesz, entrysz, runtimesz;
|
||||
|
||||
if (depth != 1 || strcmp(uname, "ibm,opal") != 0)
|
||||
return 0;
|
||||
@@ -50,10 +50,10 @@ int __init early_init_dt_scan_opal(unsigned long node,
|
||||
opal.base = of_read_number(basep, basesz/4);
|
||||
opal.entry = of_read_number(entryp, entrysz/4);
|
||||
|
||||
pr_debug("OPAL Base = 0x%llx (basep=%p basesz=%ld)\n",
|
||||
pr_debug("OPAL Base = 0x%llx (basep=%p basesz=%d)\n",
|
||||
opal.base, basep, basesz);
|
||||
pr_debug("OPAL Entry = 0x%llx (entryp=%p basesz=%ld)\n",
|
||||
opal.entry, entryp, entrysz);
|
||||
pr_debug("OPAL Entry = 0x%llx (sizep=%p runtimesz=%d)\n",
|
||||
opal.size, sizep, runtimesz);
|
||||
|
||||
powerpc_firmware_features |= FW_FEATURE_OPAL;
|
||||
if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) {
|
||||
@@ -105,7 +105,7 @@ int opal_get_chars(uint32_t vtermno, char *buf, int count)
|
||||
opal_poll_events(&evt);
|
||||
if ((evt & OPAL_EVENT_CONSOLE_INPUT) == 0)
|
||||
return 0;
|
||||
len = count;
|
||||
len = cpu_to_be64(count);
|
||||
rc = opal_console_read(vtermno, &len, buf);
|
||||
if (rc == OPAL_SUCCESS)
|
||||
return len;
|
||||
|
||||
@@ -646,7 +646,7 @@ static int __init pseries_probe_fw_features(unsigned long node,
|
||||
void *data)
|
||||
{
|
||||
const char *prop;
|
||||
unsigned long len;
|
||||
int len;
|
||||
static int hypertas_found;
|
||||
static int vec5_found;
|
||||
|
||||
@@ -679,7 +679,7 @@ static int __init pseries_probe_fw_features(unsigned long node,
|
||||
static int __init pSeries_probe(void)
|
||||
{
|
||||
unsigned long root = of_get_flat_dt_root();
|
||||
char *dtype = of_get_flat_dt_prop(root, "device_type", NULL);
|
||||
const char *dtype = of_get_flat_dt_prop(root, "device_type", NULL);
|
||||
|
||||
if (dtype == NULL)
|
||||
return 0;
|
||||
|
||||
@@ -222,6 +222,43 @@ static int __init parse_bootparam(const bp_tag_t* tag)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
bool __initdata dt_memory_scan = false;
|
||||
|
||||
#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
|
||||
unsigned long xtensa_kio_paddr = XCHAL_KIO_DEFAULT_PADDR;
|
||||
EXPORT_SYMBOL(xtensa_kio_paddr);
|
||||
|
||||
static int __init xtensa_dt_io_area(unsigned long node, const char *uname,
|
||||
int depth, void *data)
|
||||
{
|
||||
const __be32 *ranges;
|
||||
int len;
|
||||
|
||||
if (depth > 1)
|
||||
return 0;
|
||||
|
||||
if (!of_flat_dt_is_compatible(node, "simple-bus"))
|
||||
return 0;
|
||||
|
||||
ranges = of_get_flat_dt_prop(node, "ranges", &len);
|
||||
if (!ranges)
|
||||
return 1;
|
||||
if (len == 0)
|
||||
return 1;
|
||||
|
||||
xtensa_kio_paddr = of_read_ulong(ranges+1, 1);
|
||||
/* round down to nearest 256MB boundary */
|
||||
xtensa_kio_paddr &= 0xf0000000;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
static int __init xtensa_dt_io_area(unsigned long node, const char *uname,
|
||||
int depth, void *data)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void __init early_init_dt_add_memory_arch(u64 base, u64 size)
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@ config OF_SELFTEST
|
||||
config OF_FLATTREE
|
||||
bool
|
||||
select DTC
|
||||
select LIBFDT
|
||||
|
||||
config OF_EARLY_FLATTREE
|
||||
bool
|
||||
@@ -83,4 +84,10 @@ config OF_MTD
|
||||
depends on MTD
|
||||
def_bool y
|
||||
|
||||
config OF_RESERVED_MEM
|
||||
depends on OF_EARLY_FLATTREE
|
||||
bool
|
||||
help
|
||||
Helpers to allow for reservation of memory regions
|
||||
|
||||
endmenu # OF
|
||||
|
||||
@@ -11,3 +11,6 @@ obj-$(CONFIG_OF_MDIO) += of_mdio.o
|
||||
obj-$(CONFIG_OF_PCI) += of_pci.o
|
||||
obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o
|
||||
obj-$(CONFIG_OF_MTD) += of_mtd.o
|
||||
obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
|
||||
|
||||
CFLAGS_fdt.o = -I$(src)/../../scripts/dtc/libfdt
|
||||
|
||||
@@ -33,6 +33,7 @@ struct device_node *of_allnodes;
|
||||
EXPORT_SYMBOL(of_allnodes);
|
||||
struct device_node *of_chosen;
|
||||
struct device_node *of_aliases;
|
||||
static struct device_node *of_stdout;
|
||||
|
||||
DEFINE_MUTEX(of_aliases_mutex);
|
||||
|
||||
@@ -1690,6 +1691,15 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
|
||||
of_chosen = of_find_node_by_path("/chosen");
|
||||
if (of_chosen == NULL)
|
||||
of_chosen = of_find_node_by_path("/chosen@0");
|
||||
|
||||
if (of_chosen) {
|
||||
const char *name;
|
||||
|
||||
name = of_get_property(of_chosen, "linux,stdout-path", NULL);
|
||||
if (name)
|
||||
of_stdout = of_find_node_by_path(name);
|
||||
}
|
||||
|
||||
of_aliases = of_find_node_by_path("/aliases");
|
||||
if (!of_aliases)
|
||||
return;
|
||||
@@ -1799,3 +1809,19 @@ const char *of_prop_next_string(struct property *prop, const char *cur)
|
||||
return curv;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_prop_next_string);
|
||||
|
||||
/**
|
||||
* of_device_is_stdout_path - check if a device node matches the
|
||||
* linux,stdout-path property
|
||||
*
|
||||
* Check if this device node matches the linux,stdout-path property
|
||||
* in the chosen node. return true if yes, false otherwise.
|
||||
*/
|
||||
int of_device_is_stdout_path(struct device_node *dn)
|
||||
{
|
||||
if (!of_stdout)
|
||||
return false;
|
||||
|
||||
return of_stdout == dn;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_device_is_stdout_path);
|
||||
|
||||
461
drivers/of/fdt.c
461
drivers/of/fdt.c
File diff suppressed because it is too large
Load Diff
217
drivers/of/of_reserved_mem.c
Normal file
217
drivers/of/of_reserved_mem.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Device tree based initialization code for reserved memory.
|
||||
*
|
||||
* Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
|
||||
* Copyright (c) 2013,2014 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com
|
||||
* Author: Marek Szyprowski <m.szyprowski@samsung.com>
|
||||
* Author: Josh Cartwright <joshc@codeaurora.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License or (at your optional) any later version of the license.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/of_reserved_mem.h>
|
||||
|
||||
#define MAX_RESERVED_REGIONS 16
|
||||
static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
|
||||
static int reserved_mem_count;
|
||||
|
||||
#if defined(CONFIG_HAVE_MEMBLOCK)
|
||||
#include <linux/memblock.h>
|
||||
int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
|
||||
phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
|
||||
phys_addr_t *res_base)
|
||||
{
|
||||
/*
|
||||
* We use __memblock_alloc_base() because memblock_alloc_base()
|
||||
* panic()s on allocation failure.
|
||||
*/
|
||||
phys_addr_t base = __memblock_alloc_base(size, align, end);
|
||||
if (!base)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Check if the allocated region fits in to start..end window
|
||||
*/
|
||||
if (base < start) {
|
||||
memblock_free(base, size);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*res_base = base;
|
||||
if (nomap)
|
||||
return memblock_remove(base, size);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
|
||||
phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
|
||||
phys_addr_t *res_base)
|
||||
{
|
||||
pr_err("Reserved memory not supported, ignoring region 0x%llx%s\n",
|
||||
size, nomap ? " (nomap)" : "");
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* res_mem_save_node() - save fdt node for second pass initialization
|
||||
*/
|
||||
void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname,
|
||||
phys_addr_t base, phys_addr_t size)
|
||||
{
|
||||
struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
|
||||
|
||||
if (reserved_mem_count == ARRAY_SIZE(reserved_mem)) {
|
||||
pr_err("Reserved memory: not enough space all defined regions.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
rmem->fdt_node = node;
|
||||
rmem->name = uname;
|
||||
rmem->base = base;
|
||||
rmem->size = size;
|
||||
|
||||
reserved_mem_count++;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* res_mem_alloc_size() - allocate reserved memory described by 'size', 'align'
|
||||
* and 'alloc-ranges' properties
|
||||
*/
|
||||
static int __init __reserved_mem_alloc_size(unsigned long node,
|
||||
const char *uname, phys_addr_t *res_base, phys_addr_t *res_size)
|
||||
{
|
||||
int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
|
||||
phys_addr_t start = 0, end = 0;
|
||||
phys_addr_t base = 0, align = 0, size;
|
||||
int len;
|
||||
const __be32 *prop;
|
||||
int nomap;
|
||||
int ret;
|
||||
|
||||
prop = of_get_flat_dt_prop(node, "size", &len);
|
||||
if (!prop)
|
||||
return -EINVAL;
|
||||
|
||||
if (len != dt_root_size_cells * sizeof(__be32)) {
|
||||
pr_err("Reserved memory: invalid size property in '%s' node.\n",
|
||||
uname);
|
||||
return -EINVAL;
|
||||
}
|
||||
size = dt_mem_next_cell(dt_root_size_cells, &prop);
|
||||
|
||||
nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
|
||||
|
||||
prop = of_get_flat_dt_prop(node, "alignment", &len);
|
||||
if (prop) {
|
||||
if (len != dt_root_addr_cells * sizeof(__be32)) {
|
||||
pr_err("Reserved memory: invalid alignment property in '%s' node.\n",
|
||||
uname);
|
||||
return -EINVAL;
|
||||
}
|
||||
align = dt_mem_next_cell(dt_root_addr_cells, &prop);
|
||||
}
|
||||
|
||||
prop = of_get_flat_dt_prop(node, "alloc-ranges", &len);
|
||||
if (prop) {
|
||||
|
||||
if (len % t_len != 0) {
|
||||
pr_err("Reserved memory: invalid alloc-ranges property in '%s', skipping node.\n",
|
||||
uname);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
base = 0;
|
||||
|
||||
while (len > 0) {
|
||||
start = dt_mem_next_cell(dt_root_addr_cells, &prop);
|
||||
end = start + dt_mem_next_cell(dt_root_size_cells,
|
||||
&prop);
|
||||
|
||||
ret = early_init_dt_alloc_reserved_memory_arch(size,
|
||||
align, start, end, nomap, &base);
|
||||
if (ret == 0) {
|
||||
pr_debug("Reserved memory: allocated memory for '%s' node: base %pa, size %ld MiB\n",
|
||||
uname, &base,
|
||||
(unsigned long)size / SZ_1M);
|
||||
break;
|
||||
}
|
||||
len -= t_len;
|
||||
}
|
||||
|
||||
} else {
|
||||
ret = early_init_dt_alloc_reserved_memory_arch(size, align,
|
||||
0, 0, nomap, &base);
|
||||
if (ret == 0)
|
||||
pr_debug("Reserved memory: allocated memory for '%s' node: base %pa, size %ld MiB\n",
|
||||
uname, &base, (unsigned long)size / SZ_1M);
|
||||
}
|
||||
|
||||
if (base == 0) {
|
||||
pr_info("Reserved memory: failed to allocate memory for node '%s'\n",
|
||||
uname);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*res_base = base;
|
||||
*res_size = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id __rmem_of_table_sentinel
|
||||
__used __section(__reservedmem_of_table_end);
|
||||
|
||||
/**
|
||||
* res_mem_init_node() - call region specific reserved memory init code
|
||||
*/
|
||||
static int __init __reserved_mem_init_node(struct reserved_mem *rmem)
|
||||
{
|
||||
extern const struct of_device_id __reservedmem_of_table[];
|
||||
const struct of_device_id *i;
|
||||
|
||||
for (i = __reservedmem_of_table; i < &__rmem_of_table_sentinel; i++) {
|
||||
reservedmem_of_init_fn initfn = i->data;
|
||||
const char *compat = i->compatible;
|
||||
|
||||
if (!of_flat_dt_is_compatible(rmem->fdt_node, compat))
|
||||
continue;
|
||||
|
||||
if (initfn(rmem, rmem->fdt_node, rmem->name) == 0) {
|
||||
pr_info("Reserved memory: initialized node %s, compatible id %s\n",
|
||||
rmem->name, compat);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* fdt_init_reserved_mem - allocate and init all saved reserved memory regions
|
||||
*/
|
||||
void __init fdt_init_reserved_mem(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < reserved_mem_count; i++) {
|
||||
struct reserved_mem *rmem = &reserved_mem[i];
|
||||
unsigned long node = rmem->fdt_node;
|
||||
int err = 0;
|
||||
|
||||
if (rmem->size == 0)
|
||||
err = __reserved_mem_alloc_size(node, rmem->name,
|
||||
&rmem->base, &rmem->size);
|
||||
if (err == 0)
|
||||
__reserved_mem_init_node(rmem);
|
||||
}
|
||||
}
|
||||
@@ -171,6 +171,16 @@
|
||||
#define CLK_OF_TABLES()
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF_RESERVED_MEM
|
||||
#define RESERVEDMEM_OF_TABLES() \
|
||||
. = ALIGN(8); \
|
||||
VMLINUX_SYMBOL(__reservedmem_of_table) = .; \
|
||||
*(__reservedmem_of_table) \
|
||||
*(__reservedmem_of_table_end)
|
||||
#else
|
||||
#define RESERVEDMEM_OF_TABLES()
|
||||
#endif
|
||||
|
||||
#define KERNEL_DTB() \
|
||||
STRUCT_ALIGN(); \
|
||||
VMLINUX_SYMBOL(__dtb_start) = .; \
|
||||
@@ -515,6 +525,7 @@
|
||||
CPU_DISCARD(init.rodata) \
|
||||
MEM_DISCARD(init.rodata) \
|
||||
CLK_OF_TABLES() \
|
||||
RESERVEDMEM_OF_TABLES() \
|
||||
CLKSRC_OF_TABLES() \
|
||||
KERNEL_DTB() \
|
||||
IRQCHIP_OF_MATCH_TABLE()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user