staging:iio:adc:ad7476 move to irqchip based triggering
authorJonathan Cameron <jic23@cam.ac.uk>
Wed, 18 May 2011 13:41:25 +0000 (14:41 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 19 May 2011 23:14:50 +0000 (16:14 -0700)
Untested

V2: Fixed missing free of pollfunc->name pointed out by
Michael Hennerich.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/iio/adc/ad7476.h
drivers/staging/iio/adc/ad7476_core.c
drivers/staging/iio/adc/ad7476_ring.c

index 17febd25aec9d402177c2117a5e34df849669283..01a70211f4ff4f6082bec8fa73a7b0741d70fdea 100644 (file)
@@ -28,8 +28,6 @@ struct ad7476_state {
        struct spi_device               *spi;
        const struct ad7476_chip_info   *chip_info;
        struct regulator                *reg;
-       struct work_struct              poll_work;
-       atomic_t                        protect_ring;
        size_t                          d_size;
        u16                             int_vref_mv;
        struct spi_transfer             xfer;
index 0438923f1afe898c1360a2c5b9d5286e1c88d52f..9729a1c9b59b2e6b25f421a719b2d3e94b874e0f 100644 (file)
@@ -6,13 +6,10 @@
  * Licensed under the GPL-2 or later.
  */
 
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/spi/spi.h>
 #include <linux/regulator/consumer.h>
 #include <linux/err.h>
@@ -176,7 +173,6 @@ static int __devinit ad7476_probe(struct spi_device *spi)
 
        spi_set_drvdata(spi, st);
 
-       atomic_set(&st->protect_ring, 0);
        st->spi = spi;
 
        st->indio_dev = iio_allocate_device(0);
index 8f00d6c23c8739929c0536895fdd9057df7c2761..ec1fa14d86abf8f3b9a4030c03180381c8dc6784 100644 (file)
@@ -8,13 +8,10 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/spi/spi.h>
 
 #include "../iio.h"
@@ -77,46 +74,19 @@ static int ad7476_ring_preenable(struct iio_dev *indio_dev)
        return 0;
 }
 
-/**
- * ad7476_poll_func_th() th of trigger launched polling to ring buffer
- *
- * As sampling only occurs on i2c comms occurring, leave timestamping until
- * then.  Some triggers will generate their own time stamp.  Currently
- * there is no way of notifying them when no one cares.
- **/
-static void ad7476_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-       struct ad7476_state *st = indio_dev->dev_data;
-
-       schedule_work(&st->poll_work);
-       return;
-}
-/**
- * ad7476_poll_bh_to_ring() bh of trigger launched polling to ring buffer
- * @work_s:    the work struct through which this was scheduled
- *
- * Currently there is no option in this driver to disable the saving of
- * timestamps within the ring.
- * I think the one copy of this at a time was to avoid problems if the
- * trigger was set far too high and the reads then locked up the computer.
- **/
-static void ad7476_poll_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t ad7476_trigger_handler(int irq, void  *p)
 {
-       struct ad7476_state *st = container_of(work_s, struct ad7476_state,
-                                                 poll_work);
-       struct iio_dev *indio_dev = st->indio_dev;
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->private_data;
+       struct ad7476_state *st = iio_dev_get_devdata(indio_dev);
        struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
        s64 time_ns;
        __u8 *rxbuf;
        int b_sent;
 
-       /* Ensure only one copy of this function running at a time */
-       if (atomic_inc_return(&st->protect_ring) > 1)
-               return;
-
        rxbuf = kzalloc(st->d_size, GFP_KERNEL);
        if (rxbuf == NULL)
-               return;
+               return -ENOMEM;
 
        b_sent = spi_read(st->spi, rxbuf,
                          st->chip_info->channel[0].scan_type.storagebits / 8);
@@ -131,8 +101,10 @@ static void ad7476_poll_bh_to_ring(struct work_struct *work_s)
 
        indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns);
 done:
+       iio_trigger_notify_done(indio_dev->trig);
        kfree(rxbuf);
-       atomic_dec(&st->protect_ring);
+
+       return IRQ_HANDLED;
 }
 
 int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
@@ -147,9 +119,22 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
        }
        /* Effectively select the ring buffer implementation */
        iio_ring_sw_register_funcs(&indio_dev->ring->access);
-       ret = iio_alloc_pollfunc(indio_dev, NULL, &ad7476_poll_func_th);
-       if (ret)
+       indio_dev->pollfunc = kzalloc(sizeof(indio_dev->pollfunc), GFP_KERNEL);
+       if (indio_dev->pollfunc == NULL) {
+               ret = -ENOMEM;
                goto error_deallocate_sw_rb;
+       }
+       indio_dev->pollfunc->private_data = indio_dev;
+       indio_dev->pollfunc->thread = &ad7476_trigger_handler;
+       indio_dev->pollfunc->type = IRQF_ONESHOT;
+       indio_dev->pollfunc->name
+               = kasprintf(GFP_KERNEL, "%s_consumer%d",
+                           spi_get_device_id(st->spi)->name,
+                           indio_dev->id);
+       if (indio_dev->pollfunc->name == NULL) {
+               ret = -ENOMEM;
+               goto error_free_pollfunc;
+       }
 
        /* Ring buffer functions - here trigger setup related */
 
@@ -158,11 +143,11 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
        indio_dev->ring->predisable = &iio_triggered_ring_predisable;
        indio_dev->ring->scan_timestamp = true;
 
-       INIT_WORK(&st->poll_work, &ad7476_poll_bh_to_ring);
-
        /* Flag that polled ring buffering is possible */
        indio_dev->modes |= INDIO_RING_TRIGGERED;
        return 0;
+error_free_pollfunc:
+       kfree(indio_dev->pollfunc);
 error_deallocate_sw_rb:
        iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -177,6 +162,7 @@ void ad7476_ring_cleanup(struct iio_dev *indio_dev)
                iio_trigger_dettach_poll_func(indio_dev->trig,
                                              indio_dev->pollfunc);
        }
+       kfree(indio_dev->pollfunc->name);
        kfree(indio_dev->pollfunc);
        iio_sw_rb_free(indio_dev->ring);
 }