Skip to content

Commit

Permalink
Merge tag 'mailbox-v4.15' of git://git.linaro.org/landing-teams/worki…
Browse files Browse the repository at this point in the history
…ng/fujitsu/integration

Pull mailbox updates from Jassi Brar:
 "Change to POLL api and fixes for FlexRM and OMAP driver.

  Summary:

   - Core: Prefer ACK method over POLL, if both supported

   - Test: use flag instead of special character

   - FlexRM: Usual driver internal minor churn

   - Omap: fix error path"

* tag 'mailbox-v4.15' of git://git.linaro.org/landing-teams/working/fujitsu/integration:
  mailbox/omap: unregister mbox class
  mailbox: mailbox-test: don't rely on rx_buffer content to signal data ready
  mailbox: reset txdone_method TXDONE_BY_POLL if client knows_txdone
  mailbox: Build Broadcom FlexRM driver as loadable module for iProc SOCs
  mailbox: bcm-flexrm-mailbox: Use common GPL comment header
  mailbox: bcm-flexrm-mailbox: add depends on ARCH_BCM_IPROC
  mailbox: bcm-flexrm-mailbox: Print ring number in errors and warnings
  mailbox: bcm-flexrm-mailbox: Fix FlexRM ring flush sequence
  • Loading branch information
torvalds committed Nov 15, 2017
2 parents 19b9aaf + 1f90a21 commit 3c18767
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 28 deletions.
3 changes: 2 additions & 1 deletion drivers/mailbox/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,10 @@ config BCM_PDC_MBOX
config BCM_FLEXRM_MBOX
tristate "Broadcom FlexRM Mailbox"
depends on ARM64
depends on ARCH_BCM_IPROC || COMPILE_TEST
depends on HAS_DMA
select GENERIC_MSI_IRQ_DOMAIN
default ARCH_BCM_IPROC
default m if ARCH_BCM_IPROC
help
Mailbox implementation of the Broadcom FlexRM ring manager,
which provides access to various offload engines on Broadcom
Expand Down
66 changes: 49 additions & 17 deletions drivers/mailbox/bcm-flexrm-mailbox.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
/* 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
Expand Down Expand Up @@ -1116,8 +1124,8 @@ static int flexrm_process_completions(struct flexrm_ring *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 */
Expand All @@ -1127,8 +1135,8 @@ static int flexrm_process_completions(struct flexrm_ring *ring)
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;
}

Expand Down Expand Up @@ -1238,7 +1246,9 @@ static int flexrm_startup(struct mbox_chan *chan)
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;
}
Expand All @@ -1261,15 +1271,18 @@ static int flexrm_startup(struct mbox_chan *chan)
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;
}
memset(ring->cmpl_base, 0, RING_CMPL_SIZE);

/* 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;
}
Expand All @@ -1278,7 +1291,8 @@ static int flexrm_startup(struct mbox_chan *chan)
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;
Expand All @@ -1291,7 +1305,9 @@ static int flexrm_startup(struct mbox_chan *chan)
&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;
}

Expand Down Expand Up @@ -1365,16 +1381,32 @@ static void flexrm_shutdown(struct mbox_chan *chan)
/* 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 {
if (readl_relaxed(ring->regs + RING_FLUSH_DONE) &
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++) {
Expand Down
11 changes: 6 additions & 5 deletions drivers/mailbox/mailbox-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#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 {
Expand Down Expand Up @@ -152,16 +153,14 @@ static ssize_t mbox_test_message_write(struct file *filp,

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,
Expand Down Expand Up @@ -223,6 +222,7 @@ 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);

Expand Down Expand Up @@ -292,6 +292,7 @@ static void mbox_test_receive_message(struct mbox_client *client, void *message)
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);
Expand Down
4 changes: 2 additions & 2 deletions drivers/mailbox/mailbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index)
init_completion(&chan->tx_complete);

if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone)
chan->txdone_method |= TXDONE_BY_ACK;
chan->txdone_method = TXDONE_BY_ACK;

spin_unlock_irqrestore(&chan->lock, flags);

Expand Down Expand Up @@ -418,7 +418,7 @@ void mbox_free_channel(struct mbox_chan *chan)
spin_lock_irqsave(&chan->lock, flags);
chan->cl = NULL;
chan->active_req = NULL;
if (chan->txdone_method == (TXDONE_BY_POLL | TXDONE_BY_ACK))
if (chan->txdone_method == TXDONE_BY_ACK)
chan->txdone_method = TXDONE_BY_POLL;

module_put(chan->mbox->dev->driver->owner);
Expand Down
6 changes: 5 additions & 1 deletion drivers/mailbox/omap-mailbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,11 @@ static int __init omap_mbox_init(void)
mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size,
sizeof(mbox_msg_t));

return platform_driver_register(&omap_mbox_driver);
err = platform_driver_register(&omap_mbox_driver);
if (err)
class_unregister(&omap_mbox_class);

return err;
}
subsys_initcall(omap_mbox_init);

Expand Down
4 changes: 2 additions & 2 deletions drivers/mailbox/pcc.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl,
init_completion(&chan->tx_complete);

if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone)
chan->txdone_method |= TXDONE_BY_ACK;
chan->txdone_method = TXDONE_BY_ACK;

spin_unlock_irqrestore(&chan->lock, flags);

Expand Down Expand Up @@ -311,7 +311,7 @@ void pcc_mbox_free_channel(struct mbox_chan *chan)
spin_lock_irqsave(&chan->lock, flags);
chan->cl = NULL;
chan->active_req = NULL;
if (chan->txdone_method == (TXDONE_BY_POLL | TXDONE_BY_ACK))
if (chan->txdone_method == TXDONE_BY_ACK)
chan->txdone_method = TXDONE_BY_POLL;

spin_unlock_irqrestore(&chan->lock, flags);
Expand Down

0 comments on commit 3c18767

Please sign in to comment.