aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/epl/TimerHighReskX86.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/epl/TimerHighReskX86.c')
-rw-r--r--drivers/staging/epl/TimerHighReskX86.c510
1 files changed, 0 insertions, 510 deletions
diff --git a/drivers/staging/epl/TimerHighReskX86.c b/drivers/staging/epl/TimerHighReskX86.c
deleted file mode 100644
index d6897de4f140..000000000000
--- a/drivers/staging/epl/TimerHighReskX86.c
+++ /dev/null
@@ -1,510 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: openPOWERLINK
-
- Description: target specific implementation of
- high resolution timer module for X86 under Linux
- The Linux kernel has to be compiled with high resolution
- timers enabled. This is done by configuring the kernel
- with CONFIG_HIGH_RES_TIMERS enabled.
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- $RCSfile: TimerHighReskX86.c,v $
-
- $Author: D.Krueger $
-
- $Revision: 1.4 $ $Date: 2008/04/17 21:38:01 $
-
- $State: Exp $
-
- Build Environment:
- GNU
-
- -------------------------------------------------------------------------
-
- Revision History:
-
-****************************************************************************/
-
-#include "EplInc.h"
-#include "kernel/EplTimerHighResk.h"
-#include "Benchmark.h"
-
-//#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/hrtimer.h>
-
-/***************************************************************************/
-/* */
-/* */
-/* G L O B A L D E F I N I T I O N S */
-/* */
-/* */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#define TIMER_COUNT 2 /* max 15 timers selectable */
-#define TIMER_MIN_VAL_SINGLE 5000 /* min 5us */
-#define TIMER_MIN_VAL_CYCLE 100000 /* min 100us */
-
-#define PROVE_OVERRUN
-
-// TracePoint support for realtime-debugging
-#ifdef _DBG_TRACE_POINTS_
-void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
-void TgtDbgPostTraceValue(u32 dwTraceValue_p);
-#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
-#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
-#else
-#define TGT_DBG_SIGNAL_TRACE_POINT(p)
-#define TGT_DBG_POST_TRACE_VALUE(v)
-#endif
-#define HRT_DBG_POST_TRACE_VALUE(Event_p, uiNodeId_p, wErrorCode_p) \
- TGT_DBG_POST_TRACE_VALUE((0xE << 28) | (Event_p << 24) \
- | (uiNodeId_p << 16) | wErrorCode_p)
-
-#define TIMERHDL_MASK 0x0FFFFFFF
-#define TIMERHDL_SHIFT 28
-#define HDL_TO_IDX(Hdl) ((Hdl >> TIMERHDL_SHIFT) - 1)
-#define HDL_INIT(Idx) ((Idx + 1) << TIMERHDL_SHIFT)
-#define HDL_INC(Hdl) (((Hdl + 1) & TIMERHDL_MASK) \
- | (Hdl & ~TIMERHDL_MASK))
-
-//---------------------------------------------------------------------------
-// modul global types
-//---------------------------------------------------------------------------
-
-typedef struct {
- tEplTimerEventArg m_EventArg;
- tEplTimerkCallback m_pfnCallback;
- struct hrtimer m_Timer;
- BOOL m_fContinuously;
- unsigned long long m_ullPeriod;
-
-} tEplTimerHighReskTimerInfo;
-
-typedef struct {
- tEplTimerHighReskTimerInfo m_aTimerInfo[TIMER_COUNT];
-
-} tEplTimerHighReskInstance;
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-static tEplTimerHighReskInstance EplTimerHighReskInstance_l;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-enum hrtimer_restart EplTimerHighReskCallback(struct hrtimer *pTimer_p);
-
-//=========================================================================//
-// //
-// P U B L I C F U N C T I O N S //
-// //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimerHighReskInit()
-//
-// Description: initializes the high resolution timer module.
-//
-// Parameters: void
-//
-// Return: tEplKernel = error code
-//
-// State: not tested
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplTimerHighReskInit(void)
-{
- tEplKernel Ret;
-
- Ret = EplTimerHighReskAddInstance();
-
- return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimerHighReskAddInstance()
-//
-// Description: initializes the high resolution timer module.
-//
-// Parameters: void
-//
-// Return: tEplKernel = error code
-//
-// State: not tested
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplTimerHighReskAddInstance(void)
-{
- tEplKernel Ret;
- unsigned int uiIndex;
-
- Ret = kEplSuccessful;
-
- EPL_MEMSET(&EplTimerHighReskInstance_l, 0,
- sizeof(EplTimerHighReskInstance_l));
-
- /*
- * Initialize hrtimer structures for all usable timers.
- */
- for (uiIndex = 0; uiIndex < TIMER_COUNT; uiIndex++) {
- tEplTimerHighReskTimerInfo *pTimerInfo;
- struct hrtimer *pTimer;
-
- pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex];
- pTimer = &pTimerInfo->m_Timer;
- hrtimer_init(pTimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
-
- pTimer->function = EplTimerHighReskCallback;
- }
-
- return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimerHighReskDelInstance()
-//
-// Description: shuts down the high resolution timer module.
-//
-// Parameters: void
-//
-// Return: tEplKernel = error code
-//
-// State: not tested
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplTimerHighReskDelInstance(void)
-{
- tEplTimerHighReskTimerInfo *pTimerInfo;
- tEplKernel Ret;
- unsigned int uiIndex;
-
- Ret = kEplSuccessful;
-
- for (uiIndex = 0; uiIndex < TIMER_COUNT; uiIndex++) {
- pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[0];
- pTimerInfo->m_pfnCallback = NULL;
- pTimerInfo->m_EventArg.m_TimerHdl = 0;
- /*
- * In this case we can not just try to cancel the timer.
- * We actually have to wait until its callback function
- * has returned.
- */
- hrtimer_cancel(&pTimerInfo->m_Timer);
- }
-
- return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimerHighReskModifyTimerNs()
-//
-// Description: modifies the timeout of the timer with the specified handle.
-// If the handle the pointer points to is zero, the timer must
-// be created first.
-// If it is not possible to stop the old timer,
-// this function always assures that the old timer does not
-// trigger the callback function with the same handle as the new
-// timer. That means the callback function must check the passed
-// handle with the one returned by this function. If these are
-// unequal, the call can be discarded.
-//
-// Parameters: pTimerHdl_p = pointer to timer handle
-// ullTimeNs_p = relative timeout in [ns]
-// pfnCallback_p = callback function, which is called mutual
-// exclusive with the Edrv callback functions
-// (Rx and Tx).
-// ulArgument_p = user-specific argument
-// fContinuously_p = if TRUE, callback function will be called
-// continuously;
-// otherwise, it is a oneshot timer.
-//
-// Return: tEplKernel = error code
-//
-// State: not tested
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplTimerHighReskModifyTimerNs(tEplTimerHdl *pTimerHdl_p,
- unsigned long long ullTimeNs_p,
- tEplTimerkCallback pfnCallback_p,
- unsigned long ulArgument_p,
- BOOL fContinuously_p)
-{
- tEplKernel Ret;
- unsigned int uiIndex;
- tEplTimerHighReskTimerInfo *pTimerInfo;
- ktime_t RelTime;
-
- Ret = kEplSuccessful;
-
- // check pointer to handle
- if (pTimerHdl_p == NULL) {
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
-
- if (*pTimerHdl_p == 0) { // no timer created yet
-
- // search free timer info structure
- pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[0];
- for (uiIndex = 0; uiIndex < TIMER_COUNT;
- uiIndex++, pTimerInfo++) {
- if (pTimerInfo->m_EventArg.m_TimerHdl == 0) { // free structure found
- break;
- }
- }
- if (uiIndex >= TIMER_COUNT) { // no free structure found
- Ret = kEplTimerNoTimerCreated;
- goto Exit;
- }
-
- pTimerInfo->m_EventArg.m_TimerHdl = HDL_INIT(uiIndex);
- } else {
- uiIndex = HDL_TO_IDX(*pTimerHdl_p);
- if (uiIndex >= TIMER_COUNT) { // invalid handle
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
-
- pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex];
- }
-
- /*
- * increment timer handle
- * (if timer expires right after this statement, the user
- * would detect an unknown timer handle and discard it)
- */
- pTimerInfo->m_EventArg.m_TimerHdl =
- HDL_INC(pTimerInfo->m_EventArg.m_TimerHdl);
- *pTimerHdl_p = pTimerInfo->m_EventArg.m_TimerHdl;
-
- // reject too small time values
- if ((fContinuously_p && (ullTimeNs_p < TIMER_MIN_VAL_CYCLE))
- || (!fContinuously_p && (ullTimeNs_p < TIMER_MIN_VAL_SINGLE))) {
- Ret = kEplTimerNoTimerCreated;
- goto Exit;
- }
-
- pTimerInfo->m_EventArg.m_ulArg = ulArgument_p;
- pTimerInfo->m_pfnCallback = pfnCallback_p;
- pTimerInfo->m_fContinuously = fContinuously_p;
- pTimerInfo->m_ullPeriod = ullTimeNs_p;
-
- /*
- * HRTIMER_MODE_REL does not influence general handling of this timer.
- * It only sets relative mode for this start operation.
- * -> Expire time is calculated by: Now + RelTime
- * hrtimer_start also skips pending timer events.
- * The state HRTIMER_STATE_CALLBACK is ignored.
- * We have to cope with that in our callback function.
- */
- RelTime = ktime_add_ns(ktime_set(0, 0), ullTimeNs_p);
- hrtimer_start(&pTimerInfo->m_Timer, RelTime, HRTIMER_MODE_REL);
-
- Exit:
- return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimerHighReskDeleteTimer()
-//
-// Description: deletes the timer with the specified handle. Afterward the
-// handle is set to zero.
-//
-// Parameters: pTimerHdl_p = pointer to timer handle
-//
-// Return: tEplKernel = error code
-//
-// State: not tested
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplTimerHighReskDeleteTimer(tEplTimerHdl *pTimerHdl_p)
-{
- tEplKernel Ret = kEplSuccessful;
- unsigned int uiIndex;
- tEplTimerHighReskTimerInfo *pTimerInfo;
-
- // check pointer to handle
- if (pTimerHdl_p == NULL) {
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
-
- if (*pTimerHdl_p == 0) { // no timer created yet
- goto Exit;
- } else {
- uiIndex = HDL_TO_IDX(*pTimerHdl_p);
- if (uiIndex >= TIMER_COUNT) { // invalid handle
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
- pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex];
- if (pTimerInfo->m_EventArg.m_TimerHdl != *pTimerHdl_p) { // invalid handle
- goto Exit;
- }
- }
-
- *pTimerHdl_p = 0;
- pTimerInfo->m_EventArg.m_TimerHdl = 0;
- pTimerInfo->m_pfnCallback = NULL;
-
- /*
- * Three return cases of hrtimer_try_to_cancel have to be tracked:
- * 1 - timer has been removed
- * 0 - timer was not active
- * We need not do anything. hrtimer timers just consist of
- * a hrtimer struct, which we might enqueue in the hrtimers
- * event list by calling hrtimer_start().
- * If a timer is not enqueued, it is not present in hrtimers.
- * -1 - callback function is running
- * In this case we have to ensure that the timer is not
- * continuously restarted. This has been done by clearing
- * its handle.
- */
- hrtimer_try_to_cancel(&pTimerInfo->m_Timer);
-
- Exit:
- return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimerHighReskCallback()
-//
-// Description: Callback function commonly used for all timers.
-//
-// Parameters: pTimer_p = pointer to hrtimer
-//
-// Return:
-//
-// State: not tested
-//
-//---------------------------------------------------------------------------
-
-enum hrtimer_restart EplTimerHighReskCallback(struct hrtimer *pTimer_p)
-{
- unsigned int uiIndex;
- tEplTimerHighReskTimerInfo *pTimerInfo;
- tEplTimerHdl OrgTimerHdl;
- enum hrtimer_restart Ret;
-
- BENCHMARK_MOD_24_SET(4);
-
- Ret = HRTIMER_NORESTART;
- pTimerInfo =
- container_of(pTimer_p, tEplTimerHighReskTimerInfo, m_Timer);
- uiIndex = HDL_TO_IDX(pTimerInfo->m_EventArg.m_TimerHdl);
- if (uiIndex >= TIMER_COUNT) { // invalid handle
- goto Exit;
- }
-
- /*
- * We store the timer handle before calling the callback function
- * as the timer can be modified inside it.
- */
- OrgTimerHdl = pTimerInfo->m_EventArg.m_TimerHdl;
-
- if (pTimerInfo->m_pfnCallback != NULL) {
- pTimerInfo->m_pfnCallback(&pTimerInfo->m_EventArg);
- }
-
- if (pTimerInfo->m_fContinuously) {
- ktime_t Interval;
-#ifdef PROVE_OVERRUN
- ktime_t Now;
- unsigned long Overruns;
-#endif
-
- if (OrgTimerHdl != pTimerInfo->m_EventArg.m_TimerHdl) {
- /* modified timer has already been restarted */
- goto Exit;
- }
-#ifdef PROVE_OVERRUN
- Now = ktime_get();
- Interval =
- ktime_add_ns(ktime_set(0, 0), pTimerInfo->m_ullPeriod);
- Overruns = hrtimer_forward(pTimer_p, Now, Interval);
- if (Overruns > 1) {
- printk
- ("EplTimerHighResk: Continuous timer (handle 0x%lX) had to skip %lu interval(s)!\n",
- pTimerInfo->m_EventArg.m_TimerHdl, Overruns - 1);
- }
-#else
- pTimer_p->expires = ktime_add_ns(pTimer_p->expires,
- pTimerInfo->m_ullPeriod);
-#endif
-
- Ret = HRTIMER_RESTART;
- }
-
- Exit:
- BENCHMARK_MOD_24_RESET(4);
- return Ret;
-}