mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 04:13:31 +00:00
107 lines
3.1 KiB
Diff
107 lines
3.1 KiB
Diff
From fa28fb2edcc310f9038538b2f1d27998b01c7db7 Mon Sep 17 00:00:00 2001
|
|
From: Hector Martin <marcan@marcan.st>
|
|
Date: Tue, 8 Feb 2022 19:16:08 +0900
|
|
Subject: [PATCH 042/171] mailbox: apple: Implement poll_data() operation
|
|
|
|
This allows clients running in atomic context to poll for messages to
|
|
arrive.
|
|
|
|
Signed-off-by: Hector Martin <marcan@marcan.st>
|
|
---
|
|
drivers/mailbox/apple-mailbox.c | 37 ++++++++++++++++++++++++++++++---
|
|
1 file changed, 34 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/drivers/mailbox/apple-mailbox.c b/drivers/mailbox/apple-mailbox.c
|
|
index 33e7acf71e3e..1c14ff63f3d3 100644
|
|
--- a/drivers/mailbox/apple-mailbox.c
|
|
+++ b/drivers/mailbox/apple-mailbox.c
|
|
@@ -26,6 +26,7 @@
|
|
#include <linux/module.h>
|
|
#include <linux/of.h>
|
|
#include <linux/platform_device.h>
|
|
+#include <linux/spinlock.h>
|
|
#include <linux/types.h>
|
|
|
|
#define APPLE_ASC_MBOX_CONTROL_FULL BIT(16)
|
|
@@ -101,6 +102,7 @@ struct apple_mbox {
|
|
|
|
struct device *dev;
|
|
struct mbox_controller controller;
|
|
+ spinlock_t rx_lock;
|
|
};
|
|
|
|
static const struct of_device_id apple_mbox_of_match[];
|
|
@@ -204,13 +206,16 @@ static irqreturn_t apple_mbox_send_empty_irq(int irq, void *data)
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
-static irqreturn_t apple_mbox_recv_irq(int irq, void *data)
|
|
+static int apple_mbox_poll(struct apple_mbox *apple_mbox)
|
|
{
|
|
- struct apple_mbox *apple_mbox = data;
|
|
+
|
|
struct apple_mbox_msg msg;
|
|
+ int ret = 0;
|
|
|
|
- while (apple_mbox_hw_recv(apple_mbox, &msg) == 0)
|
|
+ while (apple_mbox_hw_recv(apple_mbox, &msg) == 0) {
|
|
mbox_chan_received_data(&apple_mbox->chan, (void *)&msg);
|
|
+ ret++;
|
|
+ }
|
|
|
|
/*
|
|
* The interrupt will keep firing even if there are no more messages
|
|
@@ -225,9 +230,33 @@ static irqreturn_t apple_mbox_recv_irq(int irq, void *data)
|
|
apple_mbox->regs + apple_mbox->hw->irq_ack);
|
|
}
|
|
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static irqreturn_t apple_mbox_recv_irq(int irq, void *data)
|
|
+{
|
|
+ struct apple_mbox *apple_mbox = data;
|
|
+
|
|
+ spin_lock(&apple_mbox->rx_lock);
|
|
+ apple_mbox_poll(apple_mbox);
|
|
+ spin_unlock(&apple_mbox->rx_lock);
|
|
+
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
+static bool apple_mbox_chan_peek_data(struct mbox_chan *chan)
|
|
+{
|
|
+ struct apple_mbox *apple_mbox = chan->con_priv;
|
|
+ unsigned long flags;
|
|
+ int ret;
|
|
+
|
|
+ spin_lock_irqsave(&apple_mbox->rx_lock, flags);
|
|
+ ret = apple_mbox_poll(apple_mbox);
|
|
+ spin_unlock_irqrestore(&apple_mbox->rx_lock, flags);
|
|
+
|
|
+ return ret > 0;
|
|
+}
|
|
+
|
|
static int apple_mbox_chan_flush(struct mbox_chan *chan, unsigned long timeout)
|
|
{
|
|
struct apple_mbox *apple_mbox = chan->con_priv;
|
|
@@ -276,6 +305,7 @@ static void apple_mbox_chan_shutdown(struct mbox_chan *chan)
|
|
|
|
static const struct mbox_chan_ops apple_mbox_ops = {
|
|
.send_data = apple_mbox_chan_send_data,
|
|
+ .peek_data = apple_mbox_chan_peek_data,
|
|
.flush = apple_mbox_chan_flush,
|
|
.startup = apple_mbox_chan_startup,
|
|
.shutdown = apple_mbox_chan_shutdown,
|
|
@@ -331,6 +361,7 @@ static int apple_mbox_probe(struct platform_device *pdev)
|
|
mbox->controller.txdone_irq = true;
|
|
mbox->controller.of_xlate = apple_mbox_of_xlate;
|
|
mbox->chan.con_priv = mbox;
|
|
+ spin_lock_init(&mbox->rx_lock);
|
|
|
|
irqname = devm_kasprintf(dev, GFP_KERNEL, "%s-recv", dev_name(dev));
|
|
if (!irqname)
|
|
--
|
|
2.34.1
|
|
|