aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2005-05-25 17:58:04 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-05-25 17:58:04 -0400
commit4b463f785837f73bdd88ae3821bb7b69599010c9 (patch)
tree80dc0a7e3e33596ff3ece410d9ff9e6b63e45b87 /arch
parent6df16d0c35b9c0d3627f30c106e6142d3d12662b (diff)
parent384f1fcd2db8bc5a15f20f10793d8e1c82acd6c5 (diff)
Merge of /home/davem/src/GIT/linux-2.6/.git/
Diffstat (limited to 'arch')
-rw-r--r--arch/i386/mach-voyager/voyager_smp.c17
-rw-r--r--arch/ppc64/kernel/mf.c85
-rw-r--r--arch/ppc64/kernel/rtc.c39
-rw-r--r--arch/ppc64/kernel/time.c1
4 files changed, 75 insertions, 67 deletions
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
index 903d739ca74a..a6e0ddd65bd0 100644
--- a/arch/i386/mach-voyager/voyager_smp.c
+++ b/arch/i386/mach-voyager/voyager_smp.c
@@ -97,7 +97,6 @@ static void ack_vic_irq(unsigned int irq);
97static void vic_enable_cpi(void); 97static void vic_enable_cpi(void);
98static void do_boot_cpu(__u8 cpuid); 98static void do_boot_cpu(__u8 cpuid);
99static void do_quad_bootstrap(void); 99static void do_quad_bootstrap(void);
100static inline void wrapper_smp_local_timer_interrupt(struct pt_regs *);
101 100
102int hard_smp_processor_id(void); 101int hard_smp_processor_id(void);
103 102
@@ -126,6 +125,14 @@ send_QIC_CPI(__u32 cpuset, __u8 cpi)
126} 125}
127 126
128static inline void 127static inline void
128wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
129{
130 irq_enter();
131 smp_local_timer_interrupt(regs);
132 irq_exit();
133}
134
135static inline void
129send_one_CPI(__u8 cpu, __u8 cpi) 136send_one_CPI(__u8 cpu, __u8 cpi)
130{ 137{
131 if(voyager_quad_processors & (1<<cpu)) 138 if(voyager_quad_processors & (1<<cpu))
@@ -1249,14 +1256,6 @@ smp_vic_timer_interrupt(struct pt_regs *regs)
1249 smp_local_timer_interrupt(regs); 1256 smp_local_timer_interrupt(regs);
1250} 1257}
1251 1258
1252static inline void
1253wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
1254{
1255 irq_enter();
1256 smp_local_timer_interrupt(regs);
1257 irq_exit();
1258}
1259
1260/* local (per CPU) timer interrupt. It does both profiling and 1259/* local (per CPU) timer interrupt. It does both profiling and
1261 * process statistics/rescheduling. 1260 * process statistics/rescheduling.
1262 * 1261 *
diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c
index 1bd52ece497c..5aca7e8005a8 100644
--- a/arch/ppc64/kernel/mf.c
+++ b/arch/ppc64/kernel/mf.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * mf.c 2 * mf.c
3 * Copyright (C) 2001 Troy D. Armstrong IBM Corporation 3 * Copyright (C) 2001 Troy D. Armstrong IBM Corporation
4 * Copyright (C) 2004 Stephen Rothwell IBM Corporation 4 * Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation
5 * 5 *
6 * This modules exists as an interface between a Linux secondary partition 6 * This modules exists as an interface between a Linux secondary partition
7 * running on an iSeries and the primary partition's Virtual Service 7 * running on an iSeries and the primary partition's Virtual Service
@@ -36,10 +36,12 @@
36 36
37#include <asm/time.h> 37#include <asm/time.h>
38#include <asm/uaccess.h> 38#include <asm/uaccess.h>
39#include <asm/paca.h>
39#include <asm/iSeries/vio.h> 40#include <asm/iSeries/vio.h>
40#include <asm/iSeries/mf.h> 41#include <asm/iSeries/mf.h>
41#include <asm/iSeries/HvLpConfig.h> 42#include <asm/iSeries/HvLpConfig.h>
42#include <asm/iSeries/ItSpCommArea.h> 43#include <asm/iSeries/ItSpCommArea.h>
44#include <asm/iSeries/ItLpQueue.h>
43 45
44/* 46/*
45 * This is the structure layout for the Machine Facilites LPAR event 47 * This is the structure layout for the Machine Facilites LPAR event
@@ -696,36 +698,23 @@ static void get_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
696 complete(&rtc->com); 698 complete(&rtc->com);
697} 699}
698 700
699int mf_get_rtc(struct rtc_time *tm) 701static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
700{ 702{
701 struct ce_msg_comp_data ce_complete;
702 struct rtc_time_data rtc_data;
703 int rc;
704
705 memset(&ce_complete, 0, sizeof(ce_complete));
706 memset(&rtc_data, 0, sizeof(rtc_data));
707 init_completion(&rtc_data.com);
708 ce_complete.handler = &get_rtc_time_complete;
709 ce_complete.token = &rtc_data;
710 rc = signal_ce_msg_simple(0x40, &ce_complete);
711 if (rc)
712 return rc;
713 wait_for_completion(&rtc_data.com);
714 tm->tm_wday = 0; 703 tm->tm_wday = 0;
715 tm->tm_yday = 0; 704 tm->tm_yday = 0;
716 tm->tm_isdst = 0; 705 tm->tm_isdst = 0;
717 if (rtc_data.rc) { 706 if (rc) {
718 tm->tm_sec = 0; 707 tm->tm_sec = 0;
719 tm->tm_min = 0; 708 tm->tm_min = 0;
720 tm->tm_hour = 0; 709 tm->tm_hour = 0;
721 tm->tm_mday = 15; 710 tm->tm_mday = 15;
722 tm->tm_mon = 5; 711 tm->tm_mon = 5;
723 tm->tm_year = 52; 712 tm->tm_year = 52;
724 return rtc_data.rc; 713 return rc;
725 } 714 }
726 715
727 if ((rtc_data.ce_msg.ce_msg[2] == 0xa9) || 716 if ((ce_msg[2] == 0xa9) ||
728 (rtc_data.ce_msg.ce_msg[2] == 0xaf)) { 717 (ce_msg[2] == 0xaf)) {
729 /* TOD clock is not set */ 718 /* TOD clock is not set */
730 tm->tm_sec = 1; 719 tm->tm_sec = 1;
731 tm->tm_min = 1; 720 tm->tm_min = 1;
@@ -736,7 +725,6 @@ int mf_get_rtc(struct rtc_time *tm)
736 mf_set_rtc(tm); 725 mf_set_rtc(tm);
737 } 726 }
738 { 727 {
739 u8 *ce_msg = rtc_data.ce_msg.ce_msg;
740 u8 year = ce_msg[5]; 728 u8 year = ce_msg[5];
741 u8 sec = ce_msg[6]; 729 u8 sec = ce_msg[6];
742 u8 min = ce_msg[7]; 730 u8 min = ce_msg[7];
@@ -765,6 +753,63 @@ int mf_get_rtc(struct rtc_time *tm)
765 return 0; 753 return 0;
766} 754}
767 755
756int mf_get_rtc(struct rtc_time *tm)
757{
758 struct ce_msg_comp_data ce_complete;
759 struct rtc_time_data rtc_data;
760 int rc;
761
762 memset(&ce_complete, 0, sizeof(ce_complete));
763 memset(&rtc_data, 0, sizeof(rtc_data));
764 init_completion(&rtc_data.com);
765 ce_complete.handler = &get_rtc_time_complete;
766 ce_complete.token = &rtc_data;
767 rc = signal_ce_msg_simple(0x40, &ce_complete);
768 if (rc)
769 return rc;
770 wait_for_completion(&rtc_data.com);
771 return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
772}
773
774struct boot_rtc_time_data {
775 int busy;
776 struct ce_msg_data ce_msg;
777 int rc;
778};
779
780static void get_boot_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
781{
782 struct boot_rtc_time_data *rtc = token;
783
784 memcpy(&rtc->ce_msg, ce_msg, sizeof(rtc->ce_msg));
785 rtc->rc = 0;
786 rtc->busy = 0;
787}
788
789int mf_get_boot_rtc(struct rtc_time *tm)
790{
791 struct ce_msg_comp_data ce_complete;
792 struct boot_rtc_time_data rtc_data;
793 int rc;
794
795 memset(&ce_complete, 0, sizeof(ce_complete));
796 memset(&rtc_data, 0, sizeof(rtc_data));
797 rtc_data.busy = 1;
798 ce_complete.handler = &get_boot_rtc_time_complete;
799 ce_complete.token = &rtc_data;
800 rc = signal_ce_msg_simple(0x40, &ce_complete);
801 if (rc)
802 return rc;
803 /* We need to poll here as we are not yet taking interrupts */
804 while (rtc_data.busy) {
805 extern unsigned long lpevent_count;
806 struct ItLpQueue *lpq = get_paca()->lpqueue_ptr;
807 if (lpq && ItLpQueue_isLpIntPending(lpq))
808 lpevent_count += ItLpQueue_process(lpq, NULL);
809 }
810 return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
811}
812
768int mf_set_rtc(struct rtc_time *tm) 813int mf_set_rtc(struct rtc_time *tm)
769{ 814{
770 char ce_time[12]; 815 char ce_time[12];
diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c
index 3e70b91375fc..67989055a9fe 100644
--- a/arch/ppc64/kernel/rtc.c
+++ b/arch/ppc64/kernel/rtc.c
@@ -292,47 +292,10 @@ int iSeries_set_rtc_time(struct rtc_time *tm)
292 292
293void iSeries_get_boot_time(struct rtc_time *tm) 293void iSeries_get_boot_time(struct rtc_time *tm)
294{ 294{
295 unsigned long time;
296 static unsigned long lastsec = 1;
297
298 u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart));
299 u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1);
300 int year = 1970;
301 int year1 = ( dataWord1 >> 24 ) & 0x000000FF;
302 int year2 = ( dataWord1 >> 16 ) & 0x000000FF;
303 int sec = ( dataWord1 >> 8 ) & 0x000000FF;
304 int min = dataWord1 & 0x000000FF;
305 int hour = ( dataWord2 >> 24 ) & 0x000000FF;
306 int day = ( dataWord2 >> 8 ) & 0x000000FF;
307 int mon = dataWord2 & 0x000000FF;
308
309 if ( piranha_simulator ) 295 if ( piranha_simulator )
310 return; 296 return;
311 297
312 BCD_TO_BIN(sec); 298 mf_get_boot_rtc(tm);
313 BCD_TO_BIN(min);
314 BCD_TO_BIN(hour);
315 BCD_TO_BIN(day);
316 BCD_TO_BIN(mon);
317 BCD_TO_BIN(year1);
318 BCD_TO_BIN(year2);
319 year = year1 * 100 + year2;
320
321 time = mktime(year, mon, day, hour, min, sec);
322 time += ( jiffies / HZ );
323
324 /* Now THIS is a nasty hack!
325 * It ensures that the first two calls get different answers.
326 * That way the loop in init_time (time.c) will not think
327 * the clock is stuck.
328 */
329 if ( lastsec ) {
330 time -= lastsec;
331 --lastsec;
332 }
333
334 to_tm(time, tm);
335 tm->tm_year -= 1900;
336 tm->tm_mon -= 1; 299 tm->tm_mon -= 1;
337} 300}
338#endif 301#endif
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
index 772a465b49f9..3d54745108c7 100644
--- a/arch/ppc64/kernel/time.c
+++ b/arch/ppc64/kernel/time.c
@@ -515,6 +515,7 @@ void __init time_init(void)
515 do_gtod.varp = &do_gtod.vars[0]; 515 do_gtod.varp = &do_gtod.vars[0];
516 do_gtod.var_idx = 0; 516 do_gtod.var_idx = 0;
517 do_gtod.varp->tb_orig_stamp = tb_last_stamp; 517 do_gtod.varp->tb_orig_stamp = tb_last_stamp;
518 get_paca()->next_jiffy_update_tb = tb_last_stamp + tb_ticks_per_jiffy;
518 do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC; 519 do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
519 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; 520 do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
520 do_gtod.varp->tb_to_xs = tb_to_xs; 521 do_gtod.varp->tb_to_xs = tb_to_xs;