summaryrefslogtreecommitdiffstats
path: root/drivers/mailbox
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mailbox')
-rw-r--r--drivers/mailbox/bcm-pdc-mailbox.c38
1 files changed, 13 insertions, 25 deletions
diff --git a/drivers/mailbox/bcm-pdc-mailbox.c b/drivers/mailbox/bcm-pdc-mailbox.c
index 8c2aa7c9c27f..c1ec17cfa03a 100644
--- a/drivers/mailbox/bcm-pdc-mailbox.c
+++ b/drivers/mailbox/bcm-pdc-mailbox.c
@@ -298,14 +298,6 @@ struct pdc_state {
298 298
299 unsigned int pdc_irq; 299 unsigned int pdc_irq;
300 300
301 /*
302 * Last interrupt status read from PDC device. Saved in interrupt
303 * handler so the handler can clear the interrupt in the device,
304 * and the interrupt thread called later can know which interrupt
305 * bits are active.
306 */
307 unsigned long intstatus;
308
309 /* tasklet for deferred processing after DMA rx interrupt */ 301 /* tasklet for deferred processing after DMA rx interrupt */
310 struct tasklet_struct rx_tasklet; 302 struct tasklet_struct rx_tasklet;
311 303
@@ -955,32 +947,30 @@ static irqreturn_t pdc_irq_handler(int irq, void *data)
955 struct pdc_state *pdcs = dev_get_drvdata(dev); 947 struct pdc_state *pdcs = dev_get_drvdata(dev);
956 u32 intstatus = ioread32(pdcs->pdc_reg_vbase + PDC_INTSTATUS_OFFSET); 948 u32 intstatus = ioread32(pdcs->pdc_reg_vbase + PDC_INTSTATUS_OFFSET);
957 949
958 if (likely(intstatus & PDC_RCVINTEN_0)) 950 if (unlikely(intstatus == 0))
959 set_bit(PDC_RCVINT_0, &pdcs->intstatus); 951 return IRQ_NONE;
960
961 /* Clear interrupt flags in device */
962 iowrite32(intstatus, pdcs->pdc_reg_vbase + PDC_INTSTATUS_OFFSET);
963 952
964 /* Disable interrupts until soft handler runs */ 953 /* Disable interrupts until soft handler runs */
965 iowrite32(0, pdcs->pdc_reg_vbase + PDC_INTMASK_OFFSET); 954 iowrite32(0, pdcs->pdc_reg_vbase + PDC_INTMASK_OFFSET);
966 955
956 /* Clear interrupt flags in device */
957 iowrite32(intstatus, pdcs->pdc_reg_vbase + PDC_INTSTATUS_OFFSET);
958
967 /* Wakeup IRQ thread */ 959 /* Wakeup IRQ thread */
968 if (likely(pdcs && (irq == pdcs->pdc_irq) && 960 tasklet_schedule(&pdcs->rx_tasklet);
969 (intstatus & PDC_INTMASK))) { 961 return IRQ_HANDLED;
970 tasklet_schedule(&pdcs->rx_tasklet);
971 return IRQ_HANDLED;
972 }
973 return IRQ_NONE;
974} 962}
975 963
964/**
965 * pdc_tasklet_cb() - Tasklet callback that runs the deferred processing after
966 * a DMA receive interrupt. Reenables the receive interrupt.
967 * @data: PDC state structure
968 */
976static void pdc_tasklet_cb(unsigned long data) 969static void pdc_tasklet_cb(unsigned long data)
977{ 970{
978 struct pdc_state *pdcs = (struct pdc_state *)data; 971 struct pdc_state *pdcs = (struct pdc_state *)data;
979 bool rx_int;
980 972
981 rx_int = test_and_clear_bit(PDC_RCVINT_0, &pdcs->intstatus); 973 pdc_receive(pdcs);
982 if (likely(pdcs && rx_int))
983 pdc_receive(pdcs);
984 974
985 /* reenable interrupts */ 975 /* reenable interrupts */
986 iowrite32(PDC_INTMASK, pdcs->pdc_reg_vbase + PDC_INTMASK_OFFSET); 976 iowrite32(PDC_INTMASK, pdcs->pdc_reg_vbase + PDC_INTMASK_OFFSET);
@@ -1405,8 +1395,6 @@ static int pdc_interrupts_init(struct pdc_state *pdcs)
1405 struct device_node *dn = pdev->dev.of_node; 1395 struct device_node *dn = pdev->dev.of_node;
1406 int err; 1396 int err;
1407 1397
1408 pdcs->intstatus = 0;
1409
1410 /* interrupt configuration */ 1398 /* interrupt configuration */
1411 iowrite32(PDC_INTMASK, pdcs->pdc_reg_vbase + PDC_INTMASK_OFFSET); 1399 iowrite32(PDC_INTMASK, pdcs->pdc_reg_vbase + PDC_INTMASK_OFFSET);
1412 iowrite32(PDC_LAZY_INT, pdcs->pdc_reg_vbase + PDC_RCVLAZY0_OFFSET); 1400 iowrite32(PDC_LAZY_INT, pdcs->pdc_reg_vbase + PDC_RCVLAZY0_OFFSET);