diff options
-rw-r--r-- | arch/powerpc/kernel/time.c | 30 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/setup.c | 6 | ||||
-rw-r--r-- | include/asm-powerpc/time.h | 2 |
3 files changed, 23 insertions, 15 deletions
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 43c687a1d76..66d2db7495a 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -77,9 +77,8 @@ /* keep track of when we need to update the rtc */ time_t last_rtc_update; #ifdef CONFIG_PPC_ISERIES -unsigned long iSeries_recal_titan = 0; -unsigned long iSeries_recal_tb = 0; -static unsigned long first_settimeofday = 1; +static unsigned long __initdata iSeries_recal_titan; +static signed long __initdata iSeries_recal_tb; #endif /* The decrementer counts down by 128 every 128ns on a 601. */ @@ -556,10 +555,15 @@ EXPORT_SYMBOL(profile_pc); * returned by the service processor for the timebase frequency. */ -static void iSeries_tb_recal(void) +static int __init iSeries_tb_recal(void) { struct div_result divres; unsigned long titan, tb; + + /* Make sure we only run on iSeries */ + if (!firmware_has_feature(FW_FEATURE_ISERIES)) + return -ENODEV; + tb = get_tb(); titan = HvCallXm_loadTod(); if ( iSeries_recal_titan ) { @@ -600,8 +604,18 @@ static void iSeries_tb_recal(void) } iSeries_recal_titan = titan; iSeries_recal_tb = tb; + + return 0; } -#endif +late_initcall(iSeries_tb_recal); + +/* Called from platform early init */ +void __init iSeries_time_init_early(void) +{ + iSeries_recal_tb = get_tb(); + iSeries_recal_titan = HvCallXm_loadTod(); +} +#endif /* CONFIG_PPC_ISERIES */ /* * For iSeries shared processors, we have to let the hypervisor @@ -765,12 +779,6 @@ int do_settimeofday(struct timespec *tv) * to the RTC again, or write to the RTC but then they don't call * settimeofday to perform this operation. */ -#ifdef CONFIG_PPC_ISERIES - if (firmware_has_feature(FW_FEATURE_ISERIES) && first_settimeofday) { - iSeries_tb_recal(); - first_settimeofday = 0; - } -#endif /* Make userspace gettimeofday spin until we're done. */ ++vdso_data->tb_update_count; diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 7f5dcee814d..13a8b1908de 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -79,8 +79,6 @@ extern void iSeries_pci_final_fixup(void); static void iSeries_pci_final_fixup(void) { } #endif -extern unsigned long iSeries_recal_tb; -extern unsigned long iSeries_recal_titan; struct MemoryBlock { unsigned long absStart; @@ -292,8 +290,8 @@ static void __init iSeries_init_early(void) { DBG(" -> iSeries_init_early()\n"); - iSeries_recal_tb = get_tb(); - iSeries_recal_titan = HvCallXm_loadTod(); + /* Snapshot the timebase, for use in later recalibration */ + iSeries_time_init_early(); /* * Initialize the DMA/TCE management diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h index 2d00e13c981..d7f5ddfbaac 100644 --- a/include/asm-powerpc/time.h +++ b/include/asm-powerpc/time.h @@ -240,5 +240,7 @@ extern void snapshot_timebases(void); #define snapshot_timebases() do { } while (0) #endif +extern void iSeries_time_init_early(void); + #endif /* __KERNEL__ */ #endif /* __POWERPC_TIME_H */ |