diff options
author | Baruch Siach <baruch@tkos.co.il> | 2013-12-29 13:03:30 +0400 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2014-01-15 00:25:14 +0400 |
commit | 6cb971114f633a0bf240c20b681d989b45e3ec56 (patch) | |
tree | 15d3280cf733e2bda26252e1c01b53943b47bd68 /arch/xtensa/kernel/setup.c | |
parent | f8935f307fe46faa1a829a6b76ee95ca9ba67d20 (diff) | |
download | linux-6cb971114f633a0bf240c20b681d989b45e3ec56.tar.xz |
xtensa: remap io area defined in device tree
Use the simple-bus node to discover the io area, and remap the cached and
bypass io ranges. The parent-bus-address value of the first triplet in the
"ranges" property is used. This value is rounded down to the nearest 256MB
boundary. The length of the io area is fixed at 256MB; the "ranges" property
length value is ignored.
Other limitations: (1) only the first simple-bus node is considered, and (2)
only the first triplet of the "ranges" property is considered.
See ePAPR 1.1 §6.5 for the simple-bus node description, and §2.3.8 for the
"ranges" property description.
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'arch/xtensa/kernel/setup.c')
-rw-r--r-- | arch/xtensa/kernel/setup.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index f38badeb7747..7d12af1317f1 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -212,6 +212,42 @@ 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; + unsigned long 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) { if (!dt_memory_scan) @@ -232,6 +268,7 @@ void __init early_init_devtree(void *params) dt_memory_scan = true; early_init_dt_scan(params); + of_scan_flat_dt(xtensa_dt_io_area, NULL); if (!command_line[0]) strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); |