aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartosz Golaszewski <brgl@bgdev.pl>2017-08-14 10:53:17 -0400
committerThomas Gleixner <tglx@linutronix.de>2017-08-16 10:40:02 -0400
commit44e72c7ebf294043cfe276f7328b8c0e6a3e50e9 (patch)
tree3e481d86d3c8c42c5ac5485b5dfe3ade12339c64
parentb19af510e67e6ca696b8721f45c148119437307c (diff)
genirq/irq_sim: Add a devres variant of irq_sim_init()
Add a resource managed version of irq_sim_init(). This can be conveniently used in device drivers. Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl> Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Cc: Lars-Peter Clausen <lars@metafoo.de> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: Linus Walleij <linus.walleij@linaro.org> Cc: linux-doc@vger.kernel.org Cc: linux-gpio@vger.kernel.org Cc: Bamvor Jian Zhang <bamvor.zhangjian@linaro.org> Cc: Jonathan Cameron <jic23@kernel.org> Link: http://lkml.kernel.org/r/20170814145318.6495-3-brgl@bgdev.pl Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--Documentation/driver-model/devres.txt1
-rw-r--r--include/linux/irq_sim.h3
-rw-r--r--kernel/irq/irq_sim.c43
3 files changed, 47 insertions, 0 deletions
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 30e04f7a690d..69f08c0f23a8 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -312,6 +312,7 @@ IRQ
312 devm_irq_alloc_descs_from() 312 devm_irq_alloc_descs_from()
313 devm_irq_alloc_generic_chip() 313 devm_irq_alloc_generic_chip()
314 devm_irq_setup_generic_chip() 314 devm_irq_setup_generic_chip()
315 devm_irq_sim_init()
315 316
316LED 317LED
317 devm_led_classdev_register() 318 devm_led_classdev_register()
diff --git a/include/linux/irq_sim.h b/include/linux/irq_sim.h
index 39ce57bfa995..0380d899b955 100644
--- a/include/linux/irq_sim.h
+++ b/include/linux/irq_sim.h
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/irq_work.h> 12#include <linux/irq_work.h>
13#include <linux/device.h>
13 14
14/* 15/*
15 * Provides a framework for allocating simulated interrupts which can be 16 * Provides a framework for allocating simulated interrupts which can be
@@ -34,6 +35,8 @@ struct irq_sim {
34}; 35};
35 36
36int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs); 37int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs);
38int devm_irq_sim_init(struct device *dev, struct irq_sim *sim,
39 unsigned int num_irqs);
37void irq_sim_fini(struct irq_sim *sim); 40void irq_sim_fini(struct irq_sim *sim);
38void irq_sim_fire(struct irq_sim *sim, unsigned int offset); 41void irq_sim_fire(struct irq_sim *sim, unsigned int offset);
39int irq_sim_irqnum(struct irq_sim *sim, unsigned int offset); 42int irq_sim_irqnum(struct irq_sim *sim, unsigned int offset);
diff --git a/kernel/irq/irq_sim.c b/kernel/irq/irq_sim.c
index 31a2c12a79ae..24caabf1a0f7 100644
--- a/kernel/irq/irq_sim.c
+++ b/kernel/irq/irq_sim.c
@@ -10,6 +10,10 @@
10#include <linux/irq_sim.h> 10#include <linux/irq_sim.h>
11#include <linux/irq.h> 11#include <linux/irq.h>
12 12
13struct irq_sim_devres {
14 struct irq_sim *sim;
15};
16
13static void irq_sim_irqmask(struct irq_data *data) 17static void irq_sim_irqmask(struct irq_data *data)
14{ 18{
15 struct irq_sim_irq_ctx *irq_ctx = irq_data_get_irq_chip_data(data); 19 struct irq_sim_irq_ctx *irq_ctx = irq_data_get_irq_chip_data(data);
@@ -92,6 +96,45 @@ void irq_sim_fini(struct irq_sim *sim)
92} 96}
93EXPORT_SYMBOL_GPL(irq_sim_fini); 97EXPORT_SYMBOL_GPL(irq_sim_fini);
94 98
99static void devm_irq_sim_release(struct device *dev, void *res)
100{
101 struct irq_sim_devres *this = res;
102
103 irq_sim_fini(this->sim);
104}
105
106/**
107 * irq_sim_init - Initialize the interrupt simulator for a managed device.
108 *
109 * @dev: Device to initialize the simulator object for.
110 * @sim: The interrupt simulator object to initialize.
111 * @num_irqs: Number of interrupts to allocate
112 *
113 * Returns 0 on success and a negative error number on failure.
114 */
115int devm_irq_sim_init(struct device *dev, struct irq_sim *sim,
116 unsigned int num_irqs)
117{
118 struct irq_sim_devres *dr;
119 int rv;
120
121 dr = devres_alloc(devm_irq_sim_release, sizeof(*dr), GFP_KERNEL);
122 if (!dr)
123 return -ENOMEM;
124
125 rv = irq_sim_init(sim, num_irqs);
126 if (rv) {
127 devres_free(dr);
128 return rv;
129 }
130
131 dr->sim = sim;
132 devres_add(dev, dr);
133
134 return 0;
135}
136EXPORT_SYMBOL_GPL(devm_irq_sim_init);
137
95/** 138/**
96 * irq_sim_fire - Enqueue an interrupt. 139 * irq_sim_fire - Enqueue an interrupt.
97 * 140 *