linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Bartosz Golaszewski <brgl@bgdev.pl>
To: Linus Walleij <linus.walleij@linaro.org>,
	Thomas Gleixner <tglx@linutronix.de>
Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org,
	Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Subject: [PATCH 1/2] genirq/irq_sim: add a notifier for irqchip events
Date: Wed, 12 Jun 2024 13:52:25 +0200	[thread overview]
Message-ID: <20240612115231.26703-2-brgl@bgdev.pl> (raw)
In-Reply-To: <20240612115231.26703-1-brgl@bgdev.pl>

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Currently users of the interrupt simulator don't have any way of being
notified about interrupts from the simulated domain being requested or
released. This causes a problem for one of the users - the GPIO
simulator - which is unable to lock the pins as interrupts.

Add a blocking notifier and provide interfaces to register with it, then
use it to notify users of the domain about interrupts being requested
and released while also leaving space for future extensions.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 include/linux/irq_sim.h | 11 +++++++
 kernel/irq/irq_sim.c    | 64 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)

diff --git a/include/linux/irq_sim.h b/include/linux/irq_sim.h
index ab831e5ae748..462d1913bb27 100644
--- a/include/linux/irq_sim.h
+++ b/include/linux/irq_sim.h
@@ -10,6 +10,7 @@
 #include <linux/device.h>
 #include <linux/fwnode.h>
 #include <linux/irqdomain.h>
+#include <linux/notifier.h>
 
 /*
  * Provides a framework for allocating simulated interrupts which can be
@@ -23,4 +24,14 @@ struct irq_domain *devm_irq_domain_create_sim(struct device *dev,
 					      unsigned int num_irqs);
 void irq_domain_remove_sim(struct irq_domain *domain);
 
+enum {
+	IRQ_SIM_DOMAIN_IRQ_REQUESTED = 1,
+	IRQ_SIM_DOMAIN_IRQ_RELEASED,
+};
+
+int irq_sim_domain_register_notifier(struct irq_domain *domain,
+				     struct notifier_block *nb);
+int irq_sim_domain_unregister_notifier(struct irq_domain *domain,
+				       struct notifier_block *nb);
+
 #endif /* _LINUX_IRQ_SIM_H */
diff --git a/kernel/irq/irq_sim.c b/kernel/irq/irq_sim.c
index 38d6ae651ac7..653b6ca869cb 100644
--- a/kernel/irq/irq_sim.c
+++ b/kernel/irq/irq_sim.c
@@ -17,6 +17,7 @@ struct irq_sim_work_ctx {
 	unsigned int		irq_count;
 	unsigned long		*pending;
 	struct irq_domain	*domain;
+	struct blocking_notifier_head notifier;
 };
 
 struct irq_sim_irq_ctx {
@@ -88,6 +89,28 @@ static int irq_sim_set_irqchip_state(struct irq_data *data,
 	return 0;
 }
 
+static int irq_sim_request_resources(struct irq_data *data)
+{
+	struct irq_sim_irq_ctx *irq_ctx = irq_data_get_irq_chip_data(data);
+	struct irq_sim_work_ctx *work_ctx = irq_ctx->work_ctx;
+	irq_hw_number_t hwirq = irqd_to_hwirq(data);
+
+	blocking_notifier_call_chain(&work_ctx->notifier,
+				     IRQ_SIM_DOMAIN_IRQ_REQUESTED, &hwirq);
+
+	return 0;
+}
+
+static void irq_sim_release_resources(struct irq_data *data)
+{
+	struct irq_sim_irq_ctx *irq_ctx = irq_data_get_irq_chip_data(data);
+	struct irq_sim_work_ctx *work_ctx = irq_ctx->work_ctx;
+	irq_hw_number_t hwirq = irqd_to_hwirq(data);
+
+	blocking_notifier_call_chain(&work_ctx->notifier,
+				     IRQ_SIM_DOMAIN_IRQ_RELEASED, &hwirq);
+}
+
 static struct irq_chip irq_sim_irqchip = {
 	.name			= "irq_sim",
 	.irq_mask		= irq_sim_irqmask,
@@ -95,6 +118,8 @@ static struct irq_chip irq_sim_irqchip = {
 	.irq_set_type		= irq_sim_set_type,
 	.irq_get_irqchip_state	= irq_sim_get_irqchip_state,
 	.irq_set_irqchip_state	= irq_sim_set_irqchip_state,
+	.irq_request_resources	= irq_sim_request_resources,
+	.irq_release_resources	= irq_sim_release_resources,
 };
 
 static void irq_sim_handle_irq(struct irq_work *work)
@@ -183,6 +208,7 @@ struct irq_domain *irq_domain_create_sim(struct fwnode_handle *fwnode,
 	work_ctx->irq_count = num_irqs;
 	work_ctx->work = IRQ_WORK_INIT_HARD(irq_sim_handle_irq);
 	work_ctx->pending = no_free_ptr(pending);
+	BLOCKING_INIT_NOTIFIER_HEAD(&work_ctx->notifier);
 
 	return no_free_ptr(work_ctx)->domain;
 }
@@ -242,3 +268,41 @@ struct irq_domain *devm_irq_domain_create_sim(struct device *dev,
 	return domain;
 }
 EXPORT_SYMBOL_GPL(devm_irq_domain_create_sim);
+
+/**
+ * irq_sim_domain_register_notifier - Start listening for events on this
+ *                                    interrupt simulator.
+ *
+ * @domain:     The interrupt simulator domain to register with.
+ * @nb:         Notifier block called on domain events.
+ *
+ * On success: return 0.
+ * On failure: return negative error code.
+ */
+int irq_sim_domain_register_notifier(struct irq_domain *domain,
+				     struct notifier_block *nb)
+{
+	struct irq_sim_work_ctx *work_ctx = domain->host_data;
+
+	return blocking_notifier_chain_register(&work_ctx->notifier, nb);
+}
+EXPORT_SYMBOL_GPL(irq_sim_domain_register_notifier);
+
+/**
+ * irq_sim_domain_unregister_notifier - Stop listening for events on this
+ *                                      interrupt simulator.
+ *
+ * @domain:     The interrupt simulator domain to register with.
+ * @nb:         Notifier block called on domain events.
+ *
+ * On success: return 0.
+ * On failure: return negative error code.
+ */
+int irq_sim_domain_unregister_notifier(struct irq_domain *domain,
+				       struct notifier_block *nb)
+{
+	struct irq_sim_work_ctx *work_ctx = domain->host_data;
+
+	return blocking_notifier_chain_unregister(&work_ctx->notifier, nb);
+}
+EXPORT_SYMBOL_GPL(irq_sim_domain_unregister_notifier);
-- 
2.40.1


  reply	other threads:[~2024-06-12 11:53 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-12 11:52 [PATCH 0/2] gpio: sim: lock simulated GPIOs as interrupts Bartosz Golaszewski
2024-06-12 11:52 ` Bartosz Golaszewski [this message]
2024-06-21 15:40   ` [PATCH 1/2] genirq/irq_sim: add a notifier for irqchip events Thomas Gleixner
2024-06-21 15:59     ` Bartosz Golaszewski
2024-06-21 16:16       ` Thomas Gleixner
2024-06-12 11:52 ` [PATCH 2/2] gpio: sim: lock GPIOs as interrupts when they are requested Bartosz Golaszewski

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=20240612115231.26703-2-brgl@bgdev.pl \
    --to=brgl@bgdev.pl \
    --cc=bartosz.golaszewski@linaro.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tglx@linutronix.de \
    /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).