diff options
Diffstat (limited to 'arch/ppc64/kernel/ItLpQueue.c')
| -rw-r--r-- | arch/ppc64/kernel/ItLpQueue.c | 166 |
1 files changed, 0 insertions, 166 deletions
diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c deleted file mode 100644 index cdea00d7707..00000000000 --- a/arch/ppc64/kernel/ItLpQueue.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * ItLpQueue.c - * Copyright (C) 2001 Mike Corrigan IBM Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#include <linux/stddef.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <asm/system.h> -#include <asm/paca.h> -#include <asm/iSeries/ItLpQueue.h> -#include <asm/iSeries/HvLpEvent.h> -#include <asm/iSeries/HvCallEvent.h> - -static __inline__ int set_inUse( struct ItLpQueue * lpQueue ) -{ - int t; - u32 * inUseP = &(lpQueue->xInUseWord); - - __asm__ __volatile__("\n\ -1: lwarx %0,0,%2 \n\ - cmpwi 0,%0,0 \n\ - li %0,0 \n\ - bne- 2f \n\ - addi %0,%0,1 \n\ - stwcx. %0,0,%2 \n\ - bne- 1b \n\ -2: eieio" - : "=&r" (t), "=m" (lpQueue->xInUseWord) - : "r" (inUseP), "m" (lpQueue->xInUseWord) - : "cc"); - - return t; -} - -static __inline__ void clear_inUse( struct ItLpQueue * lpQueue ) -{ - lpQueue->xInUseWord = 0; -} - -/* Array of LpEvent handler functions */ -extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; -unsigned long ItLpQueueInProcess = 0; - -struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) -{ - struct HvLpEvent * nextLpEvent = - (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; - if ( nextLpEvent->xFlags.xValid ) { - /* rmb() needed only for weakly consistent machines (regatta) */ - rmb(); - /* Set pointer to next potential event */ - lpQueue->xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + - LpEventAlign ) / - LpEventAlign ) * - LpEventAlign; - /* Wrap to beginning if no room at end */ - if (lpQueue->xSlicCurEventPtr > lpQueue->xSlicLastValidEventPtr) - lpQueue->xSlicCurEventPtr = lpQueue->xSlicEventStackPtr; - } - else - nextLpEvent = NULL; - - return nextLpEvent; -} - -int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue ) -{ - int retval = 0; - struct HvLpEvent * nextLpEvent; - if ( lpQueue ) { - nextLpEvent = (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; - retval = nextLpEvent->xFlags.xValid | lpQueue->xPlicOverflowIntPending; - } - return retval; -} - -void ItLpQueue_clearValid( struct HvLpEvent * event ) -{ - /* Clear the valid bit of the event - * Also clear bits within this event that might - * look like valid bits (on 64-byte boundaries) - */ - unsigned extra = (( event->xSizeMinus1 + LpEventAlign ) / - LpEventAlign ) - 1; - switch ( extra ) { - case 3: - ((struct HvLpEvent*)((char*)event+3*LpEventAlign))->xFlags.xValid=0; - case 2: - ((struct HvLpEvent*)((char*)event+2*LpEventAlign))->xFlags.xValid=0; - case 1: - ((struct HvLpEvent*)((char*)event+1*LpEventAlign))->xFlags.xValid=0; - case 0: - ; - } - mb(); - event->xFlags.xValid = 0; -} - -unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) -{ - unsigned numIntsProcessed = 0; - struct HvLpEvent * nextLpEvent; - - /* If we have recursed, just return */ - if ( !set_inUse( lpQueue ) ) - return 0; - - if (ItLpQueueInProcess == 0) - ItLpQueueInProcess = 1; - else - BUG(); - - for (;;) { - nextLpEvent = ItLpQueue_getNextLpEvent( lpQueue ); - if ( nextLpEvent ) { - /* Count events to return to caller - * and count processed events in lpQueue - */ - ++numIntsProcessed; - lpQueue->xLpIntCount++; - /* Call appropriate handler here, passing - * a pointer to the LpEvent. The handler - * must make a copy of the LpEvent if it - * needs it in a bottom half. (perhaps for - * an ACK) - * - * Handlers are responsible for ACK processing - * - * The Hypervisor guarantees that LpEvents will - * only be delivered with types that we have - * registered for, so no type check is necessary - * here! - */ - if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes ) - lpQueue->xLpIntCountByType[nextLpEvent->xType]++; - if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes && - lpEventHandler[nextLpEvent->xType] ) - lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); - else - printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); - - ItLpQueue_clearValid( nextLpEvent ); - } else if ( lpQueue->xPlicOverflowIntPending ) - /* - * No more valid events. If overflow events are - * pending process them - */ - HvCallEvent_getOverflowLpEvents( lpQueue->xIndex); - else - break; - } - - ItLpQueueInProcess = 0; - mb(); - clear_inUse( lpQueue ); - - get_paca()->lpevent_count += numIntsProcessed; - - return numIntsProcessed; -} |
