Commit ca481398 authored by Bartosz Golaszewski's avatar Bartosz Golaszewski Committed by Jonathan Cameron

iio: dummy: evgen: use irq_sim

Switch to using the recently added interrupt simulator for dummy irqs.
Signed-off-by: default avatarBartosz Golaszewski <brgl@bgdev.pl>
Reviewed-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Tested-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 4546813a
...@@ -5,7 +5,7 @@ menu "IIO dummy driver" ...@@ -5,7 +5,7 @@ menu "IIO dummy driver"
depends on IIO depends on IIO
config IIO_DUMMY_EVGEN config IIO_DUMMY_EVGEN
select IRQ_WORK select IRQ_SIM
tristate tristate
config IIO_SIMPLE_DUMMY config IIO_SIMPLE_DUMMY
......
...@@ -24,97 +24,46 @@ ...@@ -24,97 +24,46 @@
#include "iio_dummy_evgen.h" #include "iio_dummy_evgen.h"
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
#include <linux/irq_work.h> #include <linux/irq_sim.h>
/* Fiddly bit of faking and irq without hardware */ /* Fiddly bit of faking and irq without hardware */
#define IIO_EVENTGEN_NO 10 #define IIO_EVENTGEN_NO 10
/** /**
* struct iio_dummy_handle_irq - helper struct to simulate interrupt generation
* @work: irq_work used to run handlers from hardirq context
* @irq: fake irq line number to trigger an interrupt
*/
struct iio_dummy_handle_irq {
struct irq_work work;
int irq;
};
/**
* struct iio_dummy_evgen - evgen state
* @chip: irq chip we are faking
* @base: base of irq range
* @enabled: mask of which irqs are enabled
* @inuse: mask of which irqs are connected
* @regs: irq regs we are faking * @regs: irq regs we are faking
* @lock: protect the evgen state * @lock: protect the evgen state
* @handler: helper for a 'hardware-like' interrupt simulation * @inuse: mask of which irqs are connected
* @irq_sim: interrupt simulator
* @base: base of irq range
*/ */
struct iio_dummy_eventgen { struct iio_dummy_eventgen {
struct irq_chip chip;
int base;
bool enabled[IIO_EVENTGEN_NO];
bool inuse[IIO_EVENTGEN_NO];
struct iio_dummy_regs regs[IIO_EVENTGEN_NO]; struct iio_dummy_regs regs[IIO_EVENTGEN_NO];
struct mutex lock; struct mutex lock;
struct iio_dummy_handle_irq handler; bool inuse[IIO_EVENTGEN_NO];
struct irq_sim irq_sim;
int base;
}; };
/* We can only ever have one instance of this 'device' */ /* We can only ever have one instance of this 'device' */
static struct iio_dummy_eventgen *iio_evgen; static struct iio_dummy_eventgen *iio_evgen;
static const char *iio_evgen_name = "iio_dummy_evgen";
static void iio_dummy_event_irqmask(struct irq_data *d)
{
struct irq_chip *chip = irq_data_get_irq_chip(d);
struct iio_dummy_eventgen *evgen =
container_of(chip, struct iio_dummy_eventgen, chip);
evgen->enabled[d->irq - evgen->base] = false;
}
static void iio_dummy_event_irqunmask(struct irq_data *d)
{
struct irq_chip *chip = irq_data_get_irq_chip(d);
struct iio_dummy_eventgen *evgen =
container_of(chip, struct iio_dummy_eventgen, chip);
evgen->enabled[d->irq - evgen->base] = true;
}
static void iio_dummy_work_handler(struct irq_work *work)
{
struct iio_dummy_handle_irq *irq_handler;
irq_handler = container_of(work, struct iio_dummy_handle_irq, work);
handle_simple_irq(irq_to_desc(irq_handler->irq));
}
static int iio_dummy_evgen_create(void) static int iio_dummy_evgen_create(void)
{ {
int ret, i; int ret;
iio_evgen = kzalloc(sizeof(*iio_evgen), GFP_KERNEL); iio_evgen = kzalloc(sizeof(*iio_evgen), GFP_KERNEL);
if (!iio_evgen) if (!iio_evgen)
return -ENOMEM; return -ENOMEM;
iio_evgen->base = irq_alloc_descs(-1, 0, IIO_EVENTGEN_NO, 0); ret = irq_sim_init(&iio_evgen->irq_sim, IIO_EVENTGEN_NO);
if (iio_evgen->base < 0) { if (ret) {
ret = iio_evgen->base;
kfree(iio_evgen); kfree(iio_evgen);
return ret; return ret;
} }
iio_evgen->chip.name = iio_evgen_name;
iio_evgen->chip.irq_mask = &iio_dummy_event_irqmask; iio_evgen->base = irq_sim_irqnum(&iio_evgen->irq_sim, 0);
iio_evgen->chip.irq_unmask = &iio_dummy_event_irqunmask;
for (i = 0; i < IIO_EVENTGEN_NO; i++) {
irq_set_chip(iio_evgen->base + i, &iio_evgen->chip);
irq_set_handler(iio_evgen->base + i, &handle_simple_irq);
irq_modify_status(iio_evgen->base + i,
IRQ_NOREQUEST | IRQ_NOAUTOEN,
IRQ_NOPROBE);
}
init_irq_work(&iio_evgen->handler.work, iio_dummy_work_handler);
mutex_init(&iio_evgen->lock); mutex_init(&iio_evgen->lock);
return 0; return 0;
} }
...@@ -132,15 +81,17 @@ int iio_dummy_evgen_get_irq(void) ...@@ -132,15 +81,17 @@ int iio_dummy_evgen_get_irq(void)
return -ENODEV; return -ENODEV;
mutex_lock(&iio_evgen->lock); mutex_lock(&iio_evgen->lock);
for (i = 0; i < IIO_EVENTGEN_NO; i++) for (i = 0; i < IIO_EVENTGEN_NO; i++) {
if (!iio_evgen->inuse[i]) { if (!iio_evgen->inuse[i]) {
ret = iio_evgen->base + i; ret = irq_sim_irqnum(&iio_evgen->irq_sim, i);
iio_evgen->inuse[i] = true; iio_evgen->inuse[i] = true;
break; break;
} }
}
mutex_unlock(&iio_evgen->lock); mutex_unlock(&iio_evgen->lock);
if (i == IIO_EVENTGEN_NO) if (i == IIO_EVENTGEN_NO)
return -ENOMEM; return -ENOMEM;
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_irq); EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_irq);
...@@ -167,7 +118,7 @@ EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_regs); ...@@ -167,7 +118,7 @@ EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_regs);
static void iio_dummy_evgen_free(void) static void iio_dummy_evgen_free(void)
{ {
irq_free_descs(iio_evgen->base, IIO_EVENTGEN_NO); irq_sim_fini(&iio_evgen->irq_sim);
kfree(iio_evgen); kfree(iio_evgen);
} }
...@@ -192,9 +143,7 @@ static ssize_t iio_evgen_poke(struct device *dev, ...@@ -192,9 +143,7 @@ static ssize_t iio_evgen_poke(struct device *dev,
iio_evgen->regs[this_attr->address].reg_id = this_attr->address; iio_evgen->regs[this_attr->address].reg_id = this_attr->address;
iio_evgen->regs[this_attr->address].reg_data = event; iio_evgen->regs[this_attr->address].reg_data = event;
iio_evgen->handler.irq = iio_evgen->base + this_attr->address; irq_sim_fire(&iio_evgen->irq_sim, this_attr->address);
if (iio_evgen->enabled[this_attr->address])
irq_work_queue(&iio_evgen->handler.work);
return len; return len;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment