Commit d6c7e5f8 authored by Andy Walls's avatar Andy Walls Committed by Mauro Carvalho Chehab

V4L/DVB (9725): cx18: Remove unnecessary MMIO accesses in time critical irq handling path

Remove unnecessary MMIO accesses in time critical irq handling path.  Also
ensured that the mailbox ack field is read in last, so we know for sure if we
have a stale mailbox or not on receipt.
Signed-off-by: default avatarAndy Walls <awalls@radix.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 3f75c616
......@@ -446,6 +446,10 @@ struct cx18 {
/* when the current DMA is finished this queue is woken up */
wait_queue_head_t dma_waitq;
u32 sw1_irq_mask;
u32 sw2_irq_mask;
u32 hw2_irq_mask;
struct cx18_epu_work_order epu_work_order[CX18_MAX_EPU_WORK_ORDERS];
char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */
......
......@@ -71,32 +71,28 @@ void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count)
void cx18_sw1_irq_enable(struct cx18 *cx, u32 val)
{
u32 r;
cx18_write_reg_expect(cx, val, SW1_INT_STATUS, ~val, val);
r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI);
cx18_write_reg(cx, r | val, SW1_INT_ENABLE_PCI);
cx->sw1_irq_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) | val;
cx18_write_reg(cx, cx->sw1_irq_mask, SW1_INT_ENABLE_PCI);
}
void cx18_sw1_irq_disable(struct cx18 *cx, u32 val)
{
u32 r;
r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI);
cx18_write_reg(cx, r & ~val, SW1_INT_ENABLE_PCI);
cx->sw1_irq_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) & ~val;
cx18_write_reg(cx, cx->sw1_irq_mask, SW1_INT_ENABLE_PCI);
}
void cx18_sw2_irq_enable(struct cx18 *cx, u32 val)
{
u32 r;
cx18_write_reg_expect(cx, val, SW2_INT_STATUS, ~val, val);
r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI);
cx18_write_reg(cx, r | val, SW2_INT_ENABLE_PCI);
cx->sw2_irq_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) | val;
cx18_write_reg(cx, cx->sw2_irq_mask, SW2_INT_ENABLE_PCI);
}
void cx18_sw2_irq_disable(struct cx18 *cx, u32 val)
{
u32 r;
r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI);
cx18_write_reg(cx, r & ~val, SW2_INT_ENABLE_PCI);
cx->sw2_irq_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) & ~val;
cx18_write_reg(cx, cx->sw2_irq_mask, SW2_INT_ENABLE_PCI);
}
void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val)
......
......@@ -44,16 +44,11 @@ static void epu_cmd(struct cx18 *cx, u32 sw1)
irqreturn_t cx18_irq_handler(int irq, void *dev_id)
{
struct cx18 *cx = (struct cx18 *)dev_id;
u32 sw1, sw1_mask;
u32 sw2, sw2_mask;
u32 hw2, hw2_mask;
u32 sw1, sw2, hw2;
sw1_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI);
sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & sw1_mask;
sw2_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI);
sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & sw2_mask;
hw2_mask = cx18_read_reg(cx, HW2_INT_MASK5_PCI);
hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & hw2_mask;
sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & cx->sw1_irq_mask;
sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & cx->sw2_irq_mask;
hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & cx->hw2_irq_mask;
if (sw1)
cx18_write_reg_expect(cx, sw1, SW1_INT_STATUS, ~sw1, sw1);
......
......@@ -399,7 +399,12 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
order->flags = 0;
order->rpu = rpu;
order_mb = &order->mb;
cx18_memcpy_fromio(cx, order_mb, mb, sizeof(struct cx18_mailbox));
/* mb->cmd and mb->args[0] through mb->args[2] */
cx18_memcpy_fromio(cx, &order_mb->cmd, &mb->cmd, 4 * sizeof(u32));
/* mb->request and mb->ack. N.B. we want to read mb->ack last */
cx18_memcpy_fromio(cx, &order_mb->request, &mb->request,
2 * sizeof(u32));
if (order_mb->request == order_mb->ack) {
CX18_WARN("Possibly falling behind: %s self-ack'ed our incoming"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment