diff options
author | Laurentiu TUDOR <Laurentiu.Tudor@freescale.com> | 2013-07-03 17:13:15 +0300 |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2013-08-07 18:38:06 -0500 |
commit | 4e21b94c9c644c43223878f4c848e852743e789c (patch) | |
tree | 70671b6571cb5c92752264d26a174cbc0d9034b8 /arch/powerpc/kernel/epapr_paravirt.c | |
parent | f31dd9443afd35696a833c2a32d584a9257abd40 (diff) |
powerpc/85xx: Move ePAPR paravirt initialization earlier
At console init, when the kernel tries to flush the log buffer
the ePAPR byte-channel based console write fails silently,
losing the buffered messages.
This happens because The ePAPR para-virtualization init isn't
done early enough so that the hcall instruction to be set,
causing the byte-channel write hcall to be a nop.
To fix, change the ePAPR para-virt init to use early device
tree functions and move it in early init.
Signed-off-by: Laurentiu Tudor <Laurentiu.Tudor@freescale.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'arch/powerpc/kernel/epapr_paravirt.c')
-rw-r--r-- | arch/powerpc/kernel/epapr_paravirt.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/arch/powerpc/kernel/epapr_paravirt.c b/arch/powerpc/kernel/epapr_paravirt.c index d44a571e45a7..6300c13bbde4 100644 --- a/arch/powerpc/kernel/epapr_paravirt.c +++ b/arch/powerpc/kernel/epapr_paravirt.c @@ -30,22 +30,20 @@ extern u32 epapr_ev_idle_start[]; bool epapr_paravirt_enabled; -static int __init epapr_paravirt_init(void) +static int __init early_init_dt_scan_epapr(unsigned long node, + const char *uname, + int depth, void *data) { - struct device_node *hyper_node; const u32 *insts; - int len, i; + unsigned long len; + int i; - hyper_node = of_find_node_by_path("/hypervisor"); - if (!hyper_node) - return -ENODEV; - - insts = of_get_property(hyper_node, "hcall-instructions", &len); + insts = of_get_flat_dt_prop(node, "hcall-instructions", &len); if (!insts) - return -ENODEV; + return 0; if (len % 4 || len > (4 * 4)) - return -ENODEV; + return -1; for (i = 0; i < (len / 4); i++) { patch_instruction(epapr_hypercall_start + i, insts[i]); @@ -55,13 +53,19 @@ static int __init epapr_paravirt_init(void) } #if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64) - if (of_get_property(hyper_node, "has-idle", NULL)) + if (of_get_flat_dt_prop(node, "has-idle", NULL)) ppc_md.power_save = epapr_ev_idle; #endif epapr_paravirt_enabled = true; + return 1; +} + +int __init epapr_paravirt_early_init(void) +{ + of_scan_flat_dt(early_init_dt_scan_epapr, NULL); + return 0; } -early_initcall(epapr_paravirt_init); |