aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/iSeries_setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc64/kernel/iSeries_setup.c')
-rw-r--r--arch/ppc64/kernel/iSeries_setup.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
index b3f770f6d402..1139e27e1713 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -834,6 +834,87 @@ static int __init iSeries_src_init(void)
834 834
835late_initcall(iSeries_src_init); 835late_initcall(iSeries_src_init);
836 836
837static unsigned long maxYieldTime = 0;
838static unsigned long minYieldTime = 0xffffffffffffffffUL;
839
840static inline void process_iSeries_events(void)
841{
842 asm volatile ("li 0,0x5555; sc" : : : "r0", "r3");
843}
844
845static void yield_shared_processor(void)
846{
847 unsigned long tb;
848 unsigned long yieldTime;
849
850 HvCall_setEnabledInterrupts(HvCall_MaskIPI |
851 HvCall_MaskLpEvent |
852 HvCall_MaskLpProd |
853 HvCall_MaskTimeout);
854
855 tb = get_tb();
856 /* Compute future tb value when yield should expire */
857 HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy);
858
859 yieldTime = get_tb() - tb;
860 if (yieldTime > maxYieldTime)
861 maxYieldTime = yieldTime;
862
863 if (yieldTime < minYieldTime)
864 minYieldTime = yieldTime;
865
866 /*
867 * The decrementer stops during the yield. Force a fake decrementer
868 * here and let the timer_interrupt code sort out the actual time.
869 */
870 get_paca()->lppaca.int_dword.fields.decr_int = 1;
871 process_iSeries_events();
872}
873
874static int iSeries_idle(void)
875{
876 struct paca_struct *lpaca;
877 long oldval;
878
879 /* ensure iSeries run light will be out when idle */
880 ppc64_runlatch_off();
881
882 lpaca = get_paca();
883
884 while (1) {
885 if (lpaca->lppaca.shared_proc) {
886 if (hvlpevent_is_pending())
887 process_iSeries_events();
888 if (!need_resched())
889 yield_shared_processor();
890 } else {
891 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
892
893 if (!oldval) {
894 set_thread_flag(TIF_POLLING_NRFLAG);
895
896 while (!need_resched()) {
897 HMT_medium();
898 if (hvlpevent_is_pending())
899 process_iSeries_events();
900 HMT_low();
901 }
902
903 HMT_medium();
904 clear_thread_flag(TIF_POLLING_NRFLAG);
905 } else {
906 set_need_resched();
907 }
908 }
909
910 ppc64_runlatch_on();
911 schedule();
912 ppc64_runlatch_off();
913 }
914
915 return 0;
916}
917
837#ifndef CONFIG_PCI 918#ifndef CONFIG_PCI
838void __init iSeries_init_IRQ(void) { } 919void __init iSeries_init_IRQ(void) { }
839#endif 920#endif