forked from Imagelibrary/rtems
leon, grcan: use RTEMS 4.12 SMP interrupt lock
This commit is contained in:
committed by
Daniel Hellstrom
parent
bc40b4def8
commit
7b8a920a27
@@ -22,6 +22,32 @@
|
|||||||
#include <drvmgr/ambapp_bus.h>
|
#include <drvmgr/ambapp_bus.h>
|
||||||
#include <ambapp.h>
|
#include <ambapp.h>
|
||||||
|
|
||||||
|
#if (((__RTEMS_MAJOR__ << 16) | (__RTEMS_MINOR__ << 8) | __RTEMS_REVISION__) >= 0x040b63)
|
||||||
|
|
||||||
|
/* Spin locks mapped via rtems_interrupt_lock_* API: */
|
||||||
|
#define SPIN_DECLARE(lock) RTEMS_INTERRUPT_LOCK_MEMBER(lock)
|
||||||
|
#define SPIN_INIT(lock, name) rtems_interrupt_lock_initialize(lock, name)
|
||||||
|
#define SPIN_LOCK(lock, level) rtems_interrupt_lock_acquire_isr(lock, &level)
|
||||||
|
#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_lock_acquire(lock, &level)
|
||||||
|
#define SPIN_UNLOCK(lock, level) rtems_interrupt_lock_release_isr(lock, &level)
|
||||||
|
#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_lock_release(lock, &level)
|
||||||
|
#define SPIN_IRQFLAGS(k) rtems_interrupt_lock_context k
|
||||||
|
#define SPIN_ISR_IRQFLAGS(k) SPIN_IRQFLAGS(k)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* maintain compatibility with older versions of RTEMS: */
|
||||||
|
#define SPIN_DECLARE(name)
|
||||||
|
#define SPIN_INIT(lock, name)
|
||||||
|
#define SPIN_LOCK(lock, level)
|
||||||
|
#define SPIN_LOCK_IRQ(lock, level) rtems_interrupt_disable(level)
|
||||||
|
#define SPIN_UNLOCK(lock, level)
|
||||||
|
#define SPIN_UNLOCK_IRQ(lock, level) rtems_interrupt_enable(level)
|
||||||
|
#define SPIN_IRQFLAGS(k) rtems_interrupt_level k
|
||||||
|
#define SPIN_ISR_IRQFLAGS(k)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Maximum number of GRCAN devices supported by driver */
|
/* Maximum number of GRCAN devices supported by driver */
|
||||||
#define GRCAN_COUNT_MAX 8
|
#define GRCAN_COUNT_MAX 8
|
||||||
|
|
||||||
@@ -43,18 +69,6 @@
|
|||||||
#define RX_BUF_SIZE ((3*BLOCK_SIZE)*16)
|
#define RX_BUF_SIZE ((3*BLOCK_SIZE)*16)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef IRQ_GLOBAL_PREPARE
|
|
||||||
#define IRQ_GLOBAL_PREPARE(level) rtems_interrupt_level level
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef IRQ_GLOBAL_DISABLE
|
|
||||||
#define IRQ_GLOBAL_DISABLE(level) rtems_interrupt_disable(level)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef IRQ_GLOBAL_ENABLE
|
|
||||||
#define IRQ_GLOBAL_ENABLE(level) rtems_interrupt_enable(level)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef IRQ_CLEAR_PENDING
|
#ifndef IRQ_CLEAR_PENDING
|
||||||
#define IRQ_CLEAR_PENDING(irqno)
|
#define IRQ_CLEAR_PENDING(irqno)
|
||||||
#endif
|
#endif
|
||||||
@@ -137,6 +151,7 @@ struct grcan_priv {
|
|||||||
struct grcan_stats stats;
|
struct grcan_stats stats;
|
||||||
|
|
||||||
rtems_id rx_sem, tx_sem, txempty_sem, dev_sem;
|
rtems_id rx_sem, tx_sem, txempty_sem, dev_sem;
|
||||||
|
SPIN_DECLARE(devlock);
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __inline__ grcan_hw_reset(struct grcan_regs *regs);
|
static void __inline__ grcan_hw_reset(struct grcan_regs *regs);
|
||||||
@@ -384,7 +399,7 @@ static rtems_device_driver grcan_hw_start(struct grcan_priv *pDev)
|
|||||||
*/
|
*/
|
||||||
unsigned int tmp RTEMS_UNUSED;
|
unsigned int tmp RTEMS_UNUSED;
|
||||||
|
|
||||||
IRQ_GLOBAL_PREPARE(oldLevel);
|
SPIN_IRQFLAGS(oldLevel);
|
||||||
|
|
||||||
FUNCDBG();
|
FUNCDBG();
|
||||||
|
|
||||||
@@ -428,11 +443,11 @@ static rtems_device_driver grcan_hw_start(struct grcan_priv *pDev)
|
|||||||
pDev->regs->imr = 0x1601f;
|
pDev->regs->imr = 0x1601f;
|
||||||
|
|
||||||
/* Enable routing of the IRQs */
|
/* Enable routing of the IRQs */
|
||||||
IRQ_GLOBAL_DISABLE(oldLevel);
|
SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
|
||||||
IRQ_UNMASK(pDev->irq + GRCAN_IRQ_TXSYNC);
|
IRQ_UNMASK(pDev->irq + GRCAN_IRQ_TXSYNC);
|
||||||
IRQ_UNMASK(pDev->irq + GRCAN_IRQ_RXSYNC);
|
IRQ_UNMASK(pDev->irq + GRCAN_IRQ_RXSYNC);
|
||||||
IRQ_UNMASK(pDev->irq + GRCAN_IRQ_IRQ);
|
IRQ_UNMASK(pDev->irq + GRCAN_IRQ_IRQ);
|
||||||
IRQ_GLOBAL_ENABLE(oldLevel);
|
SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
|
||||||
|
|
||||||
/* Reset some software data */
|
/* Reset some software data */
|
||||||
/*pDev->txerror = 0;
|
/*pDev->txerror = 0;
|
||||||
@@ -868,7 +883,7 @@ static int grcan_wait_rxdata(struct grcan_priv *pDev, int min)
|
|||||||
unsigned int wp, rp, size, irq;
|
unsigned int wp, rp, size, irq;
|
||||||
unsigned int irq_trunk, dataavail;
|
unsigned int irq_trunk, dataavail;
|
||||||
int wait;
|
int wait;
|
||||||
IRQ_GLOBAL_PREPARE(oldLevel);
|
SPIN_IRQFLAGS(oldLevel);
|
||||||
|
|
||||||
FUNCDBG();
|
FUNCDBG();
|
||||||
|
|
||||||
@@ -876,7 +891,7 @@ static int grcan_wait_rxdata(struct grcan_priv *pDev, int min)
|
|||||||
* Set up a valid IRQ point so that an IRQ is received
|
* Set up a valid IRQ point so that an IRQ is received
|
||||||
* when one or more messages are received
|
* when one or more messages are received
|
||||||
*/
|
*/
|
||||||
IRQ_GLOBAL_DISABLE(oldLevel);
|
SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
|
||||||
|
|
||||||
size = READ_REG(&pDev->regs->rx0size);
|
size = READ_REG(&pDev->regs->rx0size);
|
||||||
rp = READ_REG(&pDev->regs->rx0rd);
|
rp = READ_REG(&pDev->regs->rx0rd);
|
||||||
@@ -909,7 +924,7 @@ static int grcan_wait_rxdata(struct grcan_priv *pDev, int min)
|
|||||||
/* enough message has been received, abort sleep - don't unmask interrupt */
|
/* enough message has been received, abort sleep - don't unmask interrupt */
|
||||||
wait = 0;
|
wait = 0;
|
||||||
}
|
}
|
||||||
IRQ_GLOBAL_ENABLE(oldLevel);
|
SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
|
||||||
|
|
||||||
/* Wait for IRQ to fire only if has been triggered */
|
/* Wait for IRQ to fire only if has been triggered */
|
||||||
if (wait) {
|
if (wait) {
|
||||||
@@ -938,12 +953,12 @@ static int grcan_wait_txspace(struct grcan_priv *pDev, int min)
|
|||||||
int wait;
|
int wait;
|
||||||
unsigned int irq, rp, wp, size, space_left;
|
unsigned int irq, rp, wp, size, space_left;
|
||||||
unsigned int irq_trunk;
|
unsigned int irq_trunk;
|
||||||
IRQ_GLOBAL_PREPARE(oldLevel);
|
SPIN_IRQFLAGS(oldLevel);
|
||||||
|
|
||||||
DBGC(DBG_TX, "\n");
|
DBGC(DBG_TX, "\n");
|
||||||
/*FUNCDBG(); */
|
/*FUNCDBG(); */
|
||||||
|
|
||||||
IRQ_GLOBAL_DISABLE(oldLevel);
|
SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
|
||||||
|
|
||||||
pDev->regs->tx0ctrl = GRCAN_TXCTRL_ENABLE;
|
pDev->regs->tx0ctrl = GRCAN_TXCTRL_ENABLE;
|
||||||
|
|
||||||
@@ -985,7 +1000,7 @@ static int grcan_wait_txspace(struct grcan_priv *pDev, int min)
|
|||||||
/* There are enough room in buffer, abort wait - don't unmask interrupt */
|
/* There are enough room in buffer, abort wait - don't unmask interrupt */
|
||||||
wait = 0;
|
wait = 0;
|
||||||
}
|
}
|
||||||
IRQ_GLOBAL_ENABLE(oldLevel);
|
SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
|
||||||
|
|
||||||
/* Wait for IRQ to fire only if it has been triggered */
|
/* Wait for IRQ to fire only if it has been triggered */
|
||||||
if (wait) {
|
if (wait) {
|
||||||
@@ -1005,7 +1020,7 @@ static int grcan_tx_flush(struct grcan_priv *pDev)
|
|||||||
{
|
{
|
||||||
int wait;
|
int wait;
|
||||||
unsigned int rp, wp;
|
unsigned int rp, wp;
|
||||||
IRQ_GLOBAL_PREPARE(oldLevel);
|
SPIN_IRQFLAGS(oldLevel);
|
||||||
FUNCDBG();
|
FUNCDBG();
|
||||||
|
|
||||||
/* loop until all data in circular buffer has been read by hw.
|
/* loop until all data in circular buffer has been read by hw.
|
||||||
@@ -1018,7 +1033,7 @@ static int grcan_tx_flush(struct grcan_priv *pDev)
|
|||||||
(rp = READ_REG(&pDev->regs->tx0rd))
|
(rp = READ_REG(&pDev->regs->tx0rd))
|
||||||
) {
|
) {
|
||||||
/* Wait for TX empty IRQ */
|
/* Wait for TX empty IRQ */
|
||||||
IRQ_GLOBAL_DISABLE(oldLevel);
|
SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
|
||||||
/* Clear pending TXEmpty IRQ */
|
/* Clear pending TXEmpty IRQ */
|
||||||
pDev->regs->picr = GRCAN_TXEMPTY_IRQ;
|
pDev->regs->picr = GRCAN_TXEMPTY_IRQ;
|
||||||
|
|
||||||
@@ -1031,7 +1046,7 @@ static int grcan_tx_flush(struct grcan_priv *pDev)
|
|||||||
/* TX fifo is empty */
|
/* TX fifo is empty */
|
||||||
wait = 0;
|
wait = 0;
|
||||||
}
|
}
|
||||||
IRQ_GLOBAL_ENABLE(oldLevel);
|
SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
|
||||||
if (!wait)
|
if (!wait)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1188,6 +1203,8 @@ void *grcan_open(int dev_no)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SPIN_INIT(&pDev->devlock, pDev->devName);
|
||||||
|
|
||||||
/* Mark device taken */
|
/* Mark device taken */
|
||||||
pDev->open = 1;
|
pDev->open = 1;
|
||||||
|
|
||||||
@@ -1609,13 +1626,13 @@ int grcan_get_stats(void *d, struct grcan_stats *stats)
|
|||||||
int grcan_clr_stats(void *d)
|
int grcan_clr_stats(void *d)
|
||||||
{
|
{
|
||||||
struct grcan_priv *pDev = d;
|
struct grcan_priv *pDev = d;
|
||||||
IRQ_GLOBAL_PREPARE(oldLevel);
|
SPIN_IRQFLAGS(oldLevel);
|
||||||
|
|
||||||
FUNCDBG();
|
FUNCDBG();
|
||||||
|
|
||||||
IRQ_GLOBAL_DISABLE(oldLevel);
|
SPIN_LOCK_IRQ(&pDev->devlock, oldLevel);
|
||||||
memset(&pDev->stats,0,sizeof(struct grcan_stats));
|
memset(&pDev->stats,0,sizeof(struct grcan_stats));
|
||||||
IRQ_GLOBAL_ENABLE(oldLevel);
|
SPIN_UNLOCK_IRQ(&pDev->devlock, oldLevel);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user