Commit 31f7c3a6 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'devicetree-for-linus' of git://git.secretlab.ca/git/linux

Pull device tree core updates from Grant Likely:
 "Generally minor changes.  A bunch of bug fixes, particularly for
  initialization and some refactoring.  Most notable change if feeding
  the entire flattened tree into the random pool at boot.  May not be
  significant, but shouldn't hurt either"

Tim Bird questions whether the boot time cost of the random feeding may
be noticeable.  And "add_device_randomness()" is definitely not some
speed deamon of a function.

* tag 'devicetree-for-linus' of git://git.secretlab.ca/git/linux:
  of/platform: add error reporting to of_amba_device_create()
  irq/of: Fix comment typo for irq_of_parse_and_map
  of: Feed entire flattened device tree into the random pool
  of/fdt: Clean up casting in unflattening path
  of/fdt: Remove duplicate memory clearing on FDT unflattening
  gpio: implement gpio-ranges binding document fix
  of: call __of_parse_phandle_with_args from of_parse_phandle
  of: introduce of_parse_phandle_with_fixed_args
  of: move of_parse_phandle()
  of: move documentation of of_parse_phandle_with_args
  of: Fix missing memory initialization on FDT unflattening
  of: consolidate definition of early_init_dt_alloc_memory_arch()
  of: Make of_get_phy_mode() return int i.s.o. const int
  include: dt-binding: input: create a DT header defining key codes.
  of/platform: Staticize of_platform_device_create_pdata()
  of: Specify initrd location using 64-bit
  dt: Typo fix
  OF: make of_property_for_each_{u32|string}() use parameters if OF is not enabled
