u-boot/arch/arm/cpu/armv7/virt-dt.c
Tom Rini dd09f7e73c ARM: PSCI: Rework the DT handler slightly
The way the PSCI DT update happens currently means we pull in
<asm/armv7.h> everywhere, including on ARMv8 and that in turn brings in
<asm/io.h> for some non-PSCI related things that header needs to deal
with.

To fix this, we rework the hook slightly.  A good portion of
arch/arm/cpu/armv7/virt-dt.c is common looking and I hope that when PSCI
is needed on ARMv8 we can re-use this by and large.  So rename the
current hook to psci_update_dt(), move the prototype to <asm/psci.h> and
add an #ifdef that will make re-use later easier.

Reported-by: York Sun <yorksun@freescale.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: York Sun <yorksun@freescale.com>
Cc: Ian Campbell <ijc@hellion.org.uk>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Albert ARIBAUD <albert.u.boot@aribaud.net>
Signed-off-by: Tom Rini <trini@konsulko.com>
Acked-by: York Sun <yorksun@freescale.com>
2015-03-09 11:13:29 -04:00

104 lines
2.6 KiB
C

/*
* Copyright (C) 2013 - ARM Ltd
* Author: Marc Zyngier <marc.zyngier@arm.com>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <common.h>
#include <stdio_dev.h>
#include <linux/ctype.h>
#include <linux/types.h>
#include <asm/global_data.h>
#include <libfdt.h>
#include <fdt_support.h>
#include <asm/armv7.h>
#include <asm/psci.h>
static int fdt_psci(void *fdt)
{
#ifdef CONFIG_ARMV7_PSCI
int nodeoff;
int tmp;
nodeoff = fdt_path_offset(fdt, "/cpus");
if (nodeoff < 0) {
printf("couldn't find /cpus\n");
return nodeoff;
}
/* add 'enable-method = "psci"' to each cpu node */
for (tmp = fdt_first_subnode(fdt, nodeoff);
tmp >= 0;
tmp = fdt_next_subnode(fdt, tmp)) {
const struct fdt_property *prop;
int len;
prop = fdt_get_property(fdt, tmp, "device_type", &len);
if (!prop)
continue;
if (len < 4)
continue;
if (strcmp(prop->data, "cpu"))
continue;
fdt_setprop_string(fdt, tmp, "enable-method", "psci");
}
nodeoff = fdt_path_offset(fdt, "/psci");
if (nodeoff < 0) {
nodeoff = fdt_path_offset(fdt, "/");
if (nodeoff < 0)
return nodeoff;
nodeoff = fdt_add_subnode(fdt, nodeoff, "psci");
if (nodeoff < 0)
return nodeoff;
}
tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci");
if (tmp)
return tmp;
tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc");
if (tmp)
return tmp;
tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", ARM_PSCI_FN_CPU_SUSPEND);
if (tmp)
return tmp;
tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", ARM_PSCI_FN_CPU_OFF);
if (tmp)
return tmp;
tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", ARM_PSCI_FN_CPU_ON);
if (tmp)
return tmp;
tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", ARM_PSCI_FN_MIGRATE);
if (tmp)
return tmp;
#endif
return 0;
}
int psci_update_dt(void *fdt)
{
#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT)
if (!armv7_boot_nonsec())
return 0;
#endif
#ifndef CONFIG_ARMV7_SECURE_BASE
/* secure code lives in RAM, keep it alive */
fdt_add_mem_rsv(fdt, (unsigned long)__secure_start,
__secure_end - __secure_start);
#endif
return fdt_psci(fdt);
}