Files
2026-07-30 11:19:44 +05:30

189 lines
4.6 KiB
C

/****************************************************************************
* sec2_io.c -- bus operations for SEC2 Driver
****************************************************************************
* Copyright (c) Certicom Corp. 1996-2002. All rights reserved
* Copyright (c) 2003, 2004 Freescale Semiconductor
* All Rights Reserved. Proprietary and Confidential.
*
* NOTICE: The information contained in this file is proprietary
* to Freescale Semiconductor, and is being made available to
* Freescale's customers under strict license agreements.
* Use or disclosure of this information is permissible only
* under the terms of the existing license agreement.
***************************************************************************/
/* Revision History:
* 1.0 Aug 24,2003 dgs adapted from the final version of mpc18x
* May 12,2004 sec - switched core interrupt for 8555 configuration
* 1.1.0 Dec 05,2004 sec - merge in linux support from prior versions
* 1.1.1 Dec 16,2004 sec - remove lock variable, remove old diagnostics
* 1.2 Jan 27,2005
*/
#include "Sec2Driver.h"
#ifdef __KERNEL__
extern void InterruptServiceRoutine(int irq, void *dev_id, struct pt_regs *pt_regs);
#endif
#ifdef VXWORKS
#include "intLib.h"
IO_STATUS IOInitQs()
{
/* set up ISR/ProcessingComplete message queue */
IsrMsgQId = msgQCreate(MAX_MESSAGES, sizeof(DEVICE_REGS), MSG_Q_FIFO);
if (IsrMsgQId == NULL)
return SEC2_VXWORKS_CANNOT_CREATE_QUEUE;
return SEC2_SUCCESS;
}
IO_STATUS IORegisterDriver()
{
/* start ProcessComplete task, with high priority */
if (taskSpawn ("tSEC2_pc",
PROCESSING_COMPLETE_PRIORITY,
0,
PROCESSING_COMPLETE_STACKSIZE,
(FUNCPTR)ProcessingComplete,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0) == TASK_ID_ERROR)
return (SEC2_UNKNOWN_ERROR);
/* add the driver to the driver table */
driverNum = iosDrvInstall(SEC2Open, NULL, SEC2Open, SEC2Close, NULL, NULL, SEC2_ioctl);
if (driverNum < 0)
return (SEC2_IO_VXWORKS_DRIVER_TABLE_ADD_ERROR);
(void) iosDevAdd(&vxworksDrvDev, vxworksDrvName, driverNum);
return (SEC2_SUCCESS);
}
#endif
void IOInitSemaphores()
{
/* initialize semaphores */
#ifdef VXWORKS
ChannelAssignSemId = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
QueueSemId = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
#endif
#ifdef __KERNEL__
spin_lock_init(&ChannelAssignLock);
spin_lock_init(&QueueLock);
#endif
}
/*
* IOConnectInterrupt()
*/
#ifdef VXWORKS
/* the Interrupt connect should be moved to sysLib.c since it is board dependent */
IO_STATUS IOConnectInterrupt()
{
/* Interpeak begin */
int inum_sec2;
extern int ipfreescale_sec_inum(void);
inum_sec2 = ipfreescale_sec_inum();
/* Install our IRQ handler */
if (intConnect(INUM_TO_IVEC(inum_sec2),
(VOIDFUNCPTR)InterruptServiceRoutine,
(int)NULL) == ERROR)
return(ERROR);
/* Enable the handler at the controller level */
intEnable(inum_sec2);
/* Interpeak end */
SEC2Dump(DBGTXT_INITDEV, ("IOConnectInterrupt ISR connected\n"));
return(SEC2_SUCCESS);
}
#endif
#ifdef __KERNEL__
IO_STATUS IOConnectInterrupt()
{
if ((request_irq(MPC85xx_IRQ_SEC, InterruptServiceRoutine, 0, "mpc-sec", NULL)) != 0)
return -1;
return (SEC2_SUCCESS);
}
#endif
#ifdef __KERNEL__
#include <linux/sched.h>
#include <asm/atomic.h>
#include <asm/semaphore.h>
unsigned long irq_flag; /* here for spin locks to use */
static inline int __sem_update_count(struct semaphore *sem, int incr)
{
int old_count, tmp;
__asm__ __volatile__("\n"
"1: lwarx %0,0,%3\n"
" srawi %0,%0,31\n"
" andc %1,%0,%1\n"
" add %1,%1,%4\n"
PPC405_ERR77(0,%3)
" stwcx. %1,0,%3\n"
" bne 1b"
: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
: "r" (&sem->count), "r" (incr), "m" (sem->count)
: "cc");
return old_count;
}
long __down_interruptible_timeout(struct semaphore *sem, long timeout)
{
int retval = 0;
struct task_struct *tsk = current;
DECLARE_WAITQUEUE(wait, tsk);
tsk->state = TASK_INTERRUPTIBLE;
add_wait_queue_exclusive(&sem->wait, &wait);
smp_wmb();
while (__sem_update_count(sem, -1) <= 0) {
if (signal_pending(current)) {
__sem_update_count(sem, 0);
retval = -EINTR;
break;
}
timeout = schedule_timeout(timeout);
tsk->state = TASK_INTERRUPTIBLE;
}
tsk->state = TASK_RUNNING;
remove_wait_queue(&sem->wait, &wait);
wake_up(&sem->wait);
return timeout >= 0 ? 0 : -1;
}
#endif