-/* Broadcom FlexRM Mailbox Driver
- *
+/*
* Copyright (C) 2017 Broadcom
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * Broadcom FlexRM Mailbox Driver
*
* Each Broadcom FlexSparx4 offload engine is implemented as an
* extension to Broadcom FlexRM ring manager. The FlexRM ring
err = flexrm_cmpl_desc_to_error(desc);
if (err < 0) {
dev_warn(ring->mbox->dev,
- "got completion desc=0x%lx with error %d",
- (unsigned long)desc, err);
+ "ring%d got completion desc=0x%lx with error %d\n",
+ ring->num, (unsigned long)desc, err);
}
/* Determine request id from completion descriptor */
msg = ring->requests[reqid];
if (!msg) {
dev_warn(ring->mbox->dev,
- "null msg pointer for completion desc=0x%lx",
- (unsigned long)desc);
+ "ring%d null msg pointer for completion desc=0x%lx\n",
+ ring->num, (unsigned long)desc);
continue;
}
ring->bd_base = dma_pool_alloc(ring->mbox->bd_pool,
GFP_KERNEL, &ring->bd_dma_base);
if (!ring->bd_base) {
- dev_err(ring->mbox->dev, "can't allocate BD memory\n");
+ dev_err(ring->mbox->dev,
+ "can't allocate BD memory for ring%d\n",
+ ring->num);
ret = -ENOMEM;
goto fail;
}
ring->cmpl_base = dma_pool_alloc(ring->mbox->cmpl_pool,
GFP_KERNEL, &ring->cmpl_dma_base);
if (!ring->cmpl_base) {
- dev_err(ring->mbox->dev, "can't allocate completion memory\n");
+ dev_err(ring->mbox->dev,
+ "can't allocate completion memory for ring%d\n",
+ ring->num);
ret = -ENOMEM;
goto fail_free_bd_memory;
}
/* Request IRQ */
if (ring->irq == UINT_MAX) {
- dev_err(ring->mbox->dev, "ring IRQ not available\n");
+ dev_err(ring->mbox->dev,
+ "ring%d IRQ not available\n", ring->num);
ret = -ENODEV;
goto fail_free_cmpl_memory;
}
flexrm_irq_thread,
0, dev_name(ring->mbox->dev), ring);
if (ret) {
- dev_err(ring->mbox->dev, "failed to request ring IRQ\n");
+ dev_err(ring->mbox->dev,
+ "failed to request ring%d IRQ\n", ring->num);
goto fail_free_cmpl_memory;
}
ring->irq_requested = true;
&ring->irq_aff_hint);
ret = irq_set_affinity_hint(ring->irq, &ring->irq_aff_hint);
if (ret) {
- dev_err(ring->mbox->dev, "failed to set IRQ affinity hint\n");
+ dev_err(ring->mbox->dev,
+ "failed to set IRQ affinity hint for ring%d\n",
+ ring->num);
goto fail_free_irq;
}
/* Disable/inactivate ring */
writel_relaxed(0x0, ring->regs + RING_CONTROL);
- /* Flush ring with timeout of 1s */
- timeout = 1000;
+ /* Set ring flush state */
+ timeout = 1000; /* timeout of 1s */
writel_relaxed(BIT(CONTROL_FLUSH_SHIFT),
ring->regs + RING_CONTROL);
do {
FLUSH_DONE_MASK)
break;
mdelay(1);
- } while (timeout--);
+ } while (--timeout);
+ if (!timeout)
+ dev_err(ring->mbox->dev,
+ "setting ring%d flush state timedout\n", ring->num);
+
+ /* Clear ring flush state */
+ timeout = 1000; /* timeout of 1s */
+ writel_relaxed(0x0, ring + RING_CONTROL);
+ do {
+ if (!(readl_relaxed(ring + RING_FLUSH_DONE) &
+ FLUSH_DONE_MASK))
+ break;
+ mdelay(1);
+ } while (--timeout);
+ if (!timeout)
+ dev_err(ring->mbox->dev,
+ "clearing ring%d flush state timedout\n", ring->num);
/* Abort all in-flight requests */
for (reqid = 0; reqid < RING_MAX_REQ_COUNT; reqid++) {
#define MBOX_HEXDUMP_MAX_LEN (MBOX_HEXDUMP_LINE_LEN * \
(MBOX_MAX_MSG_LEN / MBOX_BYTES_PER_LINE))
+static bool mbox_data_ready;
static struct dentry *root_debugfs_dir;
struct mbox_test_device {
static bool mbox_test_message_data_ready(struct mbox_test_device *tdev)
{
- unsigned char data;
+ bool data_ready;
unsigned long flags;
spin_lock_irqsave(&tdev->lock, flags);
- data = tdev->rx_buffer[0];
+ data_ready = mbox_data_ready;
spin_unlock_irqrestore(&tdev->lock, flags);
- if (data != '\0')
- return true;
- return false;
+ return data_ready;
}
static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf,
*(touser + l) = '\0';
memset(tdev->rx_buffer, 0, MBOX_MAX_MSG_LEN);
+ mbox_data_ready = false;
spin_unlock_irqrestore(&tdev->lock, flags);
message, MBOX_MAX_MSG_LEN);
memcpy(tdev->rx_buffer, message, MBOX_MAX_MSG_LEN);
}
+ mbox_data_ready = true;
spin_unlock_irqrestore(&tdev->lock, flags);
wake_up_interruptible(&tdev->waitq);