diff options
Diffstat (limited to 'arch/powerpc/platforms/iseries/mf.c')
-rw-r--r-- | arch/powerpc/platforms/iseries/mf.c | 112 |
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 | ||
48 | extern int piranha_simulator; | 48 | extern int piranha_simulator; |
49 | static 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; | |||
143 | static struct pending_event *pending_event_head; | 144 | static struct pending_event *pending_event_head; |
144 | static struct pending_event *pending_event_tail; | 145 | static struct pending_event *pending_event_tail; |
145 | static struct pending_event *pending_event_avail; | 146 | static struct pending_event *pending_event_avail; |
146 | static struct pending_event pending_event_prealloc[16]; | 147 | #define PENDING_EVENT_PREALLOC_LEN 16 |
148 | static 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 | */ |
600 | void mf_reboot(void) | 602 | void 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 | */ |
628 | void mf_display_progress(u16 value) | 630 | static __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 | */ |
652 | void mf_clear_src(void) | 654 | static 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 | ||
659 | void __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 | */ |
660 | void mf_init(void) | 673 | void __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 | ||
709 | static 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 | |||
695 | static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm) | 746 | static 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 | ||
750 | int mf_get_rtc(struct rtc_time *tm) | 801 | static 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 | ||
783 | int mf_get_boot_rtc(struct rtc_time *tm) | 834 | static 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 | ||
805 | int 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 | ||
844 | static int proc_mf_dump_cmdline(char *page, char **start, off_t off, | 858 | static int proc_mf_dump_cmdline(char *page, char **start, off_t off, |