summaryrefslogtreecommitdiffstats
path: root/drivers/mailbox
diff options
context:
space:
mode:
authorRob Rice <rob.rice@broadcom.com>2016-11-14 13:26:01 -0500
committerJassi Brar <jaswinder.singh@linaro.org>2016-12-19 09:40:21 -0500
commit8aef00f090bcbe5237c5a6628e7c000890267efe (patch)
treea388b78ba634615cbabcb38956c7c39040bcec83 /drivers/mailbox
parent7493cde34efc28641c295ee0d52ab9d790853c62 (diff)
mailbox: bcm-pdc: Convert from threaded IRQ to tasklet
Previously used threaded IRQs in the PDC driver to defer processing the rx DMA ring after getting an rx done interrupt. Instead, use a tasklet at normal priority for deferred processing. Signed-off-by: Rob Rice <rob.rice@broadcom.com> Reviewed-by: Andy Gospodarek <gospo@broadcom.com> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Diffstat (limited to 'drivers/mailbox')
-rw-r--r--drivers/mailbox/bcm-pdc-mailbox.c57
1 files changed, 25 insertions, 32 deletions
diff --git a/drivers/mailbox/bcm-pdc-mailbox.c b/drivers/mailbox/bcm-pdc-mailbox.c
index 7ed3f0247cb8..16e544018a68 100644
--- a/drivers/mailbox/bcm-pdc-mailbox.c
+++ b/drivers/mailbox/bcm-pdc-mailbox.c
@@ -285,6 +285,9 @@ struct pdc_state {
285 */ 285 */
286 unsigned long intstatus; 286 unsigned long intstatus;
287 287
288 /* tasklet for deferred processing after DMA rx interrupt */
289 struct tasklet_struct rx_tasklet;
290
288 /* Number of bytes of receive status prior to each rx frame */ 291 /* Number of bytes of receive status prior to each rx frame */
289 u32 rx_status_len; 292 u32 rx_status_len;
290 /* Whether a BCM header is prepended to each frame */ 293 /* Whether a BCM header is prepended to each frame */
@@ -931,7 +934,7 @@ static int pdc_rx_list_sg_add(struct pdc_state *pdcs, struct scatterlist *sg)
931/** 934/**
932 * pdc_irq_handler() - Interrupt handler called in interrupt context. 935 * pdc_irq_handler() - Interrupt handler called in interrupt context.
933 * @irq: Interrupt number that has fired 936 * @irq: Interrupt number that has fired
934 * @cookie: PDC state for DMA engine that generated the interrupt 937 * @data: device struct for DMA engine that generated the interrupt
935 * 938 *
936 * We have to clear the device interrupt status flags here. So cache the 939 * We have to clear the device interrupt status flags here. So cache the
937 * status for later use in the thread function. Other than that, just return 940 * status for later use in the thread function. Other than that, just return
@@ -940,9 +943,10 @@ static int pdc_rx_list_sg_add(struct pdc_state *pdcs, struct scatterlist *sg)
940 * Return: IRQ_WAKE_THREAD if interrupt is ours 943 * Return: IRQ_WAKE_THREAD if interrupt is ours
941 * IRQ_NONE otherwise 944 * IRQ_NONE otherwise
942 */ 945 */
943static irqreturn_t pdc_irq_handler(int irq, void *cookie) 946static irqreturn_t pdc_irq_handler(int irq, void *data)
944{ 947{
945 struct pdc_state *pdcs = cookie; 948 struct device *dev = (struct device *)data;
949 struct pdc_state *pdcs = dev_get_drvdata(dev);
946 u32 intstatus = ioread32(pdcs->pdc_reg_vbase + PDC_INTSTATUS_OFFSET); 950 u32 intstatus = ioread32(pdcs->pdc_reg_vbase + PDC_INTSTATUS_OFFSET);
947 951
948 if (likely(intstatus & PDC_RCVINTEN_0)) 952 if (likely(intstatus & PDC_RCVINTEN_0))
@@ -952,39 +956,22 @@ static irqreturn_t pdc_irq_handler(int irq, void *cookie)
952 iowrite32(intstatus, pdcs->pdc_reg_vbase + PDC_INTSTATUS_OFFSET); 956 iowrite32(intstatus, pdcs->pdc_reg_vbase + PDC_INTSTATUS_OFFSET);
953 957
954 /* Wakeup IRQ thread */ 958 /* Wakeup IRQ thread */
955 if (likely(pdcs && (irq == pdcs->pdc_irq) && (intstatus & PDC_INTMASK))) 959 if (likely(pdcs && (irq == pdcs->pdc_irq) &&
956 return IRQ_WAKE_THREAD; 960 (intstatus & PDC_INTMASK))) {
957 961 tasklet_schedule(&pdcs->rx_tasklet);
962 return IRQ_HANDLED;
963 }
958 return IRQ_NONE; 964 return IRQ_NONE;
959} 965}
960 966
961/** 967static void pdc_tasklet_cb(unsigned long data)
962 * pdc_irq_thread() - Function invoked on deferred thread when data is available
963 * to receive.
964 * @irq: Interrupt number
965 * @cookie: PDC state for PDC that generated the interrupt
966 *
967 * On DMA rx complete, process as many SPU response messages as are available
968 * and send each to the mailbox client.
969 *
970 * Return: IRQ_HANDLED if we recognized and handled the interrupt
971 * IRQ_NONE otherwise
972 */
973static irqreturn_t pdc_irq_thread(int irq, void *cookie)
974{ 968{
975 struct pdc_state *pdcs = cookie; 969 struct pdc_state *pdcs = (struct pdc_state *)data;
976 bool rx_int; 970 bool rx_int;
977 971
978 rx_int = test_and_clear_bit(PDC_RCVINT_0, &pdcs->intstatus); 972 rx_int = test_and_clear_bit(PDC_RCVINT_0, &pdcs->intstatus);
979 if (likely(pdcs && rx_int)) { 973 if (likely(pdcs && rx_int))
980 dev_dbg(&pdcs->pdev->dev,
981 "%s() got irq %d with rx_int %s",
982 __func__, irq, rx_int ? "set" : "clear");
983
984 pdc_receive(pdcs); 974 pdc_receive(pdcs);
985 return IRQ_HANDLED;
986 }
987 return IRQ_NONE;
988} 975}
989 976
990/** 977/**
@@ -1416,11 +1403,11 @@ static int pdc_interrupts_init(struct pdc_state *pdcs)
1416 pdcs->pdc_irq = irq_of_parse_and_map(dn, 0); 1403 pdcs->pdc_irq = irq_of_parse_and_map(dn, 0);
1417 dev_dbg(dev, "pdc device %s irq %u for pdcs %p", 1404 dev_dbg(dev, "pdc device %s irq %u for pdcs %p",
1418 dev_name(dev), pdcs->pdc_irq, pdcs); 1405 dev_name(dev), pdcs->pdc_irq, pdcs);
1419 err = devm_request_threaded_irq(dev, pdcs->pdc_irq, 1406
1420 pdc_irq_handler, 1407 err = devm_request_irq(dev, pdcs->pdc_irq, pdc_irq_handler, 0,
1421 pdc_irq_thread, 0, dev_name(dev), pdcs); 1408 dev_name(dev), dev);
1422 if (err) { 1409 if (err) {
1423 dev_err(dev, "threaded tx IRQ %u request failed with err %d\n", 1410 dev_err(dev, "IRQ %u request failed with err %d\n",
1424 pdcs->pdc_irq, err); 1411 pdcs->pdc_irq, err);
1425 return err; 1412 return err;
1426 } 1413 }
@@ -1579,6 +1566,9 @@ static int pdc_probe(struct platform_device *pdev)
1579 1566
1580 pdc_hw_init(pdcs); 1567 pdc_hw_init(pdcs);
1581 1568
1569 /* Init tasklet for deferred DMA rx processing */
1570 tasklet_init(&pdcs->rx_tasklet, pdc_tasklet_cb, (unsigned long) pdcs);
1571
1582 err = pdc_interrupts_init(pdcs); 1572 err = pdc_interrupts_init(pdcs);
1583 if (err) 1573 if (err)
1584 goto cleanup_buf_pool; 1574 goto cleanup_buf_pool;
@@ -1595,6 +1585,7 @@ static int pdc_probe(struct platform_device *pdev)
1595 return PDC_SUCCESS; 1585 return PDC_SUCCESS;
1596 1586
1597cleanup_buf_pool: 1587cleanup_buf_pool:
1588 tasklet_kill(&pdcs->rx_tasklet);
1598 dma_pool_destroy(pdcs->rx_buf_pool); 1589 dma_pool_destroy(pdcs->rx_buf_pool);
1599 1590
1600cleanup_ring_pool: 1591cleanup_ring_pool:
@@ -1610,6 +1601,8 @@ static int pdc_remove(struct platform_device *pdev)
1610 1601
1611 pdc_free_debugfs(); 1602 pdc_free_debugfs();
1612 1603
1604 tasklet_kill(&pdcs->rx_tasklet);
1605
1613 pdc_hw_disable(pdcs); 1606 pdc_hw_disable(pdcs);
1614 1607
1615 mbox_controller_unregister(&pdcs->mbc); 1608 mbox_controller_unregister(&pdcs->mbc);