From: Samuel Holland <samuel@sholland.org>
To: Maxime Ripard <maxime.ripard@bootlin.com>,
Chen-Yu Tsai <wens@csie.org>,
Jassi Brar <jassisinghbrar@gmail.com>,
Michael Turquette <mturquette@baylibre.com>,
Stephen Boyd <sboyd@kernel.org>, Rob Herring <robh+dt@kernel.org>,
Mark Rutland <mark.rutland@arm.com>
Cc: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-sunxi@googlegroups.com,
Samuel Holland <samuel@sholland.org>
Subject: [PATCH v3 12/15] [NOT FOR MERGE] irqchip/mbox: Introduce a mailbox-backed irqchip driver
Date: Fri, 1 Mar 2019 22:29:48 -0600 [thread overview]
Message-ID: <20190302042951.53671-13-samuel@sholland.org> (raw)
In-Reply-To: <20190302042951.53671-1-samuel@sholland.org>
This driver implements a simple interrupt controller using message
passing over a mailbox channel. The intention is for the other end of
the channel to be implemented in firmware. This allows filtering and
forwarding interrupts from one processor to another.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/irqchip/Kconfig | 9 ++
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-mbox.c | 199 +++++++++++++++++++++++++++++++++++++
3 files changed, 209 insertions(+)
create mode 100644 drivers/irqchip/irq-mbox.c
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 3d1e60779078..d22921276797 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -406,6 +406,15 @@ config IMX_IRQSTEER
help
Support for the i.MX IRQSTEER interrupt multiplexer/remapper.
+config IRQ_MBOX
+ tristate "Simple mailbox-backed interrupt controller"
+ depends on MAILBOX
+ select IRQ_DOMAIN
+ help
+ Support for interrupt controllers attached via a mailbox channel.
+ This allows a coprocessor to inject interrupts via a simple
+ message-based protocol.
+
endmenu
config SIFIVE_PLIC
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index c93713d24b86..9de16ab4e69a 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -94,3 +94,4 @@ obj-$(CONFIG_CSKY_APB_INTC) += irq-csky-apb-intc.o
obj-$(CONFIG_SIFIVE_PLIC) += irq-sifive-plic.o
obj-$(CONFIG_IMX_IRQSTEER) += irq-imx-irqsteer.o
obj-$(CONFIG_MADERA_IRQ) += irq-madera.o
+obj-$(CONFIG_IRQ_MBOX) += irq-mbox.o
diff --git a/drivers/irqchip/irq-mbox.c b/drivers/irqchip/irq-mbox.c
new file mode 100644
index 000000000000..f7f6b47bc5b9
--- /dev/null
+++ b/drivers/irqchip/irq-mbox.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2018-2019 Samuel Holland <samuel@sholland.org>
+
+/*
+ * Simple mailbox-backed interrupt controller driver using 32-bit messages.
+ * The mailbox controller is expected to take a (uint32_t *) message argument.
+ *
+ * Client-to-server messages:
+ * Byte 3 (MSB) : Reserved
+ * Byte 2 : Reserved
+ * Byte 1 : Message type (enumerated below)
+ * Byte 0 (LSB) : IRQ number
+ *
+ * Server-to-client messages:
+ * Byte 3 (MSB) : Reserved
+ * Byte 2 : Reserved
+ * Byte 1 : Message type (must be zero == interrupt received)
+ * Byte 0 (LSB) : IRQ number
+ *
+ * IRQ lines must be unmasked before they can be used (generic irqchip code
+ * takes care of that in this driver).
+ */
+
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+
+#define MBOX_INTC_MAX_IRQS 32
+
+enum {
+ MSG_EOI = 0,
+ MSG_MASK = 1,
+ MSG_UNMASK = 2,
+};
+
+struct mbox_intc {
+ struct irq_chip chip;
+ struct irq_domain *domain;
+ struct mbox_chan *rx_chan;
+ struct mbox_chan *tx_chan;
+ struct mbox_client cl;
+};
+
+static int mbox_intc_map(struct irq_domain *domain, unsigned int virq,
+ irq_hw_number_t hwirq)
+{
+ struct mbox_intc *intc = domain->host_data;
+
+ if (hwirq >= MBOX_INTC_MAX_IRQS)
+ return -ENODEV;
+
+ irq_set_chip_data(virq, intc);
+ irq_set_chip_and_handler(virq, &intc->chip, handle_fasteoi_irq);
+ irq_set_status_flags(virq, IRQ_LEVEL);
+
+ return 0;
+}
+
+static const struct irq_domain_ops mbox_intc_domain_ops = {
+ .map = mbox_intc_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+static void mbox_intc_rx_callback(struct mbox_client *cl, void *msg)
+{
+ struct mbox_intc *intc = container_of(cl, struct mbox_intc, cl);
+ uint32_t hwirq = *(uint32_t *)msg;
+
+ if (hwirq >= MBOX_INTC_MAX_IRQS)
+ return;
+
+ generic_handle_irq(irq_linear_revmap(intc->domain, hwirq));
+}
+
+static void mbox_intc_tx_msg(struct irq_data *d, uint8_t request)
+{
+ struct mbox_intc *intc = irq_data_get_irq_chip_data(d);
+ uint32_t msg = (request << 8) | (d->hwirq & GENMASK(0, 7));
+
+ /* Since we don't expect an ACK for this message, immediately complete
+ * the transmission. This ensures that each message is sent out without
+ * sleeping, and 'data' remains in scope until actual transmission. */
+ if (mbox_send_message(intc->tx_chan, &msg) >= 0)
+ mbox_client_txdone(intc->tx_chan, 0);
+}
+
+static void mbox_intc_irq_mask(struct irq_data *d)
+{
+ mbox_intc_tx_msg(d, MSG_MASK);
+}
+
+static void mbox_intc_irq_unmask(struct irq_data *d)
+{
+ mbox_intc_tx_msg(d, MSG_UNMASK);
+}
+
+static void mbox_intc_irq_eoi(struct irq_data *d)
+{
+ mbox_intc_tx_msg(d, MSG_EOI);
+}
+
+static int mbox_intc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mbox_intc *intc;
+ int ret;
+
+ intc = devm_kzalloc(dev, sizeof(*intc), GFP_KERNEL);
+ if (!intc)
+ return -ENOMEM;
+
+ intc->cl.dev = dev;
+ intc->cl.knows_txdone = true;
+ intc->cl.rx_callback = mbox_intc_rx_callback;
+
+ if (of_get_property(dev->of_node, "mbox-names", NULL)) {
+ intc->rx_chan = mbox_request_channel_byname(&intc->cl, "rx");
+ if (IS_ERR(intc->rx_chan)) {
+ ret = PTR_ERR(intc->rx_chan);
+ dev_err(dev, "Failed to request rx mailbox channel\n");
+ goto err;
+ }
+ intc->tx_chan = mbox_request_channel_byname(&intc->cl, "tx");
+ if (IS_ERR(intc->tx_chan)) {
+ ret = PTR_ERR(intc->tx_chan);
+ dev_err(dev, "Failed to request tx mailbox channel\n");
+ goto err_free_rx_chan;
+ }
+ } else {
+ intc->rx_chan = mbox_request_channel(&intc->cl, 0);
+ intc->tx_chan = intc->rx_chan;
+ if (IS_ERR(intc->tx_chan)) {
+ ret = PTR_ERR(intc->tx_chan);
+ dev_err(dev, "Failed to request mailbox channel\n");
+ goto err;
+ }
+ }
+
+ intc->chip.name = dev_name(dev);
+ intc->chip.irq_mask = mbox_intc_irq_mask;
+ intc->chip.irq_unmask = mbox_intc_irq_unmask;
+ intc->chip.irq_eoi = mbox_intc_irq_eoi;
+
+ intc->domain = irq_domain_add_linear(dev->of_node, MBOX_INTC_MAX_IRQS,
+ &mbox_intc_domain_ops, intc);
+ if (IS_ERR(intc->domain)) {
+ ret = PTR_ERR(intc->domain);
+ dev_err(dev, "Failed to allocate IRQ domain: %d\n", ret);
+ goto err_free_tx_chan;
+ }
+
+ platform_set_drvdata(pdev, intc);
+
+ return 0;
+
+err_free_tx_chan:
+ if (intc->tx_chan != intc->rx_chan)
+ mbox_free_channel(intc->tx_chan);
+err_free_rx_chan:
+ mbox_free_channel(intc->rx_chan);
+err:
+ return ret;
+}
+
+static int mbox_intc_remove(struct platform_device *pdev)
+{
+ struct mbox_intc *intc = platform_get_drvdata(pdev);
+
+ irq_domain_remove(intc->domain);
+ if (intc->tx_chan != intc->rx_chan)
+ mbox_free_channel(intc->tx_chan);
+ mbox_free_channel(intc->rx_chan);
+
+ return 0;
+}
+
+static const struct of_device_id mbox_intc_of_match[] = {
+ { .compatible = "allwinner,sunxi-msgbox-intc" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mbox_intc_of_match);
+
+static struct platform_driver mbox_intc_driver = {
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .of_match_table = mbox_intc_of_match,
+ },
+ .probe = mbox_intc_probe,
+ .remove = mbox_intc_remove,
+};
+module_platform_driver(mbox_intc_driver);
+
+MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>");
+MODULE_DESCRIPTION("Simple mailbox-backed interrupt controller");
+MODULE_LICENSE("GPL v2");
--
2.19.2
next prev parent reply other threads:[~2019-03-02 4:30 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-02 4:29 [PATCH v3 00/15] Allwinner sunxi message box support Samuel Holland
2019-03-02 4:29 ` [PATCH v3 01/15] clk: sunxi-ng: Mark msgbox clocks as critical Samuel Holland
2019-03-02 4:29 ` [PATCH v3 02/15] clk: sunxi-ng: Mark AR100 " Samuel Holland
2019-03-02 4:29 ` [PATCH v3 03/15] dt-bindings: mailbox: Add a sunxi message box binding Samuel Holland
2019-03-12 13:36 ` Rob Herring
2019-03-02 4:29 ` [PATCH v3 04/15] mailbox: sunxi-msgbox: Add a new mailbox driver Samuel Holland
2019-03-02 4:29 ` [PATCH v3 05/15] ARM: dts: sunxi: a80: Add msgbox node Samuel Holland
2019-03-02 4:29 ` [PATCH v3 06/15] ARM: dts: sunxi: a83t: " Samuel Holland
2019-03-02 4:29 ` [PATCH v3 07/15] ARM: dts: sunxi: h3/h5: " Samuel Holland
2019-03-06 3:39 ` Samuel Holland
2019-03-02 4:29 ` [PATCH v3 08/15] arm64: dts: allwinner: a64: " Samuel Holland
2019-03-02 4:29 ` [PATCH v3 09/15] arm64: dts: allwinner: h6: " Samuel Holland
2019-03-02 4:29 ` [PATCH v3 10/15] [NOT FOR MERGE] clk: sunxi-ng: sun8i: Avoid turning off unused PRCM gates Samuel Holland
2019-03-02 4:29 ` [PATCH v3 11/15] [NOT FOR MERGE] dt-bindings: Add a binding for a mailbox-backed interrupt controller Samuel Holland
2019-03-12 13:42 ` Rob Herring
2019-03-02 4:29 ` Samuel Holland [this message]
2019-03-02 4:29 ` [PATCH v3 13/15] [NOT FOR MERGE] arm64: dts: allwinner: a64: Add interrupt controller node Samuel Holland
2019-03-02 4:29 ` [PATCH v3 14/15] [NOT FOR MERGE] arm64: dts: allwinner: a64: Convert DTS to use msgbox_intc Samuel Holland
2019-03-02 4:29 ` [PATCH v3 15/15] [NOT FOR MERGE] arm64: dts: allwinner: a64: Remove unused r_intc Samuel Holland
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190302042951.53671-13-samuel@sholland.org \
--to=samuel@sholland.org \
--cc=devicetree@vger.kernel.org \
--cc=jassisinghbrar@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sunxi@googlegroups.com \
--cc=mark.rutland@arm.com \
--cc=maxime.ripard@bootlin.com \
--cc=mturquette@baylibre.com \
--cc=robh+dt@kernel.org \
--cc=sboyd@kernel.org \
--cc=wens@csie.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).