summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc/shared/spw/grspw_pkt.c
diff options
context:
space:
mode:
authorDaniel Hellstrom <daniel@gaisler.com>2017-01-22 15:58:18 +0100
committerDaniel Hellstrom <daniel@gaisler.com>2017-03-06 07:54:55 +0100
commit94fb377bd92c7c0fbbfe76e60c513959e6e32f2d (patch)
tree3b6f18fe1b52459a820650cadbee7c55c69d3ee3 /c/src/lib/libbsp/sparc/shared/spw/grspw_pkt.c
parentleon, grpsw_pkt: set unique work-task name (diff)
downloadrtems-94fb377bd92c7c0fbbfe76e60c513959e6e32f2d.tar.bz2
leon, grspw_pkt: ISR RX/TX DMA interrupt source disable configurable
This patch introduces some new options to let the user control when the ISR shall disable DMA RX/TX interrupt. The ISR can be set in three modes when a RX/TX DMA interrupt is asserted: 1) ISR will always clear both RX/TX DMA interrupt enable. (DEFAULT). 2) ISR will never never RX or TX DMA interrupt enable, ISR will leave RX/TX DMA interrupt enable untouched. 3) ISR will clear the interrupt enable(s) causing the interrupt, this allows separate RX and TX IRQ handling. This patch is backwards compatible since default mode 1) is activated when the grspw_dma_config.flags DMAFLAGS2_IRQD field is 0.
Diffstat (limited to 'c/src/lib/libbsp/sparc/shared/spw/grspw_pkt.c')
-rw-r--r--c/src/lib/libbsp/sparc/shared/spw/grspw_pkt.c48
1 files changed, 37 insertions, 11 deletions
diff --git a/c/src/lib/libbsp/sparc/shared/spw/grspw_pkt.c b/c/src/lib/libbsp/sparc/shared/spw/grspw_pkt.c
index b64a807d99..6b5390fffd 100644
--- a/c/src/lib/libbsp/sparc/shared/spw/grspw_pkt.c
+++ b/c/src/lib/libbsp/sparc/shared/spw/grspw_pkt.c
@@ -2625,10 +2625,21 @@ static void grspw_work_dma_func(struct grspw_dma_priv *dma, unsigned int msg)
default:
break;
}
+ if (msg == 0)
+ return;
rx_cond_true = 0;
tx_cond_true = 0;
+ if ((dma->cfg.flags & DMAFLAG2_IRQD_MASK) == DMAFLAG2_IRQD_BOTH) {
+ /* In case both interrupt sources are disabled simultaneously
+ * by the ISR the re-enabling of the interrupt source must also
+ * do so to avoid missing interrupts. Both RX and TX process
+ * will be forced.
+ */
+ msg |= WORK_DMA_RX_MASK | WORK_DMA_TX_MASK;
+ }
+
if (msg & WORK_DMA_RX_MASK) {
/* Do RX Work */
@@ -2726,7 +2737,7 @@ STATIC void grspw_isr(void *data)
unsigned int dma_stat, stat, stat_clrmsk, ctrl, icctrl, timecode, irqs;
unsigned int rxirq, rxack, intto;
int i, handled = 0, call_user_int_isr;
- unsigned int message = WORK_NONE;
+ unsigned int message = WORK_NONE, dma_en;
#ifdef RTEMS_HAS_SMP
IRQFLAGS_TYPE irqflags;
#endif
@@ -2839,26 +2850,41 @@ STATIC void grspw_isr(void *data)
if (!irqs)
continue;
- /* Disable Further IRQs (until enabled again)
- * from this DMA channel. Let the status
- * bit remain so that they can be handled by
- * work function.
- */
- REG_WRITE(&priv->regs->dma[i].ctrl, dma_stat &
- ~(GRSPW_DMACTRL_RI|GRSPW_DMACTRL_TI|
- GRSPW_DMACTRL_PR|GRSPW_DMACTRL_PS|
- GRSPW_DMACTRL_RA|GRSPW_DMACTRL_TA|
- GRSPW_DMACTRL_AT));
handled = 1;
/* DMA error has priority, if error happens it is assumed that
* the common work-queue stops the DMA operation for that
* channel and makes the DMA tasks exit from their waiting
* functions (both RX and TX tasks).
+ *
+ * Disable Further IRQs (until enabled again)
+ * from this DMA channel. Let the status
+ * bit remain so that they can be handled by
+ * work function.
*/
if (irqs & GRSPW_DMA_STATUS_ERROR) {
+ REG_WRITE(&priv->regs->dma[i].ctrl, dma_stat &
+ ~(GRSPW_DMACTRL_RI | GRSPW_DMACTRL_TI |
+ GRSPW_DMACTRL_PR | GRSPW_DMACTRL_PS |
+ GRSPW_DMACTRL_RA | GRSPW_DMACTRL_TA |
+ GRSPW_DMACTRL_AT));
message |= WORK_DMA_ER(i);
} else {
+ /* determine if RX/TX interrupt source(s) shall remain
+ * enabled.
+ */
+ if (priv->dma[i].cfg.flags & DMAFLAG2_IRQD_SRC) {
+ dma_en = ~irqs >> 3;
+ } else {
+ dma_en = priv->dma[i].cfg.flags >>
+ (DMAFLAG2_IRQD_BIT - GRSPW_DMACTRL_TI_BIT);
+ }
+ dma_en &= (GRSPW_DMACTRL_RI | GRSPW_DMACTRL_TI);
+ REG_WRITE(&priv->regs->dma[i].ctrl, dma_stat &
+ (~(GRSPW_DMACTRL_RI | GRSPW_DMACTRL_TI |
+ GRSPW_DMACTRL_PR | GRSPW_DMACTRL_PS |
+ GRSPW_DMACTRL_RA | GRSPW_DMACTRL_TA |
+ GRSPW_DMACTRL_AT) | dma_en));
message |= WORK_DMA(i, irqs >> GRSPW_DMACTRL_PS_BIT);
}
}