diff options
author | Michael Ellerman <michael@ellerman.id.au> | 2005-07-07 20:56:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-07 21:23:40 -0400 |
commit | d200903e11f6867b91dffa81b2038e55be599f49 (patch) | |
tree | e741dfb082e94685c6cb0d1ccc3616c216af7c7a /arch/ppc64/kernel/iSeries_setup.c | |
parent | fd899c0cc725387992ccfc83fb6f70505c36cbeb (diff) |
[PATCH] ppc64: Move iSeries_idle() into iSeries_setup.c
Move iSeries_idle() into iSeries_setup.c, no one else needs to know about it.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc64/kernel/iSeries_setup.c')
-rw-r--r-- | arch/ppc64/kernel/iSeries_setup.c | 81 |
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 | ||
835 | late_initcall(iSeries_src_init); | 835 | late_initcall(iSeries_src_init); |
836 | 836 | ||
837 | static unsigned long maxYieldTime = 0; | ||
838 | static unsigned long minYieldTime = 0xffffffffffffffffUL; | ||
839 | |||
840 | static inline void process_iSeries_events(void) | ||
841 | { | ||
842 | asm volatile ("li 0,0x5555; sc" : : : "r0", "r3"); | ||
843 | } | ||
844 | |||
845 | static 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 | |||
874 | static 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 |
838 | void __init iSeries_init_IRQ(void) { } | 919 | void __init iSeries_init_IRQ(void) { } |
839 | #endif | 920 | #endif |