aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/iseries/mf.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/iseries/mf.c')
-rw-r--r--arch/powerpc/platforms/iseries/mf.c112
1 files changed, 63 insertions, 49 deletions
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index a41d8b78c0cd..d771b8ee857d 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -46,6 +46,7 @@
46#include "setup.h" 46#include "setup.h"
47 47
48extern int piranha_simulator; 48extern int piranha_simulator;
49static int mf_initialized;
49 50
50/* 51/*
51 * This is the structure layout for the Machine Facilites LPAR event 52 * This is the structure layout for the Machine Facilites LPAR event
@@ -143,7 +144,8 @@ static spinlock_t pending_event_spinlock;
143static struct pending_event *pending_event_head; 144static struct pending_event *pending_event_head;
144static struct pending_event *pending_event_tail; 145static struct pending_event *pending_event_tail;
145static struct pending_event *pending_event_avail; 146static struct pending_event *pending_event_avail;
146static struct pending_event pending_event_prealloc[16]; 147#define PENDING_EVENT_PREALLOC_LEN 16
148static struct pending_event pending_event_prealloc[PENDING_EVENT_PREALLOC_LEN];
147 149
148/* 150/*
149 * Put a pending event onto the available queue, so it can get reused. 151 * Put a pending event onto the available queue, so it can get reused.
@@ -597,7 +599,7 @@ void mf_power_off(void)
597 * Global kernel interface to tell the VSP object in the primary 599 * Global kernel interface to tell the VSP object in the primary
598 * partition to reboot this partition. 600 * partition to reboot this partition.
599 */ 601 */
600void mf_reboot(void) 602void mf_reboot(char *cmd)
601{ 603{
602 printk(KERN_INFO "mf.c: Preparing to bounce...\n"); 604 printk(KERN_INFO "mf.c: Preparing to bounce...\n");
603 signal_ce_msg_simple(0x4e, NULL); 605 signal_ce_msg_simple(0x4e, NULL);
@@ -625,7 +627,7 @@ void mf_display_src(u32 word)
625/* 627/*
626 * Display a single word SRC of the form "PROGXXXX" on the VSP control panel. 628 * Display a single word SRC of the form "PROGXXXX" on the VSP control panel.
627 */ 629 */
628void mf_display_progress(u16 value) 630static __init void mf_display_progress_src(u16 value)
629{ 631{
630 u8 ce[12]; 632 u8 ce[12];
631 u8 src[72]; 633 u8 src[72];
@@ -649,30 +651,42 @@ void mf_display_progress(u16 value)
649 * Clear the VSP control panel. Used to "erase" an SRC that was 651 * Clear the VSP control panel. Used to "erase" an SRC that was
650 * previously displayed. 652 * previously displayed.
651 */ 653 */
652void mf_clear_src(void) 654static void mf_clear_src(void)
653{ 655{
654 signal_ce_msg_simple(0x4b, NULL); 656 signal_ce_msg_simple(0x4b, NULL);
655} 657}
656 658
659void __init mf_display_progress(u16 value)
660{
661 if (piranha_simulator || !mf_initialized)
662 return;
663
664 if (0xFFFF == value)
665 mf_clear_src();
666 else
667 mf_display_progress_src(value);
668}
669
657/* 670/*
658 * Initialization code here. 671 * Initialization code here.
659 */ 672 */
660void mf_init(void) 673void __init mf_init(void)
661{ 674{
662 int i; 675 int i;
663 676
664 /* initialize */
665 spin_lock_init(&pending_event_spinlock); 677 spin_lock_init(&pending_event_spinlock);
666 for (i = 0; 678
667 i < sizeof(pending_event_prealloc) / sizeof(*pending_event_prealloc); 679 for (i = 0; i < PENDING_EVENT_PREALLOC_LEN; i++)
668 ++i)
669 free_pending_event(&pending_event_prealloc[i]); 680 free_pending_event(&pending_event_prealloc[i]);
681
670 HvLpEvent_registerHandler(HvLpEvent_Type_MachineFac, &hv_handler); 682 HvLpEvent_registerHandler(HvLpEvent_Type_MachineFac, &hv_handler);
671 683
672 /* virtual continue ack */ 684 /* virtual continue ack */
673 signal_ce_msg_simple(0x57, NULL); 685 signal_ce_msg_simple(0x57, NULL);
674 686
675 /* initialization complete */ 687 mf_initialized = 1;
688 mb();
689
676 printk(KERN_NOTICE "mf.c: iSeries Linux LPAR Machine Facilities " 690 printk(KERN_NOTICE "mf.c: iSeries Linux LPAR Machine Facilities "
677 "initialized\n"); 691 "initialized\n");
678} 692}
@@ -692,6 +706,43 @@ static void get_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
692 complete(&rtc->com); 706 complete(&rtc->com);
693} 707}
694 708
709static int mf_set_rtc(struct rtc_time *tm)
710{
711 char ce_time[12];
712 u8 day, mon, hour, min, sec, y1, y2;
713 unsigned year;
714
715 year = 1900 + tm->tm_year;
716 y1 = year / 100;
717 y2 = year % 100;
718
719 sec = tm->tm_sec;
720 min = tm->tm_min;
721 hour = tm->tm_hour;
722 day = tm->tm_mday;
723 mon = tm->tm_mon + 1;
724
725 BIN_TO_BCD(sec);
726 BIN_TO_BCD(min);
727 BIN_TO_BCD(hour);
728 BIN_TO_BCD(mon);
729 BIN_TO_BCD(day);
730 BIN_TO_BCD(y1);
731 BIN_TO_BCD(y2);
732
733 memset(ce_time, 0, sizeof(ce_time));
734 ce_time[3] = 0x41;
735 ce_time[4] = y1;
736 ce_time[5] = y2;
737 ce_time[6] = sec;
738 ce_time[7] = min;
739 ce_time[8] = hour;
740 ce_time[10] = day;
741 ce_time[11] = mon;
742
743 return signal_ce_msg(ce_time, NULL);
744}
745
695static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm) 746static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
696{ 747{
697 tm->tm_wday = 0; 748 tm->tm_wday = 0;
@@ -747,7 +798,7 @@ static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
747 return 0; 798 return 0;
748} 799}
749 800
750int mf_get_rtc(struct rtc_time *tm) 801static int mf_get_rtc(struct rtc_time *tm)
751{ 802{
752 struct ce_msg_comp_data ce_complete; 803 struct ce_msg_comp_data ce_complete;
753 struct rtc_time_data rtc_data; 804 struct rtc_time_data rtc_data;
@@ -780,7 +831,7 @@ static void get_boot_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
780 rtc->busy = 0; 831 rtc->busy = 0;
781} 832}
782 833
783int mf_get_boot_rtc(struct rtc_time *tm) 834static int mf_get_boot_rtc(struct rtc_time *tm)
784{ 835{
785 struct ce_msg_comp_data ce_complete; 836 struct ce_msg_comp_data ce_complete;
786 struct boot_rtc_time_data rtc_data; 837 struct boot_rtc_time_data rtc_data;
@@ -802,43 +853,6 @@ int mf_get_boot_rtc(struct rtc_time *tm)
802 return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); 853 return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
803} 854}
804 855
805int mf_set_rtc(struct rtc_time *tm)
806{
807 char ce_time[12];
808 u8 day, mon, hour, min, sec, y1, y2;
809 unsigned year;
810
811 year = 1900 + tm->tm_year;
812 y1 = year / 100;
813 y2 = year % 100;
814
815 sec = tm->tm_sec;
816 min = tm->tm_min;
817 hour = tm->tm_hour;
818 day = tm->tm_mday;
819 mon = tm->tm_mon + 1;
820
821 BIN_TO_BCD(sec);
822 BIN_TO_BCD(min);
823 BIN_TO_BCD(hour);
824 BIN_TO_BCD(mon);
825 BIN_TO_BCD(day);
826 BIN_TO_BCD(y1);
827 BIN_TO_BCD(y2);
828
829 memset(ce_time, 0, sizeof(ce_time));
830 ce_time[3] = 0x41;
831 ce_time[4] = y1;
832 ce_time[5] = y2;
833 ce_time[6] = sec;
834 ce_time[7] = min;
835 ce_time[8] = hour;
836 ce_time[10] = day;
837 ce_time[11] = mon;
838
839 return signal_ce_msg(ce_time, NULL);
840}
841
842#ifdef CONFIG_PROC_FS 856#ifdef CONFIG_PROC_FS
843 857
844static int proc_mf_dump_cmdline(char *page, char **start, off_t off, 858static int proc_mf_dump_cmdline(char *page, char **start, off_t off,