diff options
author | Bartosz Golaszewski <brgl@bgdev.pl> | 2017-08-14 10:53:17 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-08-16 10:40:02 -0400 |
commit | 44e72c7ebf294043cfe276f7328b8c0e6a3e50e9 (patch) | |
tree | 3e481d86d3c8c42c5ac5485b5dfe3ade12339c64 | |
parent | b19af510e67e6ca696b8721f45c148119437307c (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.txt | 1 | ||||
-rw-r--r-- | include/linux/irq_sim.h | 3 | ||||
-rw-r--r-- | kernel/irq/irq_sim.c | 43 |
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 | ||
316 | LED | 317 | LED |
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 | ||
36 | int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs); | 37 | int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs); |
38 | int devm_irq_sim_init(struct device *dev, struct irq_sim *sim, | ||
39 | unsigned int num_irqs); | ||
37 | void irq_sim_fini(struct irq_sim *sim); | 40 | void irq_sim_fini(struct irq_sim *sim); |
38 | void irq_sim_fire(struct irq_sim *sim, unsigned int offset); | 41 | void irq_sim_fire(struct irq_sim *sim, unsigned int offset); |
39 | int irq_sim_irqnum(struct irq_sim *sim, unsigned int offset); | 42 | int 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 | ||
13 | struct irq_sim_devres { | ||
14 | struct irq_sim *sim; | ||
15 | }; | ||
16 | |||
13 | static void irq_sim_irqmask(struct irq_data *data) | 17 | static 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 | } |
93 | EXPORT_SYMBOL_GPL(irq_sim_fini); | 97 | EXPORT_SYMBOL_GPL(irq_sim_fini); |
94 | 98 | ||
99 | static 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 | */ | ||
115 | int 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 | } | ||
136 | EXPORT_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 | * |