parents ec5b103e 2bc552df
...@@ -37,7 +37,7 @@ Optional properties: ...@@ -37,7 +37,7 @@ Optional properties:
If not specified or if the specified value is 0, the CLKOUT pin If not specified or if the specified value is 0, the CLKOUT pin
will be disabled. will be disabled.
- nxp,no-comparator-bypass : Allows to disable the CAN input comperator. - nxp,no-comparator-bypass : Allows to disable the CAN input comparator.
For further information, please have a look to the SJA1000 data sheet. For further information, please have a look to the SJA1000 data sheet.
......
...@@ -18,12 +18,6 @@ ...@@ -18,12 +18,6 @@
#include <asm/clk.h> #include <asm/clk.h>
#include <asm/mach_desc.h> #include <asm/mach_desc.h>
/* called from unflatten_device_tree() to bootstrap devicetree itself */
void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
{
return __va(memblock_alloc(size, align));
}
/** /**
* setup_machine_fdt - Machine setup when an dtb was passed to the kernel * setup_machine_fdt - Machine setup when an dtb was passed to the kernel
* @dt: virtual address pointer to dt blob * @dt: virtual address pointer to dt blob
......
...@@ -127,9 +127,8 @@ void __init free_initrd_mem(unsigned long start, unsigned long end) ...@@ -127,9 +127,8 @@ void __init free_initrd_mem(unsigned long start, unsigned long end)
#endif #endif
#ifdef CONFIG_OF_FLATTREE #ifdef CONFIG_OF_FLATTREE
void __init early_init_dt_setup_initrd_arch(unsigned long start, void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
unsigned long end)
{ {
pr_err("%s(%lx, %lx)\n", __func__, start, end); pr_err("%s(%llx, %llx)\n", __func__, start, end);
} }
#endif /* CONFIG_OF_FLATTREE */ #endif /* CONFIG_OF_FLATTREE */
...@@ -78,7 +78,7 @@ static int __init parse_tag_initrd2(const struct tag *tag) ...@@ -78,7 +78,7 @@ static int __init parse_tag_initrd2(const struct tag *tag)
__tagtable(ATAG_INITRD2, parse_tag_initrd2); __tagtable(ATAG_INITRD2, parse_tag_initrd2);
#ifdef CONFIG_OF_FLATTREE #ifdef CONFIG_OF_FLATTREE
void __init early_init_dt_setup_initrd_arch(unsigned long start, unsigned long end) void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
{ {
phys_initrd_start = start; phys_initrd_start = start;
phys_initrd_size = end - start; phys_initrd_size = end - start;
......
...@@ -190,11 +190,6 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) ...@@ -190,11 +190,6 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
memblock_add(base, size); memblock_add(base, size);
} }
void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
{
return __va(memblock_alloc(size, align));
}
/* /*
* Limit the memory size that was specified via FDT. * Limit the memory size that was specified via FDT.
*/ */
......
...@@ -44,8 +44,7 @@ static unsigned long phys_initrd_size __initdata = 0; ...@@ -44,8 +44,7 @@ static unsigned long phys_initrd_size __initdata = 0;
phys_addr_t memstart_addr __read_mostly = 0; phys_addr_t memstart_addr __read_mostly = 0;
void __init early_init_dt_setup_initrd_arch(unsigned long start, void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
unsigned long end)
{ {
phys_initrd_start = start; phys_initrd_start = start;
phys_initrd_size = end - start; phys_initrd_size = end - start;
......
...@@ -33,8 +33,7 @@ void __init early_init_devtree(void *params) ...@@ -33,8 +33,7 @@ void __init early_init_devtree(void *params)
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
void __init early_init_dt_setup_initrd_arch(unsigned long start, void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
unsigned long end)
{ {
initrd_start = (unsigned long)__va(start); initrd_start = (unsigned long)__va(start);
initrd_end = (unsigned long)__va(end); initrd_end = (unsigned long)__va(end);
...@@ -46,8 +45,3 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) ...@@ -46,8 +45,3 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
{ {
c6x_add_memory(base, size); c6x_add_memory(base, size);
} }
void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
{
return __va(memblock_alloc(size, align));
}
...@@ -407,10 +407,9 @@ void free_initrd_mem(unsigned long start, unsigned long end) ...@@ -407,10 +407,9 @@ void free_initrd_mem(unsigned long start, unsigned long end)
#endif #endif
#ifdef CONFIG_OF_FLATTREE #ifdef CONFIG_OF_FLATTREE
void __init early_init_dt_setup_initrd_arch(unsigned long start, void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
unsigned long end)
{ {
pr_err("%s(%lx, %lx)\n", pr_err("%s(%llx, %llx)\n",
__func__, start, end); __func__, start, end);
} }
#endif /* CONFIG_OF_FLATTREE */ #endif /* CONFIG_OF_FLATTREE */
...@@ -46,11 +46,6 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) ...@@ -46,11 +46,6 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
memblock_add(base, size); memblock_add(base, size);
} }
void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
{
return __va(memblock_alloc(size, align));
}
#ifdef CONFIG_EARLY_PRINTK #ifdef CONFIG_EARLY_PRINTK
static char *stdout; static char *stdout;
...@@ -136,8 +131,7 @@ void __init early_init_devtree(void *params) ...@@ -136,8 +131,7 @@ void __init early_init_devtree(void *params)
} }
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
void __init early_init_dt_setup_initrd_arch(unsigned long start, void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
unsigned long end)
{ {
initrd_start = (unsigned long)__va(start); initrd_start = (unsigned long)__va(start);
initrd_end = (unsigned long)__va(end); initrd_end = (unsigned long)__va(end);
......
...@@ -58,8 +58,7 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) ...@@ -58,8 +58,7 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
} }
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
void __init early_init_dt_setup_initrd_arch(unsigned long start, void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
unsigned long end)
{ {
initrd_start = (unsigned long)__va(start); initrd_start = (unsigned long)__va(start);
initrd_end = (unsigned long)__va(end); initrd_end = (unsigned long)__va(end);
......
...@@ -55,11 +55,6 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) ...@@ -55,11 +55,6 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
memblock_add(base, size); memblock_add(base, size);
} }
void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
{
return __va(memblock_alloc(size, align));
}
void __init early_init_devtree(void *params) void __init early_init_devtree(void *params)
{ {
void *alloc; void *alloc;
...@@ -96,8 +91,7 @@ void __init early_init_devtree(void *params) ...@@ -96,8 +91,7 @@ void __init early_init_devtree(void *params)
} }
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
void __init early_init_dt_setup_initrd_arch(unsigned long start, void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
unsigned long end)
{ {
initrd_start = (unsigned long)__va(start); initrd_start = (unsigned long)__va(start);
initrd_end = (unsigned long)__va(end); initrd_end = (unsigned long)__va(end);
......
...@@ -546,14 +546,8 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) ...@@ -546,14 +546,8 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
memblock_add(base, size); memblock_add(base, size);
} }
void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
{
return __va(memblock_alloc(size, align));
}
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
void __init early_init_dt_setup_initrd_arch(unsigned long start, void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
unsigned long end)
{ {
initrd_start = (unsigned long)__va(start); initrd_start = (unsigned long)__va(start);
initrd_end = (unsigned long)__va(end); initrd_end = (unsigned long)__va(end);
......
...@@ -52,8 +52,7 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) ...@@ -52,8 +52,7 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
} }
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
void __init early_init_dt_setup_initrd_arch(unsigned long start, void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
unsigned long end)
{ {
initrd_start = (unsigned long)__va(start); initrd_start = (unsigned long)__va(start);
initrd_end = (unsigned long)__va(end); initrd_end = (unsigned long)__va(end);
......
...@@ -170,8 +170,7 @@ static int __init parse_tag_fdt(const bp_tag_t *tag) ...@@ -170,8 +170,7 @@ static int __init parse_tag_fdt(const bp_tag_t *tag)
__tagtable(BP_TAG_FDT, parse_tag_fdt); __tagtable(BP_TAG_FDT, parse_tag_fdt);
void __init early_init_dt_setup_initrd_arch(unsigned long start, void __init early_init_dt_setup_initrd_arch(u64 start, u64 end)
unsigned long end)
{ {
initrd_start = (void *)__va(start); initrd_start = (void *)__va(start);
initrd_end = (void *)__va(end); initrd_end = (void *)__va(end);
......
...@@ -195,8 +195,8 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip) ...@@ -195,8 +195,8 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
return; return;
for (;; index++) { for (;; index++) {
ret = of_parse_phandle_with_args(np, "gpio-ranges", ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3,
"#gpio-range-cells", index, &pinspec); index, &pinspec);
if (ret) if (ret)
break; break;
......
...@@ -1176,65 +1176,10 @@ int of_property_count_strings(struct device_node *np, const char *propname) ...@@ -1176,65 +1176,10 @@ int of_property_count_strings(struct device_node *np, const char *propname)
} }
EXPORT_SYMBOL_GPL(of_property_count_strings); EXPORT_SYMBOL_GPL(of_property_count_strings);
/**
* of_parse_phandle - Resolve a phandle property to a device_node pointer
* @np: Pointer to device node holding phandle property
* @phandle_name: Name of property holding a phandle value
* @index: For properties holding a table of phandles, this is the index into
* the table
*
* Returns the device_node pointer with refcount incremented. Use
* of_node_put() on it when done.
*/
struct device_node *of_parse_phandle(const struct device_node *np,
const char *phandle_name, int index)
{
const __be32 *phandle;
int size;
phandle = of_get_property(np, phandle_name, &size);
if ((!phandle) || (size < sizeof(*phandle) * (index + 1)))
return NULL;
return of_find_node_by_phandle(be32_to_cpup(phandle + index));
}
EXPORT_SYMBOL(of_parse_phandle);
/**
* of_parse_phandle_with_args() - Find a node pointed by phandle in a list
* @np: pointer to a device tree node containing a list
* @list_name: property name that contains a list
* @cells_name: property name that specifies phandles' arguments count
* @index: index of a phandle to parse out
* @out_args: optional pointer to output arguments structure (will be filled)
*
* This function is useful to parse lists of phandles and their arguments.
* Returns 0 on success and fills out_args, on error returns appropriate
* errno value.
*
* Caller is responsible to call of_node_put() on the returned out_args->node
* pointer.
*
* Example:
*
* phandle1: node1 {
* #list-cells = <2>;
* }
*
* phandle2: node2 {
* #list-cells = <1>;
* }
*
* node3 {
* list = <&phandle1 1 2 &phandle2 3>;
* }
*
* To get a device_node of the `node2' node you may call this:
* of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
*/
static int __of_parse_phandle_with_args(const struct device_node *np, static int __of_parse_phandle_with_args(const struct device_node *np,
const char *list_name, const char *list_name,
const char *cells_name, int index, const char *cells_name,
int cell_count, int index,
struct of_phandle_args *out_args) struct of_phandle_args *out_args)
{ {
const __be32 *list, *list_end; const __be32 *list, *list_end;
...@@ -1262,19 +1207,32 @@ static int __of_parse_phandle_with_args(const struct device_node *np, ...@@ -1262,19 +1207,32 @@ static int __of_parse_phandle_with_args(const struct device_node *np,
if (phandle) { if (phandle) {
/* /*
* Find the provider node and parse the #*-cells * Find the provider node and parse the #*-cells
* property to determine the argument length * property to determine the argument length.
*
* This is not needed if the cell count is hard-coded
* (i.e. cells_name not set, but cell_count is set),
* except when we're going to return the found node
* below.
*/ */
node = of_find_node_by_phandle(phandle); if (cells_name || cur_index == index) {
if (!node) { node = of_find_node_by_phandle(phandle);
pr_err("%s: could not find phandle\n", if (!node) {
np->full_name); pr_err("%s: could not find phandle\n",
goto err; np->full_name);
goto err;
}
} }
if (of_property_read_u32(node, cells_name, &count)) {
pr_err("%s: could not get %s for %s\n", if (cells_name) {
np->full_name, cells_name, if (of_property_read_u32(node, cells_name,
node->full_name); &count)) {
goto err; pr_err("%s: could not get %s for %s\n",
np->full_name, cells_name,
node->full_name);
goto err;
}
} else {
count = cell_count;
} }
/* /*
...@@ -1334,16 +1292,116 @@ static int __of_parse_phandle_with_args(const struct device_node *np, ...@@ -1334,16 +1292,116 @@ static int __of_parse_phandle_with_args(const struct device_node *np,
return rc; return rc;
} }
/**
* of_parse_phandle - Resolve a phandle property to a device_node pointer
* @np: Pointer to device node holding phandle property
* @phandle_name: Name of property holding a phandle value
* @index: For properties holding a table of phandles, this is the index into
* the table
*
* Returns the device_node pointer with refcount incremented. Use
* of_node_put() on it when done.
*/
struct device_node *of_parse_phandle(const struct device_node *np,
const char *phandle_name, int index)
{
struct of_phandle_args args;
if (index < 0)
return NULL;
if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0,
index, &args))
return NULL;
return args.np;
}
EXPORT_SYMBOL(of_parse_phandle);
/**
* of_parse_phandle_with_args() - Find a node pointed by phandle in a list
* @np: pointer to a device tree node containing a list
* @list_name: property name that contains a list
* @cells_name: property name that specifies phandles' arguments count
* @index: index of a phandle to parse out
* @out_args: optional pointer to output arguments structure (will be filled)
*
* This function is useful to parse lists of phandles and their arguments.
* Returns 0 on success and fills out_args, on error returns appropriate
* errno value.
*
* Caller is responsible to call of_node_put() on the returned out_args->node
* pointer.
*
* Example:
*
* phandle1: node1 {
* #list-cells = <2>;
* }
*
* phandle2: node2 {
* #list-cells = <1>;
* }
*
* node3 {
* list = <&phandle1 1 2 &phandle2 3>;
* }
*
* To get a device_node of the `node2' node you may call this:
* of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
*/
int of_parse_phandle_with_args(const struct device_node *np, const char *list_name, int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
const char *cells_name, int index, const char *cells_name, int index,
struct of_phandle_args *out_args) struct of_phandle_args *out_args)
{ {
if (index < 0) if (index < 0)
return -EINVAL; return -EINVAL;
return __of_parse_phandle_with_args(np, list_name, cells_name, index, out_args); return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
index, out_args);
} }
EXPORT_SYMBOL(of_parse_phandle_with_args); EXPORT_SYMBOL(of_parse_phandle_with_args);
/**
* of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list
* @np: pointer to a device tree node containing a list
* @list_name: property name that contains a list
* @cell_count: number of argument cells following the phandle
* @index: index of a phandle to parse out
* @out_args: optional pointer to output arguments structure (will be filled)
*
* This function is useful to parse lists of phandles and their arguments.
* Returns 0 on success and fills out_args, on error returns appropriate
* errno value.
*
* Caller is responsible to call of_node_put() on the returned out_args->node
* pointer.
*
* Example:
*
* phandle1: node1 {
* }
*
* phandle2: node2 {
* }
*
* node3 {
* list = <&phandle1 0 2 &phandle2 2 3>;
* }
*
* To get a device_node of the `node2' node you may call this:
* of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args);
*/
int of_parse_phandle_with_fixed_args(const struct device_node *np,
const char *list_name, int cell_count,
int index, struct of_phandle_args *out_args)
{
if (index < 0)
return -EINVAL;
return __of_parse_phandle_with_args(np, list_name, NULL, cell_count,
index, out_args);
}
EXPORT_SYMBOL(of_parse_phandle_with_fixed_args);
/** /**
* of_count_phandle_with_args() - Find the number of phandles references in a property * of_count_phandle_with_args() - Find the number of phandles references in a property
* @np: pointer to a device tree node containing a list * @np: pointer to a device tree node containing a list
...@@ -1362,7 +1420,8 @@ EXPORT_SYMBOL(of_parse_phandle_with_args); ...@@ -1362,7 +1420,8 @@ EXPORT_SYMBOL(of_parse_phandle_with_args);
int of_count_phandle_with_args(const struct device_node *np, const char *list_name, int of_count_phandle_with_args(const struct device_node *np, const char *list_name,
const char *cells_name) const char *cells_name)
{ {
return __of_parse_phandle_with_args(np, list_name, cells_name, -1, NULL); return __of_parse_phandle_with_args(np, list_name, cells_name, 0, -1,
NULL);
} }
EXPORT_SYMBOL(of_count_phandle_with_args); EXPORT_SYMBOL(of_count_phandle_with_args);
...@@ -1734,6 +1793,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)) ...@@ -1734,6 +1793,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
ap = dt_alloc(sizeof(*ap) + len + 1, 4); ap = dt_alloc(sizeof(*ap) + len + 1, 4);
if (!ap) if (!ap)
continue; continue;
memset(ap, 0, sizeof(*ap) + len + 1);
ap->alias = start; ap->alias = start;
of_alias_add(ap, np, id, start, len); of_alias_add(ap, np, id, start, len);
} }
......
...@@ -11,12 +11,14 @@ ...@@ -11,12 +11,14 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/initrd.h> #include <linux/initrd.h>
#include <linux/memblock.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_fdt.h> #include <linux/of_fdt.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/random.h>
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */ #include <asm/setup.h> /* for COMMAND_LINE_SIZE */
#ifdef CONFIG_PPC #ifdef CONFIG_PPC
...@@ -125,13 +127,13 @@ int of_fdt_match(struct boot_param_header *blob, unsigned long node, ...@@ -125,13 +127,13 @@ int of_fdt_match(struct boot_param_header *blob, unsigned long node,
return score; return score;
} }
static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size, static void *unflatten_dt_alloc(void **mem, unsigned long size,
unsigned long align) unsigned long align)
{ {
void *res; void *res;
*mem = ALIGN(*mem, align); *mem = PTR_ALIGN(*mem, align);
res = (void *)*mem; res = *mem;
*mem += size; *mem += size;
return res; return res;
...@@ -146,9 +148,9 @@ static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size, ...@@ -146,9 +148,9 @@ static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size,
* @allnextpp: pointer to ->allnext from last allocated device_node * @allnextpp: pointer to ->allnext from last allocated device_node
* @fpsize: Size of the node path up at the current depth. * @fpsize: Size of the node path up at the current depth.
*/ */
static unsigned long unflatten_dt_node(struct boot_param_header *blob, static void * unflatten_dt_node(struct boot_param_header *blob,
unsigned long mem, void *mem,
unsigned long *p, void **p,
struct device_node *dad, struct device_node *dad,
struct device_node ***allnextpp, struct device_node ***allnextpp,
unsigned long fpsize) unsigned long fpsize)
...@@ -161,15 +163,15 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob, ...@@ -161,15 +163,15 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
int has_name = 0; int has_name = 0;
int new_format = 0; int new_format = 0;
tag = be32_to_cpup((__be32 *)(*p)); tag = be32_to_cpup(*p);
if (tag != OF_DT_BEGIN_NODE) { if (tag != OF_DT_BEGIN_NODE) {
pr_err("Weird tag at start of node: %x\n", tag); pr_err("Weird tag at start of node: %x\n", tag);
return mem; return mem;
} }
*p += 4; *p += 4;
pathp = (char *)*p; pathp = *p;
l = allocl = strlen(pathp) + 1; l = allocl = strlen(pathp) + 1;
*p = ALIGN(*p + l, 4); *p = PTR_ALIGN(*p + l, 4);
/* version 0x10 has a more compact unit name here instead of the full /* version 0x10 has a more compact unit name here instead of the full
* path. we accumulate the full path size using "fpsize", we'll rebuild * path. we accumulate the full path size using "fpsize", we'll rebuild
...@@ -201,7 +203,6 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob, ...@@ -201,7 +203,6 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
__alignof__(struct device_node)); __alignof__(struct device_node));
if (allnextpp) { if (allnextpp) {
char *fn; char *fn;
memset(np, 0, sizeof(*np));
np->full_name = fn = ((char *)np) + sizeof(*np); np->full_name = fn = ((char *)np) + sizeof(*np);
if (new_format) { if (new_format) {
/* rebuild full path for new format */ /* rebuild full path for new format */
...@@ -239,7 +240,7 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob, ...@@ -239,7 +240,7 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
u32 sz, noff; u32 sz, noff;
char *pname; char *pname;
tag = be32_to_cpup((__be32 *)(*p)); tag = be32_to_cpup(*p);
if (tag == OF_DT_NOP) { if (tag == OF_DT_NOP) {
*p += 4; *p += 4;
continue; continue;
...@@ -247,11 +248,11 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob, ...@@ -247,11 +248,11 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
if (tag != OF_DT_PROP) if (tag != OF_DT_PROP)
break; break;
*p += 4; *p += 4;
sz = be32_to_cpup((__be32 *)(*p)); sz = be32_to_cpup(*p);
noff = be32_to_cpup((__be32 *)((*p) + 4)); noff = be32_to_cpup(*p + 4);
*p += 8; *p += 8;
if (be32_to_cpu(blob->version) < 0x10) if (be32_to_cpu(blob->version) < 0x10)
*p = ALIGN(*p, sz >= 8 ? 8 : 4); *p = PTR_ALIGN(*p, sz >= 8 ? 8 : 4);
pname = of_fdt_get_string(blob, noff); pname = of_fdt_get_string(blob, noff);
if (pname == NULL) { if (pname == NULL) {
...@@ -281,11 +282,11 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob, ...@@ -281,11 +282,11 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
np->phandle = be32_to_cpup((__be32 *)*p); np->phandle = be32_to_cpup((__be32 *)*p);
pp->name = pname; pp->name = pname;
pp->length = sz; pp->length = sz;
pp->value = (void *)*p; pp->value = *p;
*prev_pp = pp; *prev_pp = pp;
prev_pp = &pp->next; prev_pp = &pp->next;
} }
*p = ALIGN((*p) + sz, 4); *p = PTR_ALIGN((*p) + sz, 4);
} }
/* with version 0x10 we may not have the name property, recreate /* with version 0x10 we may not have the name property, recreate
* it here from the unit name if absent * it here from the unit name if absent
...@@ -334,7 +335,7 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob, ...@@ -334,7 +335,7 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob,
else else
mem = unflatten_dt_node(blob, mem, p, np, allnextpp, mem = unflatten_dt_node(blob, mem, p, np, allnextpp,
fpsize); fpsize);
tag = be32_to_cpup((__be32 *)(*p)); tag = be32_to_cpup(*p);
} }
if (tag != OF_DT_END_NODE) { if (tag != OF_DT_END_NODE) {
pr_err("Weird tag at end of node: %x\n", tag); pr_err("Weird tag at end of node: %x\n", tag);
...@@ -360,7 +361,8 @@ static void __unflatten_device_tree(struct boot_param_header *blob, ...@@ -360,7 +361,8 @@ static void __unflatten_device_tree(struct boot_param_header *blob,
struct device_node **mynodes, struct device_node **mynodes,
void * (*dt_alloc)(u64 size, u64 align)) void * (*dt_alloc)(u64 size, u64 align))
{ {
unsigned long start, mem, size; unsigned long size;
void *start, *mem;
struct device_node **allnextp = mynodes; struct device_node **allnextp = mynodes;
pr_debug(" -> unflatten_device_tree()\n"); pr_debug(" -> unflatten_device_tree()\n");
...@@ -381,32 +383,28 @@ static void __unflatten_device_tree(struct boot_param_header *blob, ...@@ -381,32 +383,28 @@ static void __unflatten_device_tree(struct boot_param_header *blob,
} }
/* First pass, scan for size */ /* First pass, scan for size */
start = ((unsigned long)blob) + start = ((void *)blob) + be32_to_cpu(blob->off_dt_struct);
be32_to_cpu(blob->off_dt_struct); size = (unsigned long)unflatten_dt_node(blob, 0, &start, NULL, NULL, 0);
size = unflatten_dt_node(blob, 0, &start, NULL, NULL, 0); size = ALIGN(size, 4);
size = (size | 3) + 1;
pr_debug(" size is %lx, allocating...\n", size); pr_debug(" size is %lx, allocating...\n", size);
/* Allocate memory for the expanded device tree */ /* Allocate memory for the expanded device tree */
mem = (unsigned long) mem = dt_alloc(size + 4, __alignof__(struct device_node));
dt_alloc(size + 4, __alignof__(struct device_node)); memset(mem, 0, size);
memset((void *)mem, 0, size); *(__be32 *)(mem + size) = cpu_to_be32(0xdeadbeef);
((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef); pr_debug(" unflattening %p...\n", mem);
pr_debug(" unflattening %lx...\n", mem);
/* Second pass, do actual unflattening */ /* Second pass, do actual unflattening */
start = ((unsigned long)blob) + start = ((void *)blob) + be32_to_cpu(blob->off_dt_struct);
be32_to_cpu(blob->off_dt_struct);
unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0); unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0);
if (be32_to_cpup((__be32 *)start) != OF_DT_END) if (be32_to_cpup(start) != OF_DT_END)
pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); pr_warning("Weird tag at end of tree: %08x\n", be32_to_cpup(start));
if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef) if (be32_to_cpup(mem + size) != 0xdeadbeef)
pr_warning("End of tree marker overwritten: %08x\n", pr_warning("End of tree marker overwritten: %08x\n",
be32_to_cpu(((__be32 *)mem)[size / 4])); be32_to_cpup(mem + size));
*allnextp = NULL; *allnextp = NULL;
pr_debug(" <- unflatten_device_tree()\n"); pr_debug(" <- unflatten_device_tree()\n");
...@@ -628,7 +626,8 @@ int __init of_scan_flat_dt_by_path(const char *path, ...@@ -628,7 +626,8 @@ int __init of_scan_flat_dt_by_path(const char *path,
*/ */
void __init early_init_dt_check_for_initrd(unsigned long node) void __init early_init_dt_check_for_initrd(unsigned long node)
{ {
unsigned long start, end, len; u64 start, end;
unsigned long len;
__be32 *prop; __be32 *prop;
pr_debug("Looking for initrd properties... "); pr_debug("Looking for initrd properties... ");
...@@ -636,15 +635,16 @@ void __init early_init_dt_check_for_initrd(unsigned long node) ...@@ -636,15 +635,16 @@ void __init early_init_dt_check_for_initrd(unsigned long node)
prop = of_get_flat_dt_prop(node, "linux,initrd-start", &len); prop = of_get_flat_dt_prop(node, "linux,initrd-start", &len);
if (!prop) if (!prop)
return; return;
start = of_read_ulong(prop, len/4); start = of_read_number(prop, len/4);
prop = of_get_flat_dt_prop(node, "linux,initrd-end", &len); prop = of_get_flat_dt_prop(node, "linux,initrd-end", &len);
if (!prop) if (!prop)
return; return;
end = of_read_ulong(prop, len/4); end = of_read_number(prop, len/4);
early_init_dt_setup_initrd_arch(start, end); early_init_dt_setup_initrd_arch(start, end);
pr_debug("initrd_start=0x%lx initrd_end=0x%lx\n", start, end); pr_debug("initrd_start=0x%llx initrd_end=0x%llx\n",
(unsigned long long)start, (unsigned long long)end);
} }
#else #else
inline void early_init_dt_check_for_initrd(unsigned long node) inline void early_init_dt_check_for_initrd(unsigned long node)
...@@ -774,6 +774,17 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, ...@@ -774,6 +774,17 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
return 1; return 1;
} }
#ifdef CONFIG_HAVE_MEMBLOCK
/*
* called from unflatten_device_tree() to bootstrap devicetree itself
* Architectures can override this definition if memblock isn't used
*/
void * __init __weak early_init_dt_alloc_memory_arch(u64 size, u64 align)
{
return __va(memblock_alloc(size, align));
}
#endif
/** /**
* unflatten_device_tree - create tree of device_nodes from flat blob * unflatten_device_tree - create tree of device_nodes from flat blob
* *
...@@ -792,3 +803,14 @@ void __init unflatten_device_tree(void) ...@@ -792,3 +803,14 @@ void __init unflatten_device_tree(void)
} }
#endif /* CONFIG_OF_EARLY_FLATTREE */ #endif /* CONFIG_OF_EARLY_FLATTREE */
/* Feed entire flattened device tree into the random pool */
static int __init add_fdt_randomness(void)
{
if (initial_boot_params)
add_device_randomness(initial_boot_params,
be32_to_cpu(initial_boot_params->totalsize));
return 0;
}
core_initcall(add_fdt_randomness);
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
/** /**
* irq_of_parse_and_map - Parse and map an interrupt into linux virq space * irq_of_parse_and_map - Parse and map an interrupt into linux virq space
* @device: Device node of the device whose interrupt is to be mapped * @dev: Device node of the device whose interrupt is to be mapped
* @index: Index of the interrupt to map * @index: Index of the interrupt to map
* *
* This function is a wrapper that chains of_irq_map_one() and * This function is a wrapper that chains of_irq_map_one() and
......
...@@ -39,7 +39,7 @@ static const char *phy_modes[] = { ...@@ -39,7 +39,7 @@ static const char *phy_modes[] = {
* The function gets phy interface string from property 'phy-mode', * The function gets phy interface string from property 'phy-mode',
* and return its index in phy_modes table, or errno in error case. * and return its index in phy_modes table, or errno in error case.
*/ */
const int of_get_phy_mode(struct device_node *np) int of_get_phy_mode(struct device_node *np)
{ {
const char *pm; const char *pm;
int err, i; int err, i;
......
...@@ -197,7 +197,7 @@ EXPORT_SYMBOL(of_device_alloc); ...@@ -197,7 +197,7 @@ EXPORT_SYMBOL(of_device_alloc);
* Returns pointer to created platform device, or NULL if a device was not * Returns pointer to created platform device, or NULL if a device was not
* registered. Unavailable devices will not get registered. * registered. Unavailable devices will not get registered.
*/ */
struct platform_device *of_platform_device_create_pdata( static struct platform_device *of_platform_device_create_pdata(
struct device_node *np, struct device_node *np,
const char *bus_id, const char *bus_id,
void *platform_data, void *platform_data,
...@@ -268,8 +268,11 @@ static struct amba_device *of_amba_device_create(struct device_node *node, ...@@ -268,8 +268,11 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
return NULL; return NULL;
dev = amba_device_alloc(NULL, 0, 0); dev = amba_device_alloc(NULL, 0, 0);
if (!dev) if (!dev) {
pr_err("%s(): amba_device_alloc() failed for %s\n",
__func__, node->full_name);
return NULL; return NULL;
}
/* setup generic device info */ /* setup generic device info */
dev->dev.coherent_dma_mask = ~0; dev->dev.coherent_dma_mask = ~0;
...@@ -294,12 +297,18 @@ static struct amba_device *of_amba_device_create(struct device_node *node, ...@@ -294,12 +297,18 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
dev->irq[i] = irq_of_parse_and_map(node, i); dev->irq[i] = irq_of_parse_and_map(node, i);
ret = of_address_to_resource(node, 0, &dev->res); ret = of_address_to_resource(node, 0, &dev->res);
if (ret) if (ret) {
pr_err("%s(): of_address_to_resource() failed (%d) for %s\n",
__func__, ret, node->full_name);
goto err_free; goto err_free;
}
ret = amba_device_add(dev, &iomem_resource); ret = amba_device_add(dev, &iomem_resource);
if (ret) if (ret) {
pr_err("%s(): amba_device_add() failed (%d) for %s\n",
__func__, ret, node->full_name);
goto err_free; goto err_free;
}
return dev; return dev;
...@@ -378,6 +387,10 @@ static int of_platform_bus_create(struct device_node *bus, ...@@ -378,6 +387,10 @@ static int of_platform_bus_create(struct device_node *bus,
} }
if (of_device_is_compatible(bus, "arm,primecell")) { if (of_device_is_compatible(bus, "arm,primecell")) {
/*
* Don't return an error here to keep compatibility with older
* device tree files.
*/
of_amba_device_create(bus, bus_id, platform_data, parent); of_amba_device_create(bus, bus_id, platform_data, parent);
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -281,6 +281,9 @@ extern struct device_node *of_parse_phandle(const struct device_node *np, ...@@ -281,6 +281,9 @@ extern struct device_node *of_parse_phandle(const struct device_node *np,
extern int of_parse_phandle_with_args(const struct device_node *np, extern int of_parse_phandle_with_args(const struct device_node *np,
const char *list_name, const char *cells_name, int index, const char *list_name, const char *cells_name, int index,
struct of_phandle_args *out_args); struct of_phandle_args *out_args);
extern int of_parse_phandle_with_fixed_args(const struct device_node *np,
const char *list_name, int cells_count, int index,
struct of_phandle_args *out_args);
extern int of_count_phandle_with_args(const struct device_node *np, extern int of_count_phandle_with_args(const struct device_node *np,
const char *list_name, const char *cells_name); const char *list_name, const char *cells_name);
...@@ -324,12 +327,6 @@ extern int of_detach_node(struct device_node *); ...@@ -324,12 +327,6 @@ extern int of_detach_node(struct device_node *);
*/ */
const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
u32 *pu); u32 *pu);
#define of_property_for_each_u32(np, propname, prop, p, u) \
for (prop = of_find_property(np, propname, NULL), \
p = of_prop_next_u32(prop, NULL, &u); \
p; \
p = of_prop_next_u32(prop, p, &u))
/* /*
* struct property *prop; * struct property *prop;
* const char *s; * const char *s;
...@@ -338,11 +335,6 @@ const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, ...@@ -338,11 +335,6 @@ const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
* printk("String value: %s\n", s); * printk("String value: %s\n", s);
*/ */
const char *of_prop_next_string(struct property *prop, const char *cur); const char *of_prop_next_string(struct property *prop, const char *cur);
#define of_property_for_each_string(np, propname, prop, s) \
for (prop = of_find_property(np, propname, NULL), \
s = of_prop_next_string(prop, NULL); \
s; \
s = of_prop_next_string(prop, s))
int of_device_is_stdout_path(struct device_node *dn); int of_device_is_stdout_path(struct device_node *dn);
...@@ -497,6 +489,13 @@ static inline int of_parse_phandle_with_args(struct device_node *np, ...@@ -497,6 +489,13 @@ static inline int of_parse_phandle_with_args(struct device_node *np,
return -ENOSYS; return -ENOSYS;
} }
static inline int of_parse_phandle_with_fixed_args(const struct device_node *np,
const char *list_name, int cells_count, int index,
struct of_phandle_args *out_args)
{
return -ENOSYS;
}
static inline int of_count_phandle_with_args(struct device_node *np, static inline int of_count_phandle_with_args(struct device_node *np,
const char *list_name, const char *list_name,
const char *cells_name) const char *cells_name)
...@@ -519,12 +518,20 @@ static inline int of_device_is_stdout_path(struct device_node *dn) ...@@ -519,12 +518,20 @@ static inline int of_device_is_stdout_path(struct device_node *dn)
return 0; return 0;
} }
static inline const __be32 *of_prop_next_u32(struct property *prop,
const __be32 *cur, u32 *pu)
{
return NULL;
}
static inline const char *of_prop_next_string(struct property *prop,
const char *cur)
{
return NULL;
}
#define of_match_ptr(_ptr) NULL #define of_match_ptr(_ptr) NULL
#define of_match_node(_matches, _node) NULL #define of_match_node(_matches, _node) NULL
#define of_property_for_each_u32(np, propname, prop, p, u) \
while (0)
#define of_property_for_each_string(np, propname, prop, s) \
while (0)
#endif /* CONFIG_OF */ #endif /* CONFIG_OF */
#ifndef of_node_to_nid #ifndef of_node_to_nid
...@@ -573,6 +580,18 @@ static inline int of_property_read_u32(const struct device_node *np, ...@@ -573,6 +580,18 @@ static inline int of_property_read_u32(const struct device_node *np,
return of_property_read_u32_array(np, propname, out_value, 1); return of_property_read_u32_array(np, propname, out_value, 1);
} }
#define of_property_for_each_u32(np, propname, prop, p, u) \
for (prop = of_find_property(np, propname, NULL), \
p = of_prop_next_u32(prop, NULL, &u); \
p; \
p = of_prop_next_u32(prop, p, &u))
#define of_property_for_each_string(np, propname, prop, s) \
for (prop = of_find_property(np, propname, NULL), \
s = of_prop_next_string(prop, NULL); \
s; \
s = of_prop_next_string(prop, s))
#if defined(CONFIG_PROC_FS) && defined(CONFIG_PROC_DEVICETREE) #if defined(CONFIG_PROC_FS) && defined(CONFIG_PROC_DEVICETREE)
extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *); extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *);
extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop); extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop);
......
...@@ -109,8 +109,7 @@ extern u64 dt_mem_next_cell(int s, __be32 **cellp); ...@@ -109,8 +109,7 @@ extern u64 dt_mem_next_cell(int s, __be32 **cellp);
* physical addresses. * physical addresses.
*/ */
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
extern void early_init_dt_setup_initrd_arch(unsigned long start, extern void early_init_dt_setup_initrd_arch(u64 start, u64 end);
unsigned long end);
#endif #endif
/* Early flat tree scan hooks */ /* Early flat tree scan hooks */
......
...@@ -9,10 +9,10 @@ ...@@ -9,10 +9,10 @@
#ifdef CONFIG_OF_NET #ifdef CONFIG_OF_NET
#include <linux/of.h> #include <linux/of.h>
extern const int of_get_phy_mode(struct device_node *np); extern int of_get_phy_mode(struct device_node *np);
extern const void *of_get_mac_address(struct device_node *np); extern const void *of_get_mac_address(struct device_node *np);
#else #else
static inline const int of_get_phy_mode(struct device_node *np) static inline int of_get_phy_mode(struct device_node *np)
{ {
return -ENODEV; return -ENODEV;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment