Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1710840 > unrolled thread
| Started by | Bartosz Golaszewski <brgl@bgdev.pl> |
|---|---|
| First post | 2017-08-14 13:30 +0200 |
| Last post | 2017-08-14 13:30 +0200 |
| Articles | 9 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH v3 0/3] simulated interrupts Bartosz Golaszewski <brgl@bgdev.pl> - 2017-08-14 13:30 +0200
[PATCH v3 3/3] gpio: mockup: use irq_sim Bartosz Golaszewski <brgl@bgdev.pl> - 2017-08-14 13:30 +0200
Re: [PATCH v3 3/3] gpio: mockup: use irq_sim Linus Walleij <linus.walleij@linaro.org> - 2017-08-21 00:20 +0200
[PATCH v3 1/3] irq/irq_sim: add a simple interrupt simulator framework Bartosz Golaszewski <brgl@bgdev.pl> - 2017-08-14 13:30 +0200
Re: [PATCH v3 1/3] irq/irq_sim: add a simple interrupt simulator framework Thomas Gleixner <tglx@linutronix.de> - 2017-08-14 15:10 +0200
Re: [PATCH v3 1/3] irq/irq_sim: add a simple interrupt simulator framework Thomas Gleixner <tglx@linutronix.de> - 2017-08-14 16:50 +0200
Re: [PATCH v3 1/3] irq/irq_sim: add a simple interrupt simulator framework Bartosz Golaszewski <brgl@bgdev.pl> - 2017-08-14 16:50 +0200
Re: [PATCH v3 1/3] irq/irq_sim: add a simple interrupt simulator framework Bartosz Golaszewski <brgl@bgdev.pl> - 2017-08-14 16:50 +0200
[PATCH v3 2/3] irq/irq_sim: add a devres variant of irq_sim_init() Bartosz Golaszewski <brgl@bgdev.pl> - 2017-08-14 13:30 +0200
| From | Bartosz Golaszewski <brgl@bgdev.pl> |
|---|---|
| Date | 2017-08-14 13:30 +0200 |
| Subject | [PATCH v3 0/3] simulated interrupts |
| Message-ID | <uelJf-3wX-5@gated-at.bofh.it> |
Some frameworks (e.g. iio, gpiolib) use irq_work to implement simulated interrupts that can be 'fired' from process context when needed and requested just like normal interrupts. This is useful for testing and development purposes. Currently this code is reimplemented by every user. This series proposes to add a new set of functions that can be used by drivers that want to simulate interrupts without having to duplicate any boilerplate code. The first patch adds a simple irq simulator framework. The second extends it with resource management. The third uses the new functionality in the gpio-mockup testing driver. NOTE: The next candidate for using this API would be iio-dummy-evgen. v1 -> v2: - added a call to irq_work_sync in irq_sim_fini() v2 -> v3: - added the license header to new files - added Acked-by's and Reviewed-by's Bartosz Golaszewski (3): irq/irq_sim: add a simple interrupt simulator framework irq/irq_sim: add a devres variant of irq_sim_init() gpio: mockup: use irq_sim Documentation/driver-model/devres.txt | 1 + drivers/gpio/Kconfig | 2 +- drivers/gpio/gpio-mockup.c | 77 ++-------------- include/linux/irq_sim.h | 48 ++++++++++ init/Kconfig | 4 + kernel/Makefile | 1 + kernel/irq_sim.c | 164 ++++++++++++++++++++++++++++++++++ 7 files changed, 226 insertions(+), 71 deletions(-) create mode 100644 include/linux/irq_sim.h create mode 100644 kernel/irq_sim.c -- 2.13.2
[toc] | [next] | [standalone]
| From | Bartosz Golaszewski <brgl@bgdev.pl> |
|---|---|
| Date | 2017-08-14 13:30 +0200 |
| Subject | [PATCH v3 3/3] gpio: mockup: use irq_sim |
| Message-ID | <uelJf-3wX-9@gated-at.bofh.it> |
| In reply to | #1710840 |
Shrink the driver by removing the code dealing with dummy interrupts
and replacing it with calls to the irq_sim API.
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/gpio/Kconfig | 2 +-
drivers/gpio/gpio-mockup.c | 77 +++++-----------------------------------------
2 files changed, 8 insertions(+), 71 deletions(-)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 461d6fc3688b..f858faa5731a 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -311,7 +311,7 @@ config GPIO_MOCKUP
depends on GPIOLIB && SYSFS
select GPIO_SYSFS
select GPIOLIB_IRQCHIP
- select IRQ_WORK
+ select IRQ_SIM
help
This enables GPIO Testing driver, which provides a way to test GPIO
subsystem through sysfs(or char device) and debugfs. GPIO_SYSFS
diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c
index a6565e128f9e..6db7163e6d98 100644
--- a/drivers/gpio/gpio-mockup.c
+++ b/drivers/gpio/gpio-mockup.c
@@ -20,7 +20,7 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
-#include <linux/irq_work.h>
+#include <linux/irq_sim.h>
#include <linux/debugfs.h>
#include <linux/uaccess.h>
@@ -47,18 +47,12 @@ enum {
struct gpio_mockup_line_status {
int dir;
bool value;
- bool irq_enabled;
-};
-
-struct gpio_mockup_irq_context {
- struct irq_work work;
- int irq;
};
struct gpio_mockup_chip {
struct gpio_chip gc;
struct gpio_mockup_line_status *lines;
- struct gpio_mockup_irq_context irq_ctx;
+ struct irq_sim irqsim;
struct dentry *dbg_dir;
};
@@ -144,65 +138,11 @@ static int gpio_mockup_name_lines(struct device *dev,
return 0;
}
-static int gpio_mockup_to_irq(struct gpio_chip *chip, unsigned int offset)
-{
- return chip->irq_base + offset;
-}
-
-static void gpio_mockup_irqmask(struct irq_data *data)
+static int gpio_mockup_to_irq(struct gpio_chip *gc, unsigned int offset)
{
- struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
- chip->lines[data->irq - gc->irq_base].irq_enabled = false;
-}
-
-static void gpio_mockup_irqunmask(struct irq_data *data)
-{
- struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
- struct gpio_mockup_chip *chip = gpiochip_get_data(gc);
-
- chip->lines[data->irq - gc->irq_base].irq_enabled = true;
-}
-
-static struct irq_chip gpio_mockup_irqchip = {
- .name = GPIO_MOCKUP_NAME,
- .irq_mask = gpio_mockup_irqmask,
- .irq_unmask = gpio_mockup_irqunmask,
-};
-
-static void gpio_mockup_handle_irq(struct irq_work *work)
-{
- struct gpio_mockup_irq_context *irq_ctx;
-
- irq_ctx = container_of(work, struct gpio_mockup_irq_context, work);
- handle_simple_irq(irq_to_desc(irq_ctx->irq));
-}
-
-static int gpio_mockup_irqchip_setup(struct device *dev,
- struct gpio_mockup_chip *chip)
-{
- struct gpio_chip *gc = &chip->gc;
- int irq_base, i;
-
- irq_base = devm_irq_alloc_descs(dev, -1, 0, gc->ngpio, 0);
- if (irq_base < 0)
- return irq_base;
-
- gc->irq_base = irq_base;
- gc->irqchip = &gpio_mockup_irqchip;
-
- for (i = 0; i < gc->ngpio; i++) {
- irq_set_chip(irq_base + i, gc->irqchip);
- irq_set_chip_data(irq_base + i, gc);
- irq_set_handler(irq_base + i, &handle_simple_irq);
- irq_modify_status(irq_base + i,
- IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
- }
-
- init_irq_work(&chip->irq_ctx.work, gpio_mockup_handle_irq);
-
- return 0;
+ return irq_sim_irqnum(&chip->irqsim, offset);
}
static ssize_t gpio_mockup_event_write(struct file *file,
@@ -228,11 +168,8 @@ static ssize_t gpio_mockup_event_write(struct file *file,
chip = priv->chip;
gc = &chip->gc;
- if (chip->lines[priv->offset].irq_enabled) {
- gpiod_set_value_cansleep(desc, val);
- priv->chip->irq_ctx.irq = gc->irq_base + priv->offset;
- irq_work_queue(&priv->chip->irq_ctx.work);
- }
+ gpiod_set_value_cansleep(desc, val);
+ irq_sim_fire(&chip->irqsim, priv->offset);
return size;
}
@@ -319,7 +256,7 @@ static int gpio_mockup_add(struct device *dev,
return ret;
}
- ret = gpio_mockup_irqchip_setup(dev, chip);
+ ret = devm_irq_sim_init(dev, &chip->irqsim, gc->ngpio);
if (ret)
return ret;
--
2.13.2
[toc] | [prev] | [next] | [standalone]
| From | Linus Walleij <linus.walleij@linaro.org> |
|---|---|
| Date | 2017-08-21 00:20 +0200 |
| Subject | Re: [PATCH v3 3/3] gpio: mockup: use irq_sim |
| Message-ID | <ugGJz-4ll-7@gated-at.bofh.it> |
| In reply to | #1710841 |
On Mon, Aug 14, 2017 at 1:20 PM, Bartosz Golaszewski <brgl@bgdev.pl> wrote: > Shrink the driver by removing the code dealing with dummy interrupts > and replacing it with calls to the irq_sim API. > > Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl> > Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > Reviewed-by: Linus Walleij <linus.walleij@linaro.org> I applied this to the GPIO tree after pulling the infrastructure from Thomas branch. Yours, Linus Walleij
[toc] | [prev] | [next] | [standalone]
| From | Bartosz Golaszewski <brgl@bgdev.pl> |
|---|---|
| Date | 2017-08-14 13:30 +0200 |
| Subject | [PATCH v3 1/3] irq/irq_sim: add a simple interrupt simulator framework |
| Message-ID | <uelJf-3wX-11@gated-at.bofh.it> |
| In reply to | #1710840 |
Implement a simple, irq_work-based framework for simulating
interrupts. Currently the API exposes routines for initializing and
deinitializing the simulator object, enqueueing the interrupts and
retrieving the allocated interrupt numbers based on the offset of the
dummy interrupt in the simulator struct.
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
include/linux/irq_sim.h | 44 ++++++++++++++++++
init/Kconfig | 4 ++
kernel/Makefile | 1 +
kernel/irq_sim.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 170 insertions(+)
create mode 100644 include/linux/irq_sim.h
create mode 100644 kernel/irq_sim.c
diff --git a/include/linux/irq_sim.h b/include/linux/irq_sim.h
new file mode 100644
index 000000000000..9ee1a4f8bd94
--- /dev/null
+++ b/include/linux/irq_sim.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 Bartosz Golaszewski <brgl@bgdev.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef _LINUX_IRQ_SIM_H
+#define _LINUX_IRQ_SIM_H
+
+#include <linux/irq_work.h>
+
+/*
+ * Provides a framework for allocating simulated interrupts which can be
+ * requested like normal irqs and enqueued from process context.
+ */
+
+struct irq_sim_work_ctx {
+ struct irq_work work;
+ int irq;
+};
+
+struct irq_sim_irq_ctx {
+ int irqnum;
+ bool enabled;
+};
+
+struct irq_sim {
+ struct irq_sim_work_ctx work_ctx;
+ int irq_base;
+ unsigned int irq_count;
+ struct irq_sim_irq_ctx *irqs;
+};
+
+int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs);
+void irq_sim_fini(struct irq_sim *sim);
+
+void irq_sim_fire(struct irq_sim *sim, unsigned int offset);
+
+int irq_sim_irqnum(struct irq_sim *sim, unsigned int offset);
+
+#endif /* _LINUX_IRQ_SIM_H */
diff --git a/init/Kconfig b/init/Kconfig
index 8514b25db21c..220456599c3f 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -23,6 +23,10 @@ config CONSTRUCTORS
config IRQ_WORK
bool
+config IRQ_SIM
+ bool
+ select IRQ_WORK
+
config BUILDTIME_EXTABLE_SORT
bool
diff --git a/kernel/Makefile b/kernel/Makefile
index 4cb8e8b23c6e..4472567c5835 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -97,6 +97,7 @@ obj-$(CONFIG_TRACE_CLOCK) += trace/
obj-$(CONFIG_RING_BUFFER) += trace/
obj-$(CONFIG_TRACEPOINTS) += trace/
obj-$(CONFIG_IRQ_WORK) += irq_work.o
+obj-$(CONFIG_IRQ_SIM) += irq_sim.o
obj-$(CONFIG_CPU_PM) += cpu_pm.o
obj-$(CONFIG_BPF) += bpf/
diff --git a/kernel/irq_sim.c b/kernel/irq_sim.c
new file mode 100644
index 000000000000..31a2c12a79ae
--- /dev/null
+++ b/kernel/irq_sim.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2017 Bartosz Golaszewski <brgl@bgdev.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/irq_sim.h>
+#include <linux/irq.h>
+
+static void irq_sim_irqmask(struct irq_data *data)
+{
+ struct irq_sim_irq_ctx *irq_ctx = irq_data_get_irq_chip_data(data);
+
+ irq_ctx->enabled = false;
+}
+
+static void irq_sim_irqunmask(struct irq_data *data)
+{
+ struct irq_sim_irq_ctx *irq_ctx = irq_data_get_irq_chip_data(data);
+
+ irq_ctx->enabled = true;
+}
+
+static struct irq_chip irq_sim_irqchip = {
+ .name = "irq_sim",
+ .irq_mask = irq_sim_irqmask,
+ .irq_unmask = irq_sim_irqunmask,
+};
+
+static void irq_sim_handle_irq(struct irq_work *work)
+{
+ struct irq_sim_work_ctx *work_ctx;
+
+ work_ctx = container_of(work, struct irq_sim_work_ctx, work);
+ handle_simple_irq(irq_to_desc(work_ctx->irq));
+}
+
+/**
+ * irq_sim_init - Initialize the interrupt simulator: allocate a range of
+ * dummy interrupts.
+ *
+ * @sim: The interrupt simulator object to initialize.
+ * @num_irqs: Number of interrupts to allocate
+ *
+ * Returns 0 on success and a negative error number on failure.
+ */
+int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs)
+{
+ int i;
+
+ sim->irqs = kmalloc_array(num_irqs, sizeof(*sim->irqs), GFP_KERNEL);
+ if (!sim->irqs)
+ return -ENOMEM;
+
+ sim->irq_base = irq_alloc_descs(-1, 0, num_irqs, 0);
+ if (sim->irq_base < 0) {
+ kfree(sim->irqs);
+ return sim->irq_base;
+ }
+
+ for (i = 0; i < num_irqs; i++) {
+ sim->irqs[i].irqnum = sim->irq_base + i;
+ sim->irqs[i].enabled = false;
+ irq_set_chip(sim->irq_base + i, &irq_sim_irqchip);
+ irq_set_chip_data(sim->irq_base + i, &sim->irqs[i]);
+ irq_set_handler(sim->irq_base + i, &handle_simple_irq);
+ irq_modify_status(sim->irq_base + i,
+ IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
+ }
+
+ init_irq_work(&sim->work_ctx.work, irq_sim_handle_irq);
+ sim->irq_count = num_irqs;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(irq_sim_init);
+
+/**
+ * irq_sim_fini - Deinitialize the interrupt simulator: free the interrupt
+ * descriptors and allocated memory.
+ *
+ * @sim: The interrupt simulator to tear down.
+ */
+void irq_sim_fini(struct irq_sim *sim)
+{
+ irq_work_sync(&sim->work_ctx.work);
+ irq_free_descs(sim->irq_base, sim->irq_count);
+ kfree(sim->irqs);
+}
+EXPORT_SYMBOL_GPL(irq_sim_fini);
+
+/**
+ * irq_sim_fire - Enqueue an interrupt.
+ *
+ * @sim: The interrupt simulator object.
+ * @offset: Offset of the simulated interrupt which should be fired.
+ */
+void irq_sim_fire(struct irq_sim *sim, unsigned int offset)
+{
+ if (sim->irqs[offset].enabled) {
+ sim->work_ctx.irq = irq_sim_irqnum(sim, offset);
+ irq_work_queue(&sim->work_ctx.work);
+ }
+}
+EXPORT_SYMBOL_GPL(irq_sim_fire);
+
+/**
+ * irq_sim_irqnum - Get the allocated number of a dummy interrupt.
+ *
+ * @sim: The interrupt simulator object.
+ * @offset: Offset of the simulated interrupt for which to retrieve
+ * the number.
+ */
+int irq_sim_irqnum(struct irq_sim *sim, unsigned int offset)
+{
+ return sim->irqs[offset].irqnum;
+}
+EXPORT_SYMBOL_GPL(irq_sim_irqnum);
--
2.13.2
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-08-14 15:10 +0200 |
| Subject | Re: [PATCH v3 1/3] irq/irq_sim: add a simple interrupt simulator framework |
| Message-ID | <ueni1-4zq-5@gated-at.bofh.it> |
| In reply to | #1710843 |
On Mon, 14 Aug 2017, Bartosz Golaszewski wrote: > Implement a simple, irq_work-based framework for simulating > interrupts. Currently the API exposes routines for initializing and > deinitializing the simulator object, enqueueing the interrupts and > retrieving the allocated interrupt numbers based on the offset of the > dummy interrupt in the simulator struct. > > Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl> > Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > --- > include/linux/irq_sim.h | 44 ++++++++++++++++++ > init/Kconfig | 4 ++ > kernel/Makefile | 1 + > kernel/irq_sim.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++ Please move this to kernel/irq/ ... and the config option to kernel/irq/Kconfig. Thanks, tglx
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-08-14 16:50 +0200 |
| Subject | Re: [PATCH v3 1/3] irq/irq_sim: add a simple interrupt simulator framework |
| Message-ID | <ueoQN-5lI-1@gated-at.bofh.it> |
| In reply to | #1710906 |
On Mon, 14 Aug 2017, Bartosz Golaszewski wrote: > 2017-08-14 15:06 GMT+02:00 Thomas Gleixner <tglx@linutronix.de>: > > On Mon, 14 Aug 2017, Bartosz Golaszewski wrote: > > > >> Implement a simple, irq_work-based framework for simulating > >> interrupts. Currently the API exposes routines for initializing and > >> deinitializing the simulator object, enqueueing the interrupts and > >> retrieving the allocated interrupt numbers based on the offset of the > >> dummy interrupt in the simulator struct. > >> > >> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl> > >> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > >> --- > >> include/linux/irq_sim.h | 44 ++++++++++++++++++ > >> init/Kconfig | 4 ++ > >> kernel/Makefile | 1 + > >> kernel/irq_sim.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++ > > > > Please move this to kernel/irq/ ... and the config option to kernel/irq/Kconfig. > > > > Thanks, > > > > tglx > > > > > > How about moving irq_work.c there too? We could, but irq_work is not really part of the interrupt subsystem, while your interrupt simulator definitely is. Thanks, tglx
[toc] | [prev] | [next] | [standalone]
| From | Bartosz Golaszewski <brgl@bgdev.pl> |
|---|---|
| Date | 2017-08-14 16:50 +0200 |
| Subject | Re: [PATCH v3 1/3] irq/irq_sim: add a simple interrupt simulator framework |
| Message-ID | <ueoQO-5lI-21@gated-at.bofh.it> |
| In reply to | #1710978 |
2017-08-14 16:48 GMT+02:00 Thomas Gleixner <tglx@linutronix.de>: > On Mon, 14 Aug 2017, Bartosz Golaszewski wrote: >> 2017-08-14 15:06 GMT+02:00 Thomas Gleixner <tglx@linutronix.de>: >> > On Mon, 14 Aug 2017, Bartosz Golaszewski wrote: >> > >> >> Implement a simple, irq_work-based framework for simulating >> >> interrupts. Currently the API exposes routines for initializing and >> >> deinitializing the simulator object, enqueueing the interrupts and >> >> retrieving the allocated interrupt numbers based on the offset of the >> >> dummy interrupt in the simulator struct. >> >> >> >> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl> >> >> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> >> >> --- >> >> include/linux/irq_sim.h | 44 ++++++++++++++++++ >> >> init/Kconfig | 4 ++ >> >> kernel/Makefile | 1 + >> >> kernel/irq_sim.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++ >> > >> > Please move this to kernel/irq/ ... and the config option to kernel/irq/Kconfig. >> > >> > Thanks, >> > >> > tglx >> > >> > >> >> How about moving irq_work.c there too? > > We could, but irq_work is not really part of the interrupt subsystem, while > your interrupt simulator definitely is. > Fair enough, let's leave it where it is. I'll send v4. Thanks, Bartosz
[toc] | [prev] | [next] | [standalone]
| From | Bartosz Golaszewski <brgl@bgdev.pl> |
|---|---|
| Date | 2017-08-14 16:50 +0200 |
| Subject | Re: [PATCH v3 1/3] irq/irq_sim: add a simple interrupt simulator framework |
| Message-ID | <ueoQN-5lI-3@gated-at.bofh.it> |
| In reply to | #1710906 |
2017-08-14 15:06 GMT+02:00 Thomas Gleixner <tglx@linutronix.de>: > On Mon, 14 Aug 2017, Bartosz Golaszewski wrote: > >> Implement a simple, irq_work-based framework for simulating >> interrupts. Currently the API exposes routines for initializing and >> deinitializing the simulator object, enqueueing the interrupts and >> retrieving the allocated interrupt numbers based on the offset of the >> dummy interrupt in the simulator struct. >> >> Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl> >> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> >> --- >> include/linux/irq_sim.h | 44 ++++++++++++++++++ >> init/Kconfig | 4 ++ >> kernel/Makefile | 1 + >> kernel/irq_sim.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++ > > Please move this to kernel/irq/ ... and the config option to kernel/irq/Kconfig. > > Thanks, > > tglx > > How about moving irq_work.c there too? Best regards, Bartosz Golaszewski
[toc] | [prev] | [next] | [standalone]
| From | Bartosz Golaszewski <brgl@bgdev.pl> |
|---|---|
| Date | 2017-08-14 13:30 +0200 |
| Subject | [PATCH v3 2/3] irq/irq_sim: add a devres variant of irq_sim_init() |
| Message-ID | <uelJg-3wX-15@gated-at.bofh.it> |
| In reply to | #1710840 |
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>
---
Documentation/driver-model/devres.txt | 1 +
include/linux/irq_sim.h | 4 ++++
kernel/irq_sim.c | 43 +++++++++++++++++++++++++++++++++++
3 files changed, 48 insertions(+)
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
devm_irq_alloc_descs_from()
devm_irq_alloc_generic_chip()
devm_irq_setup_generic_chip()
+ devm_irq_sim_init()
LED
devm_led_classdev_register()
diff --git a/include/linux/irq_sim.h b/include/linux/irq_sim.h
index 9ee1a4f8bd94..9ad634fcc662 100644
--- a/include/linux/irq_sim.h
+++ b/include/linux/irq_sim.h
@@ -11,6 +11,7 @@
#define _LINUX_IRQ_SIM_H
#include <linux/irq_work.h>
+#include <linux/device.h>
/*
* Provides a framework for allocating simulated interrupts which can be
@@ -37,6 +38,9 @@ struct irq_sim {
int irq_sim_init(struct irq_sim *sim, unsigned int num_irqs);
void irq_sim_fini(struct irq_sim *sim);
+int devm_irq_sim_init(struct device *dev,
+ struct irq_sim *sim, unsigned int num_irqs);
+
void irq_sim_fire(struct irq_sim *sim, unsigned int offset);
int irq_sim_irqnum(struct irq_sim *sim, unsigned int offset);
diff --git a/kernel/irq_sim.c b/kernel/irq_sim.c
index 31a2c12a79ae..3daa10d62a27 100644
--- a/kernel/irq_sim.c
+++ b/kernel/irq_sim.c
@@ -92,6 +92,49 @@ void irq_sim_fini(struct irq_sim *sim)
}
EXPORT_SYMBOL_GPL(irq_sim_fini);
+struct irq_sim_devres {
+ struct irq_sim *sim;
+};
+
+static void devm_irq_sim_release(struct device *dev, void *res)
+{
+ struct irq_sim_devres *this = res;
+
+ irq_sim_fini(this->sim);
+}
+
+/**
+ * irq_sim_init - Initialize the interrupt simulator for a managed device.
+ *
+ * @dev: Device to initialize the simulator object for.
+ * @sim: The interrupt simulator object to initialize.
+ * @num_irqs: Number of interrupts to allocate
+ *
+ * Returns 0 on success and a negative error number on failure.
+ */
+int devm_irq_sim_init(struct device *dev,
+ struct irq_sim *sim, unsigned int num_irqs)
+{
+ struct irq_sim_devres *dr;
+ int rv;
+
+ dr = devres_alloc(devm_irq_sim_release, sizeof(*dr), GFP_KERNEL);
+ if (!dr)
+ return -ENOMEM;
+
+ rv = irq_sim_init(sim, num_irqs);
+ if (rv) {
+ devres_free(dr);
+ return rv;
+ }
+
+ dr->sim = sim;
+ devres_add(dev, dr);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(devm_irq_sim_init);
+
/**
* irq_sim_fire - Enqueue an interrupt.
*
--
2.13.2
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web