aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/powernv/setup.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-09-19 17:45:01 +0000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-09-20 16:09:57 +1000
commit628daa8d5abfd904a7329a660c5c374212230123 (patch)
tree83981d6c9566dd6bb16c45ea43938df8ed5d350f /arch/powerpc/platforms/powernv/setup.c
parentec27329ffb3b4f619be9f0065c473fcb36ea52ce (diff)
powerpc/powernv: Add RTC and NVRAM support plus RTAS fallbacks
Implements OPAL RTC and NVRAM support and wire all that up to the powernv platform. We use RTAS for RTC as a fallback if available. Using RTAS for nvram is not supported yet, pending some rework/cleanup and generalization of the pSeries & CHRP code. We also use RTAS fallbacks for power off and reboot Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms/powernv/setup.c')
-rw-r--r--arch/powerpc/platforms/powernv/setup.c57
1 files changed, 36 insertions, 21 deletions
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index 0fac0a6c951e..4a2b2e279593 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -29,7 +29,9 @@
#include <asm/machdep.h>
#include <asm/firmware.h>
#include <asm/xics.h>
+#include <asm/rtas.h>
#include <asm/opal.h>
+#include <asm/xics.h>
#include "powernv.h"
@@ -40,7 +42,9 @@ static void __init pnv_setup_arch(void)
/* XXX PCI */
- /* XXX NVRAM */
+ /* Setup RTC and NVRAM callbacks */
+ if (firmware_has_feature(FW_FEATURE_OPAL))
+ opal_nvram_init();
/* Enable NAP mode */
powersave_nap = 1;
@@ -118,30 +122,40 @@ static void __noreturn pnv_halt(void)
pnv_power_off();
}
-static unsigned long __init pnv_get_boot_time(void)
-{
- return 0;
-}
-
-static void pnv_get_rtc_time(struct rtc_time *rtc_tm)
+static void pnv_progress(char *s, unsigned short hex)
{
}
-static int pnv_set_rtc_time(struct rtc_time *tm)
+#ifdef CONFIG_KEXEC
+static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
{
- return 0;
+ xics_kexec_teardown_cpu(secondary);
}
+#endif /* CONFIG_KEXEC */
-static void pnv_progress(char *s, unsigned short hex)
+static void __init pnv_setup_machdep_opal(void)
{
+ ppc_md.get_boot_time = opal_get_boot_time;
+ ppc_md.get_rtc_time = opal_get_rtc_time;
+ ppc_md.set_rtc_time = opal_set_rtc_time;
+ ppc_md.restart = pnv_restart;
+ ppc_md.power_off = pnv_power_off;
+ ppc_md.halt = pnv_halt;
}
-#ifdef CONFIG_KEXEC
-static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
+#ifdef CONFIG_PPC_POWERNV_RTAS
+static void __init pnv_setup_machdep_rtas(void)
{
- xics_kexec_teardown_cpu(secondary);
+ if (rtas_token("get-time-of-day") != RTAS_UNKNOWN_SERVICE) {
+ ppc_md.get_boot_time = rtas_get_boot_time;
+ ppc_md.get_rtc_time = rtas_get_rtc_time;
+ ppc_md.set_rtc_time = rtas_set_rtc_time;
+ }
+ ppc_md.restart = rtas_restart;
+ ppc_md.power_off = rtas_power_off;
+ ppc_md.halt = rtas_halt;
}
-#endif /* CONFIG_KEXEC */
+#endif /* CONFIG_PPC_POWERNV_RTAS */
static int __init pnv_probe(void)
{
@@ -152,6 +166,13 @@ static int __init pnv_probe(void)
hpte_init_native();
+ if (firmware_has_feature(FW_FEATURE_OPAL))
+ pnv_setup_machdep_opal();
+#ifdef CONFIG_PPC_POWERNV_RTAS
+ else if (rtas.base)
+ pnv_setup_machdep_rtas();
+#endif /* CONFIG_PPC_POWERNV_RTAS */
+
pr_debug("PowerNV detected !\n");
return 1;
@@ -160,16 +181,10 @@ static int __init pnv_probe(void)
define_machine(powernv) {
.name = "PowerNV",
.probe = pnv_probe,
- .setup_arch = pnv_setup_arch,
.init_early = pnv_init_early,
+ .setup_arch = pnv_setup_arch,
.init_IRQ = pnv_init_IRQ,
.show_cpuinfo = pnv_show_cpuinfo,
- .restart = pnv_restart,
- .power_off = pnv_power_off,
- .halt = pnv_halt,
- .get_boot_time = pnv_get_boot_time,
- .get_rtc_time = pnv_get_rtc_time,
- .set_rtc_time = pnv_set_rtc_time,
.progress = pnv_progress,
.power_save = power7_idle,
.calibrate_decr = generic_calibrate_decr,