linux/arch/mips/lantiq/prom.c
Jonas Gorski 15f37e1588 MIPS: store the appended dtb address in a variable
Instead of rewriting the arguments to match the UHI spec, store the
address of a appended or UHI supplied dtb in fw_supplied_dtb.

That way the original bootloader arugments are kept intact while still
making the use of an appended dtb invisible for mach code.

Mach code can still find out if it is an appended dtb by comparing
fw_arg1 with fw_supplied_dtb.

Signed-off-by: Jonas Gorski <jogo@openwrt.org>
Cc: Kevin Cernekee <cernekee@gmail.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: John Crispin <john@phrozen.org>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: Alban Bedel <albeu@free.fr>
Cc: Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>
Cc: Antony Pavlov <antonynpavlov@gmail.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/13699/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2016-08-02 14:00:16 +02:00

118 lines
2.5 KiB
C

/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Copyright (C) 2010 John Crispin <john@phrozen.org>
*/
#include <linux/export.h>
#include <linux/clk.h>
#include <linux/bootmem.h>
#include <linux/of_platform.h>
#include <linux/of_fdt.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
#include <asm/prom.h>
#include <lantiq.h>
#include "prom.h"
#include "clk.h"
/* access to the ebu needs to be locked between different drivers */
DEFINE_SPINLOCK(ebu_lock);
EXPORT_SYMBOL_GPL(ebu_lock);
/*
* this struct is filled by the soc specific detection code and holds
* information about the specific soc type, revision and name
*/
static struct ltq_soc_info soc_info;
const char *get_system_type(void)
{
return soc_info.sys_type;
}
int ltq_soc_type(void)
{
return soc_info.type;
}
void __init prom_free_prom_memory(void)
{
}
static void __init prom_init_cmdline(void)
{
int argc = fw_arg0;
char **argv = (char **) KSEG1ADDR(fw_arg1);
int i;
arcs_cmdline[0] = '\0';
for (i = 0; i < argc; i++) {
char *p = (char *) KSEG1ADDR(argv[i]);
if (CPHYSADDR(p) && *p) {
strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
}
}
}
void __init plat_mem_setup(void)
{
void *dtb;
ioport_resource.start = IOPORT_RESOURCE_START;
ioport_resource.end = IOPORT_RESOURCE_END;
iomem_resource.start = IOMEM_RESOURCE_START;
iomem_resource.end = IOMEM_RESOURCE_END;
set_io_port_base((unsigned long) KSEG1);
if (fw_passed_dtb) /* UHI interface */
dtb = (void *)fw_passed_dtb;
else if (__dtb_start != __dtb_end)
dtb = (void *)__dtb_start;
else
panic("no dtb found");
/*
* Load the devicetree. This causes the chosen node to be
* parsed resulting in our memory appearing
*/
__dt_setup_arch(dtb);
}
void __init device_tree_init(void)
{
unflatten_and_copy_device_tree();
}
void __init prom_init(void)
{
/* call the soc specific detetcion code and get it to fill soc_info */
ltq_soc_detect(&soc_info);
snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev %s",
soc_info.name, soc_info.rev_type);
soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
pr_info("SoC: %s\n", soc_info.sys_type);
prom_init_cmdline();
#if defined(CONFIG_MIPS_MT_SMP)
if (register_vsmp_smp_ops())
panic("failed to register_vsmp_smp_ops()");
#endif
}
int __init plat_of_setup(void)
{
return __dt_register_buses(soc_info.compatible, "simple-bus");
}
arch_initcall(plat_of_setup);