189 lines
4.6 KiB
C
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
|