All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device
@ 2011-07-18 13:49 Jonathan Cameron
  2011-07-18 13:49 ` [PATCH 1/7] staging:iio:trigger push functions that don't need to be generaly available down into the core Jonathan Cameron
                   ` (8 more replies)
  0 siblings, 9 replies; 12+ messages in thread
From: Jonathan Cameron @ 2011-07-18 13:49 UTC (permalink / raw)
  To: linux-iio; +Cc: arnd, manuel.stahl, device-drivers-devel, Jonathan Cameron

This is another of Arnd's suggestions.

Some of the patches here are just pre conversion reworks to make the important
bit easier and some are cleanups of headers etc as a result of things not
being needed any more.

One little change I slipped in here:

devices now have iio:deviceX as their name so that we have something
sensibly named under /dev/

The important patches are 4 and 6.

4 uses Arnd's suggestion of an annon_fd obtained via ioctl on the buffer
chrdev to get a file for easy use for reading events.  This is a very neat
solution that lets us keep the actual event system separate from the data
stream without two chrdevs.

6. Moves the remaining single chrdev so it associated with the iio_dev rather
than the buffer.  This means we now only have two types of device (other than
weird ones like the sysfs trigger management node), triggers and devices.
Given either can exist independently, those two don't make sense to merge.

Anyhow, I'm far from convinced that the allocation / deallocation is now
correct and that there aren't any race conditions on removal od devices.
(then again I'm not convinced there weren't any of those before.)

Note I haven't ammended the nature of either 'chrdev' at all. There
is more to be done there.

Note, this is 3.2 material so no particular rush for comments.
Having said that, please do pull it into local trees and hammer it
nice and hard to see where I messed up.

For reference a minimal test app is:

#include <stdio.h>
/* little dirty test prog */
 #include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>

struct iio_event_data {
	int	id;
	int64_t	timestamp;
};


int main(int argc, char **argv)
{
	int ret;
	int fp;
	int data;
	int i = 0;
	FILE *evfp;
	struct iio_event_data ev;
	fp = open(argv[1], O_RDONLY);
	ret = ioctl(fp, 0, &data);
	/* So we have the fd (in theory) of the anon file */
	evfp = fdopen(data, "r");

	if (evfp)
		for (i = 0; i < 100; i++) {
			ret = fread( &ev, sizeof(ev), 1, evfp);
			printf("%d %lld\n", ev.id, ev.timestamp);
		}
	return 0;
}

Jonathan

Jonathan Cameron (7):
  staging:iio:trigger push functions that don't need to be generaly
    available down into the core.
  staging:iio:kfifo buffer - push structure definition down into
    implementation.
  staging:iio:chrdev.h rationalization.
  staging:iio: remove specific chrdev for event reading. Get fd from
    ioctl on buffer.
  staging:iio: squash chrdev handler remains into users.
  staging:iio: push the main buffer chrdev down to the top level.
  staging:iio: remove now defunct header definitions and add some
    statics

 drivers/staging/iio/Documentation/generic_buffer.c |   11 +-
 drivers/staging/iio/Documentation/iio_utils.h      |    2 +-
 drivers/staging/iio/accel/adis16201_core.c         |    6 +-
 drivers/staging/iio/accel/adis16203_core.c         |    6 +-
 drivers/staging/iio/accel/adis16204_core.c         |    6 +-
 drivers/staging/iio/accel/adis16209_core.c         |    6 +-
 drivers/staging/iio/accel/adis16240_core.c         |    6 +-
 drivers/staging/iio/accel/lis3l02dq_core.c         |    6 +-
 drivers/staging/iio/accel/sca3000_core.c           |    4 +-
 drivers/staging/iio/adc/ad7298_core.c              |    4 +-
 drivers/staging/iio/adc/ad7476_core.c              |    4 +-
 drivers/staging/iio/adc/ad7606_core.c              |    4 +-
 drivers/staging/iio/adc/ad7793.c                   |    6 +-
 drivers/staging/iio/adc/ad7887_core.c              |    4 +-
 drivers/staging/iio/adc/ad799x_core.c              |    4 +-
 drivers/staging/iio/adc/max1363_core.c             |    6 +-
 drivers/staging/iio/chrdev.h                       |   51 ----
 drivers/staging/iio/gyro/adis16260_core.c          |    6 +-
 drivers/staging/iio/iio.h                          |    4 +-
 drivers/staging/iio/iio_core.h                     |   39 +++-
 drivers/staging/iio/imu/adis16400_core.c           |    6 +-
 drivers/staging/iio/industrialio-core.c            |  273 +++++++++++---------
 drivers/staging/iio/industrialio-ring.c            |  220 ++++++-----------
 drivers/staging/iio/industrialio-trigger.c         |   30 ++-
 drivers/staging/iio/kfifo_buf.c                    |   43 ++--
 drivers/staging/iio/kfifo_buf.h                    |    8 -
 drivers/staging/iio/meter/ade7758_core.c           |    2 +-
 drivers/staging/iio/ring_generic.h                 |   28 +--
 drivers/staging/iio/ring_sw.c                      |   23 +--
 drivers/staging/iio/trigger.h                      |   39 ---
 30 files changed, 368 insertions(+), 489 deletions(-)

-- 
1.7.3.4

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/7] staging:iio:trigger push functions that don't need to be generaly available down into the core.
  2011-07-18 13:49 [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device Jonathan Cameron
@ 2011-07-18 13:49 ` Jonathan Cameron
  2011-07-18 13:49 ` [PATCH 2/7] staging:iio:kfifo buffer - push structure definition down into implementation Jonathan Cameron
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Jonathan Cameron @ 2011-07-18 13:49 UTC (permalink / raw)
  To: linux-iio; +Cc: arnd, manuel.stahl, device-drivers-devel, Jonathan Cameron

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/industrialio-trigger.c |   30 +++++++++++++++++----
 drivers/staging/iio/trigger.h              |   39 ----------------------------
 2 files changed, 24 insertions(+), 45 deletions(-)

diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c
index 72ea106..f1ece86 100644
--- a/drivers/staging/iio/industrialio-trigger.c
+++ b/drivers/staging/iio/industrialio-trigger.c
@@ -215,6 +215,26 @@ void iio_trigger_notify_done(struct iio_trigger *trig)
 EXPORT_SYMBOL(iio_trigger_notify_done);
 
 /* Trigger Consumer related functions */
+static int iio_trigger_get_irq(struct iio_trigger *trig)
+{
+	int ret;
+	mutex_lock(&trig->pool_lock);
+	ret = bitmap_find_free_region(trig->pool,
+				      CONFIG_IIO_CONSUMERS_PER_TRIGGER,
+				      ilog2(1));
+	mutex_unlock(&trig->pool_lock);
+	if (ret >= 0)
+		ret += trig->subirq_base;
+
+	return ret;
+}
+
+static void iio_trigger_put_irq(struct iio_trigger *trig, int irq)
+{
+	mutex_lock(&trig->pool_lock);
+	clear_bit(irq - trig->subirq_base, trig->pool);
+	mutex_unlock(&trig->pool_lock);
+}
 
 /* Complexity in here.  With certain triggers (datardy) an acknowledgement
  * may be needed if the pollfuncs do not include the data read for the
@@ -223,8 +243,8 @@ EXPORT_SYMBOL(iio_trigger_notify_done);
  * the relevant function is in there may be the best option.
  */
 /* Worth protecting against double additions?*/
-int iio_trigger_attach_poll_func(struct iio_trigger *trig,
-				 struct iio_poll_func *pf)
+static int iio_trigger_attach_poll_func(struct iio_trigger *trig,
+					struct iio_poll_func *pf)
 {
 	int ret = 0;
 	bool notinuse
@@ -241,10 +261,9 @@ int iio_trigger_attach_poll_func(struct iio_trigger *trig,
 
 	return ret;
 }
-EXPORT_SYMBOL(iio_trigger_attach_poll_func);
 
-int iio_trigger_dettach_poll_func(struct iio_trigger *trig,
-				  struct iio_poll_func *pf)
+static int iio_trigger_dettach_poll_func(struct iio_trigger *trig,
+					 struct iio_poll_func *pf)
 {
 	int ret = 0;
 	bool no_other_users
@@ -263,7 +282,6 @@ int iio_trigger_dettach_poll_func(struct iio_trigger *trig,
 error_ret:
 	return ret;
 }
-EXPORT_SYMBOL(iio_trigger_dettach_poll_func);
 
 irqreturn_t iio_pollfunc_store_time(int irq, void *p)
 {
diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h
index 56f8baf..722fc33 100644
--- a/drivers/staging/iio/trigger.h
+++ b/drivers/staging/iio/trigger.h
@@ -104,23 +104,6 @@ int iio_trigger_register(struct iio_trigger *trig_info);
 void iio_trigger_unregister(struct iio_trigger *trig_info);
 
 /**
- * iio_trigger_attach_poll_func() - add a function pair to be run on trigger
- * @trig:	trigger to which the function pair are being added
- * @pf:		poll function pair
- **/
-int iio_trigger_attach_poll_func(struct iio_trigger *trig,
-				 struct iio_poll_func *pf);
-
-/**
- * iio_trigger_dettach_poll_func() -	remove function pair from those to be
- *					run on trigger
- * @trig:	trigger from which the function is being removed
- * @pf:		poll function pair
- **/
-int iio_trigger_dettach_poll_func(struct iio_trigger *trig,
-				  struct iio_poll_func *pf);
-
-/**
  * iio_trigger_poll() - called on a trigger occurring
  * @trig: trigger which occurred
  *
@@ -129,30 +112,8 @@ int iio_trigger_dettach_poll_func(struct iio_trigger *trig,
 void iio_trigger_poll(struct iio_trigger *trig, s64 time);
 void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time);
 
-
 irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private);
 
-static inline int iio_trigger_get_irq(struct iio_trigger *trig)
-{
-	int ret;
-	mutex_lock(&trig->pool_lock);
-	ret = bitmap_find_free_region(trig->pool,
-				      CONFIG_IIO_CONSUMERS_PER_TRIGGER,
-				      ilog2(1));
-	mutex_unlock(&trig->pool_lock);
-	if (ret >= 0)
-		ret += trig->subirq_base;
-
-	return ret;
-};
-
-static inline void iio_trigger_put_irq(struct iio_trigger *trig, int irq)
-{
-	mutex_lock(&trig->pool_lock);
-	clear_bit(irq - trig->subirq_base, trig->pool);
-	mutex_unlock(&trig->pool_lock);
-};
-
 struct iio_trigger *iio_allocate_trigger(const char *fmt, ...)
 	__attribute__((format(printf, 1, 2)));
 void iio_free_trigger(struct iio_trigger *trig);
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/7] staging:iio:kfifo buffer - push structure definition down into implementation.
  2011-07-18 13:49 [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device Jonathan Cameron
  2011-07-18 13:49 ` [PATCH 1/7] staging:iio:trigger push functions that don't need to be generaly available down into the core Jonathan Cameron
@ 2011-07-18 13:49 ` Jonathan Cameron
  2011-07-18 13:50 ` [PATCH 3/7] staging:iio:chrdev.h rationalization Jonathan Cameron
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Jonathan Cameron @ 2011-07-18 13:49 UTC (permalink / raw)
  To: linux-iio; +Cc: arnd, manuel.stahl, device-drivers-devel, Jonathan Cameron

Nothing other than the implementation needs to know about this.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/kfifo_buf.c |    8 ++++++++
 drivers/staging/iio/kfifo_buf.h |    8 --------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/iio/kfifo_buf.c b/drivers/staging/iio/kfifo_buf.c
index 6002368..3c9516b 100644
--- a/drivers/staging/iio/kfifo_buf.c
+++ b/drivers/staging/iio/kfifo_buf.c
@@ -8,6 +8,14 @@
 
 #include "kfifo_buf.h"
 
+struct iio_kfifo {
+	struct iio_ring_buffer ring;
+	struct kfifo kf;
+	int use_count;
+	int update_needed;
+	struct mutex use_lock;
+};
+
 #define iio_to_kfifo(r) container_of(r, struct iio_kfifo, ring)
 
 static inline int __iio_allocate_kfifo(struct iio_kfifo *buf,
diff --git a/drivers/staging/iio/kfifo_buf.h b/drivers/staging/iio/kfifo_buf.h
index aac3053..fb48523 100644
--- a/drivers/staging/iio/kfifo_buf.h
+++ b/drivers/staging/iio/kfifo_buf.h
@@ -3,14 +3,6 @@
 #include "iio.h"
 #include "ring_generic.h"
 
-struct iio_kfifo {
-	struct iio_ring_buffer ring;
-	struct kfifo kf;
-	int use_count;
-	int update_needed;
-	struct mutex use_lock;
-};
-
 extern const struct iio_ring_access_funcs kfifo_access_funcs;
 
 struct iio_ring_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev);
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/7] staging:iio:chrdev.h rationalization.
  2011-07-18 13:49 [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device Jonathan Cameron
  2011-07-18 13:49 ` [PATCH 1/7] staging:iio:trigger push functions that don't need to be generaly available down into the core Jonathan Cameron
  2011-07-18 13:49 ` [PATCH 2/7] staging:iio:kfifo buffer - push structure definition down into implementation Jonathan Cameron
@ 2011-07-18 13:50 ` Jonathan Cameron
  2011-07-18 13:50 ` [PATCH 4/7] staging:iio: remove specific chrdev for event reading. Get fd from ioctl on buffer Jonathan Cameron
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Jonathan Cameron @ 2011-07-18 13:50 UTC (permalink / raw)
  To: linux-iio; +Cc: arnd, manuel.stahl, device-drivers-devel, Jonathan Cameron

Push some functions out of header and include this where it is needed
in other headers only.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/chrdev.h            |   32 -------------------------------
 drivers/staging/iio/iio.h               |    2 +-
 drivers/staging/iio/industrialio-core.c |   32 +++++++++++++++++++++++++++++++
 drivers/staging/iio/ring_generic.h      |    1 +
 4 files changed, 34 insertions(+), 33 deletions(-)

diff --git a/drivers/staging/iio/chrdev.h b/drivers/staging/iio/chrdev.h
index 3e31ee6..8a229e7 100644
--- a/drivers/staging/iio/chrdev.h
+++ b/drivers/staging/iio/chrdev.h
@@ -9,7 +9,6 @@
 
 #ifndef _IIO_CHRDEV_H_
 #define _IIO_CHRDEV_H_
-struct iio_dev;
 
 /**
  * struct iio_handler - Structure used to specify file operations
@@ -41,35 +40,4 @@ struct iio_event_data {
 	s64	timestamp;
 };
 
-/**
- * struct iio_detected_event_list - list element for events that have occurred
- * @list:		linked list header
- * @ev:			the event itself
- */
-struct iio_detected_event_list {
-	struct list_head		list;
-	struct iio_event_data		ev;
-};
-
-/**
- * struct iio_event_interface - chrdev interface for an event line
- * @dev:		device assocated with event interface
- * @handler:		fileoperations and related control for the chrdev
- * @wait:		wait queue to allow blocking reads of events
- * @event_list_lock:	mutex to protect the list of detected events
- * @det_events:		list of detected events
- * @max_events:		maximum number of events before new ones are dropped
- * @current_events:	number of events in detected list
- */
-struct iio_event_interface {
-	struct device				dev;
-	struct iio_handler			handler;
-	wait_queue_head_t			wait;
-	struct mutex				event_list_lock;
-	struct list_head			det_events;
-	int					max_events;
-	int					current_events;
-	struct list_head dev_attr_list;
-};
-
 #endif
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 61cfb26..cf43e71 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -15,7 +15,6 @@
 #include <linux/cdev.h>
 #include <linux/irq.h>
 #include "sysfs.h"
-#include "chrdev.h"
 
 /* IIO TODO LIST */
 /*
@@ -180,6 +179,7 @@ static inline s64 iio_get_time_ns(void)
 #define IIO_VAL_INT_PLUS_NANO 3
 
 struct iio_trigger; /* forward declaration */
+struct iio_dev;
 
 /**
  * struct iio_info - constant information about device
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 123841b..f9d1744 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -24,6 +24,7 @@
 #include "iio.h"
 #include "iio_core.h"
 #include "iio_core_trigger.h"
+#include "chrdev.h"
 
 #define IIO_ID_PREFIX "device"
 #define IIO_ID_FORMAT IIO_ID_PREFIX "%d"
@@ -117,6 +118,37 @@ static void iio_free_ida_val(struct ida *this_ida, int id)
 	spin_unlock(&iio_ida_lock);
 }
 
+/**
+ * struct iio_detected_event_list - list element for events that have occurred
+ * @list:		linked list header
+ * @ev:			the event itself
+ */
+struct iio_detected_event_list {
+	struct list_head		list;
+	struct iio_event_data		ev;
+};
+
+/**
+ * struct iio_event_interface - chrdev interface for an event line
+ * @dev:		device assocated with event interface
+ * @handler:		fileoperations and related control for the chrdev
+ * @wait:		wait queue to allow blocking reads of events
+ * @event_list_lock:	mutex to protect the list of detected events
+ * @det_events:		list of detected events
+ * @max_events:		maximum number of events before new ones are dropped
+ * @current_events:	number of events in detected list
+ */
+struct iio_event_interface {
+	struct device				dev;
+	struct iio_handler			handler;
+	wait_queue_head_t			wait;
+	struct mutex				event_list_lock;
+	struct list_head			det_events;
+	int					max_events;
+	int					current_events;
+	struct list_head dev_attr_list;
+};
+
 int iio_push_event(struct iio_dev *dev_info,
 		   int ev_line,
 		   int ev_code,
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index 3f26f71..d103262 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -10,6 +10,7 @@
 #ifndef _IIO_RING_GENERIC_H_
 #define _IIO_RING_GENERIC_H_
 #include "iio.h"
+#include "chrdev.h"
 
 #ifdef CONFIG_IIO_RING_BUFFER
 
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/7] staging:iio: remove specific chrdev for event reading. Get fd from ioctl on buffer.
  2011-07-18 13:49 [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device Jonathan Cameron
                   ` (2 preceding siblings ...)
  2011-07-18 13:50 ` [PATCH 3/7] staging:iio:chrdev.h rationalization Jonathan Cameron
@ 2011-07-18 13:50 ` Jonathan Cameron
  2011-07-21  8:57   ` Jonathan Cameron
  2011-07-18 13:50 ` [PATCH 5/7] staging:iio: squash chrdev handler remains into users Jonathan Cameron
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 12+ messages in thread
From: Jonathan Cameron @ 2011-07-18 13:50 UTC (permalink / raw)
  To: linux-iio; +Cc: arnd, manuel.stahl, device-drivers-devel, Jonathan Cameron

Change suggested by Arnd Bergmann.

No real reason to have two chrdevs per device. This step merges them into one.
Currently this means that events will only work on devices with buffers. THat will
be remedied shortly.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/iio.h               |    1 +
 drivers/staging/iio/industrialio-core.c |  174 ++++++++++--------------------
 drivers/staging/iio/industrialio-ring.c |   23 ++++-
 3 files changed, 81 insertions(+), 117 deletions(-)

diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index cf43e71..308b100 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -247,6 +247,7 @@ struct iio_info {
 
 };
 
+int iio_event_getfd(struct iio_dev *indio_dev);
 /**
  * struct iio_dev - industrial I/O device
  * @id:			[INTERN] used to identify device internally
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index f9d1744..31ebc3a 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -21,6 +21,7 @@
 #include <linux/wait.h>
 #include <linux/cdev.h>
 #include <linux/slab.h>
+#include <linux/anon_inodes.h>
 #include "iio.h"
 #include "iio_core.h"
 #include "iio_core_trigger.h"
@@ -128,6 +129,7 @@ struct iio_detected_event_list {
 	struct iio_event_data		ev;
 };
 
+
 /**
  * struct iio_event_interface - chrdev interface for an event line
  * @dev:		device assocated with event interface
@@ -139,7 +141,6 @@ struct iio_detected_event_list {
  * @current_events:	number of events in detected list
  */
 struct iio_event_interface {
-	struct device				dev;
 	struct iio_handler			handler;
 	wait_queue_head_t			wait;
 	struct mutex				event_list_lock;
@@ -187,7 +188,6 @@ error_ret:
 }
 EXPORT_SYMBOL(iio_push_event);
 
-
 /* This turns up an awful lot */
 ssize_t iio_read_const_attr(struct device *dev,
 			    struct device_attribute *attr,
@@ -207,7 +207,6 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
 	struct iio_detected_event_list *el;
 	int ret;
 	size_t len;
-
 	mutex_lock(&ev_int->event_list_lock);
 	if (list_empty(&ev_int->det_events)) {
 		if (filep->f_flags & O_NONBLOCK) {
@@ -249,10 +248,8 @@ error_ret:
 
 static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
 {
-	struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev);
-	struct iio_event_interface *ev_int = hand->private;
+	struct iio_event_interface *ev_int = filep->private_data;
 	struct iio_detected_event_list *el, *t;
-
 	mutex_lock(&ev_int->event_list_lock);
 	clear_bit(IIO_BUSY_BIT_POS, &ev_int->handler.flags);
 	/*
@@ -264,23 +261,7 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
 		list_del(&el->list);
 		kfree(el);
 	}
-	mutex_unlock(&ev_int->event_list_lock);
-
-	return 0;
-}
-
-static int iio_event_chrdev_open(struct inode *inode, struct file *filep)
-{
-	struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev);
-	struct iio_event_interface *ev_int = hand->private;
-
-	mutex_lock(&ev_int->event_list_lock);
-	if (test_and_set_bit(IIO_BUSY_BIT_POS, &hand->flags)) {
-		fops_put(filep->f_op);
-		mutex_unlock(&ev_int->event_list_lock);
-		return -EBUSY;
-	}
-	filep->private_data = hand->private;
+	ev_int->current_events = 0;
 	mutex_unlock(&ev_int->event_list_lock);
 
 	return 0;
@@ -289,23 +270,10 @@ static int iio_event_chrdev_open(struct inode *inode, struct file *filep)
 static const struct file_operations iio_event_chrdev_fileops = {
 	.read =  iio_event_chrdev_read,
 	.release = iio_event_chrdev_release,
-	.open = iio_event_chrdev_open,
 	.owner = THIS_MODULE,
 	.llseek = noop_llseek,
 };
 
-static void iio_event_dev_release(struct device *dev)
-{
-	struct iio_event_interface *ev_int
-		= container_of(dev, struct iio_event_interface, dev);
-	cdev_del(&ev_int->handler.chrdev);
-	iio_device_free_chrdev_minor(MINOR(dev->devt));
-};
-
-static struct device_type iio_event_type = {
-	.release = iio_event_dev_release,
-};
-
 int iio_device_get_chrdev_minor(void)
 {
 	int ret;
@@ -322,34 +290,28 @@ void iio_device_free_chrdev_minor(int val)
 	iio_free_ida_val(&iio_chrdev_ida, val);
 }
 
-static int iio_setup_ev_int(struct iio_event_interface *ev_int,
+int iio_event_getfd(struct iio_dev *indio_dev) {
+	if (indio_dev->event_interfaces == NULL)
+		return -ENODEV;
+
+	mutex_lock(&indio_dev->event_interfaces->event_list_lock);
+	if (test_and_set_bit(IIO_BUSY_BIT_POS,
+			     &indio_dev->event_interfaces->handler.flags )) {
+		mutex_unlock(&indio_dev->event_interfaces->event_list_lock);
+		return -EBUSY;
+	}
+	mutex_unlock(&indio_dev->event_interfaces->event_list_lock);
+	return anon_inode_getfd("iio:event",
+				      &iio_event_chrdev_fileops,
+				      &indio_dev->event_interfaces[0], O_RDONLY);
+}
+
+static void iio_setup_ev_int(struct iio_event_interface *ev_int,
 			    const char *dev_name,
 			    int index,
 			    struct module *owner,
 			    struct device *dev)
 {
-	int ret, minor;
-
-	ev_int->dev.bus = &iio_bus_type;
-	ev_int->dev.parent = dev;
-	ev_int->dev.type = &iio_event_type;
-	device_initialize(&ev_int->dev);
-
-	minor = iio_device_get_chrdev_minor();
-	if (minor < 0) {
-		ret = minor;
-		goto error_device_put;
-	}
-	ev_int->dev.devt = MKDEV(MAJOR(iio_devt), minor);
-	dev_set_name(&ev_int->dev, "%s:event%d", dev_name, index);
-
-	ret = device_add(&ev_int->dev);
-	if (ret)
-		goto error_free_minor;
-
-	cdev_init(&ev_int->handler.chrdev, &iio_event_chrdev_fileops);
-	ev_int->handler.chrdev.owner = owner;
-
 	mutex_init(&ev_int->event_list_lock);
 	/* discussion point - make this variable? */
 	ev_int->max_events = 10;
@@ -358,27 +320,6 @@ static int iio_setup_ev_int(struct iio_event_interface *ev_int,
 	init_waitqueue_head(&ev_int->wait);
 	ev_int->handler.private = ev_int;
 	ev_int->handler.flags = 0;
-
-	ret = cdev_add(&ev_int->handler.chrdev, ev_int->dev.devt, 1);
-	if (ret)
-		goto error_unreg_device;
-
-	return 0;
-
-error_unreg_device:
-	device_unregister(&ev_int->dev);
-error_free_minor:
-	iio_device_free_chrdev_minor(minor);
-error_device_put:
-	put_device(&ev_int->dev);
-
-	return ret;
-}
-
-static void iio_free_ev_int(struct iio_event_interface *ev_int)
-{
-	device_unregister(&ev_int->dev);
-	put_device(&ev_int->dev);
 }
 
 static int __init iio_init(void)
@@ -955,7 +896,7 @@ static int iio_device_add_event_sysfs(struct iio_dev *dev_info,
 			printk(KERN_INFO "currently unhandled type of event\n");
 		}
 		ret = __iio_add_chan_devattr(postfix,
-					     NULL,
+					     "events",
 					     chan,
 					     &iio_ev_state_show,
 					     iio_ev_state_store,
@@ -965,7 +906,7 @@ static int iio_device_add_event_sysfs(struct iio_dev *dev_info,
 					       extending the bitmask - but
 					       how far*/
 					     0,
-					     &dev_info->event_interfaces[0].dev,
+					     &dev_info->dev,
 					     &dev_info->event_interfaces[0].
 					     dev_attr_list);
 		kfree(postfix);
@@ -979,13 +920,12 @@ static int iio_device_add_event_sysfs(struct iio_dev *dev_info,
 			ret = -ENOMEM;
 			goto error_ret;
 		}
-		ret = __iio_add_chan_devattr(postfix, NULL, chan,
+		ret = __iio_add_chan_devattr(postfix, "events", chan,
 					     iio_ev_value_show,
 					     iio_ev_value_store,
 					     mask,
 					     0,
-					     &dev_info->event_interfaces[0]
-					     .dev,
+					     &dev_info->dev,
 					     &dev_info->event_interfaces[0]
 					     .dev_attr_list);
 		kfree(postfix);
@@ -1005,8 +945,7 @@ static inline void __iio_remove_event_config_attrs(struct iio_dev *dev_info,
 	list_for_each_entry_safe(p, n,
 				 &dev_info->event_interfaces[i].
 				 dev_attr_list, l) {
-		sysfs_remove_file_from_group(&dev_info
-					     ->event_interfaces[i].dev.kobj,
+		sysfs_remove_file_from_group(&dev_info->dev.kobj,
 					     &p->dev_attr.attr,
 					     NULL);
 		kfree(p->dev_attr.attr.name);
@@ -1037,6 +976,15 @@ error_clear_attrs:
 	return ret;
 }
 
+static struct attribute *iio_events_dummy_attrs[] = {
+	NULL
+};
+
+static struct attribute_group iio_events_dummy_group = {
+	.name = "events",
+	.attrs = iio_events_dummy_attrs
+};
+
 static int iio_device_register_eventset(struct iio_dev *dev_info)
 {
 	int ret = 0, i, j;
@@ -1054,42 +1002,34 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
 	}
 
 	for (i = 0; i < dev_info->info->num_interrupt_lines; i++) {
-		ret = iio_setup_ev_int(&dev_info->event_interfaces[i],
-				       dev_name(&dev_info->dev),
-				       i,
-				       dev_info->info->driver_module,
-				       &dev_info->dev);
-		if (ret) {
-			dev_err(&dev_info->dev,
-				"Could not get chrdev interface\n");
-			goto error_free_setup_event_lines;
-		}
-
-		dev_set_drvdata(&dev_info->event_interfaces[i].dev,
-				(void *)dev_info);
+		//clean up parameters for this
+		iio_setup_ev_int(&dev_info->event_interfaces[i],
+				 dev_name(&dev_info->dev),
+				 i,
+				 dev_info->info->driver_module,
+				 &dev_info->dev);
 
 		if (dev_info->info->event_attrs != NULL)
-			ret = sysfs_create_group(&dev_info
-						 ->event_interfaces[i]
-						 .dev.kobj,
+			ret = sysfs_create_group(&dev_info->dev.kobj,
 						 &dev_info->info
 						 ->event_attrs[i]);
-
+		else
+			ret = sysfs_create_group(&dev_info->dev.kobj,
+						 &iio_events_dummy_group);
 		if (ret) {
 			dev_err(&dev_info->dev,
 				"Failed to register sysfs for event attrs");
-			iio_free_ev_int(&dev_info->event_interfaces[i]);
 			goto error_free_setup_event_lines;
 		}
 		ret = __iio_add_event_config_attrs(dev_info, i);
 		if (ret) {
 			if (dev_info->info->event_attrs != NULL)
-				sysfs_remove_group(&dev_info
-						   ->event_interfaces[i]
-						   .dev.kobj,
+				sysfs_remove_group(&dev_info->dev.kobj,
 						   &dev_info->info
 						   ->event_attrs[i]);
-			iio_free_ev_int(&dev_info->event_interfaces[i]);
+			else
+				sysfs_remove_group(&dev_info->dev.kobj,
+						   &iio_events_dummy_group);
 			goto error_free_setup_event_lines;
 		}
 	}
@@ -1099,11 +1039,12 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
 error_free_setup_event_lines:
 	for (j = 0; j < i; j++) {
 		__iio_remove_event_config_attrs(dev_info, j);
-		if (dev_info->info->event_attrs != NULL)
-			sysfs_remove_group(&dev_info
-					   ->event_interfaces[j].dev.kobj,
+		if (dev_info->info->event_attrs != NULL) {
+			sysfs_remove_group(&dev_info->dev.kobj,
 					   &dev_info->info->event_attrs[j]);
-		iio_free_ev_int(&dev_info->event_interfaces[j]);
+			sysfs_remove_group(&dev_info->dev.kobj,
+					   &iio_events_dummy_group);
+		}
 	}
 	kfree(dev_info->event_interfaces);
 error_ret:
@@ -1120,10 +1061,11 @@ static void iio_device_unregister_eventset(struct iio_dev *dev_info)
 	for (i = 0; i < dev_info->info->num_interrupt_lines; i++) {
 		__iio_remove_event_config_attrs(dev_info, i);
 		if (dev_info->info->event_attrs != NULL)
-			sysfs_remove_group(&dev_info
-					   ->event_interfaces[i].dev.kobj,
+			sysfs_remove_group(&dev_info->dev.kobj,
 					   &dev_info->info->event_attrs[i]);
-		iio_free_ev_int(&dev_info->event_interfaces[i]);
+		else
+			sysfs_remove_group(&dev_info->dev.kobj,
+					   &iio_events_dummy_group);
 	}
 	kfree(dev_info->event_interfaces);
 }
diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index dce50b1..3c1b7f7 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -93,13 +93,34 @@ static unsigned int iio_ring_poll(struct file *filp,
 	return 0;
 }
 
-static const struct file_operations iio_ring_fileops = {
+/* Somewhat of a cross file organization violation - ioctls here are actually
+ * event related */
+static long iio_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+{
+
+	struct iio_ring_buffer *rb = f->private_data;
+	struct iio_dev *indio_dev = rb->indio_dev;
+	int __user *ip = (int __user *)arg;
+
+	
+	if (cmd == 0) { //cleanup
+		int fd;
+		fd = iio_event_getfd(indio_dev);
+		if (copy_to_user(ip, &fd, sizeof(fd)))
+			return -EFAULT;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+ const struct file_operations iio_ring_fileops = {
 	.read = iio_ring_read_first_n_outer,
 	.release = iio_ring_release,
 	.open = iio_ring_open,
 	.poll = iio_ring_poll,
 	.owner = THIS_MODULE,
 	.llseek = noop_llseek,
+	.unlocked_ioctl = iio_ioctl,
 };
 
 void iio_ring_access_release(struct device *dev)
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/7] staging:iio: squash chrdev handler remains into users.
  2011-07-18 13:49 [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device Jonathan Cameron
                   ` (3 preceding siblings ...)
  2011-07-18 13:50 ` [PATCH 4/7] staging:iio: remove specific chrdev for event reading. Get fd from ioctl on buffer Jonathan Cameron
@ 2011-07-18 13:50 ` Jonathan Cameron
  2011-07-18 13:50 ` [PATCH 6/7] staging:iio: push the main buffer chrdev down to the top level Jonathan Cameron
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Jonathan Cameron @ 2011-07-18 13:50 UTC (permalink / raw)
  To: linux-iio; +Cc: arnd, manuel.stahl, device-drivers-devel, Jonathan Cameron

This no longer has any purpose given all chrdevs are pretty much the same
now the event interfaces are done via anon fds

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/chrdev.h            |   19 -----------------
 drivers/staging/iio/industrialio-core.c |   30 +++++++++------------------
 drivers/staging/iio/industrialio-ring.c |   33 ++++++++++++++----------------
 drivers/staging/iio/ring_generic.h      |    5 ++-
 4 files changed, 28 insertions(+), 59 deletions(-)

diff --git a/drivers/staging/iio/chrdev.h b/drivers/staging/iio/chrdev.h
index 8a229e7..4c80180 100644
--- a/drivers/staging/iio/chrdev.h
+++ b/drivers/staging/iio/chrdev.h
@@ -11,25 +11,6 @@
 #define _IIO_CHRDEV_H_
 
 /**
- * struct iio_handler - Structure used to specify file operations
- *			for a particular chrdev
- * @chrdev:	character device structure
- * @id:		the location in the handler table - used for deallocation.
- * @flags:	file operations related flags including busy flag.
- * @private:	handler specific data used by the fileops registered with
- *		the chrdev.
- */
-struct iio_handler {
-	struct cdev	chrdev;
-	int		id;
-	unsigned long	flags;
-	void		*private;
-};
-
-#define iio_cdev_to_handler(cd)				\
-	container_of(cd, struct iio_handler, chrdev)
-
-/**
  * struct iio_event_data - The actual event being pushed to userspace
  * @id:		event identifier
  * @timestamp:	best estimate of time of event occurrence (often from
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 31ebc3a..ca0ad61 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -129,25 +129,24 @@ struct iio_detected_event_list {
 	struct iio_event_data		ev;
 };
 
-
 /**
  * struct iio_event_interface - chrdev interface for an event line
  * @dev:		device assocated with event interface
- * @handler:		fileoperations and related control for the chrdev
  * @wait:		wait queue to allow blocking reads of events
  * @event_list_lock:	mutex to protect the list of detected events
  * @det_events:		list of detected events
  * @max_events:		maximum number of events before new ones are dropped
  * @current_events:	number of events in detected list
+ * @flags:		file operations related flags including busy flag.
  */
 struct iio_event_interface {
-	struct iio_handler			handler;
 	wait_queue_head_t			wait;
 	struct mutex				event_list_lock;
 	struct list_head			det_events;
 	int					max_events;
 	int					current_events;
 	struct list_head dev_attr_list;
+	unsigned long flags;
 };
 
 int iio_push_event(struct iio_dev *dev_info,
@@ -162,7 +161,7 @@ int iio_push_event(struct iio_dev *dev_info,
 
 	/* Does anyone care? */
 	mutex_lock(&ev_int->event_list_lock);
-	if (test_bit(IIO_BUSY_BIT_POS, &ev_int->handler.flags)) {
+	if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {
 		if (ev_int->current_events == ev_int->max_events) {
 			mutex_unlock(&ev_int->event_list_lock);
 			return 0;
@@ -188,6 +187,7 @@ error_ret:
 }
 EXPORT_SYMBOL(iio_push_event);
 
+
 /* This turns up an awful lot */
 ssize_t iio_read_const_attr(struct device *dev,
 			    struct device_attribute *attr,
@@ -207,6 +207,7 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
 	struct iio_detected_event_list *el;
 	int ret;
 	size_t len;
+
 	mutex_lock(&ev_int->event_list_lock);
 	if (list_empty(&ev_int->det_events)) {
 		if (filep->f_flags & O_NONBLOCK) {
@@ -250,8 +251,9 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
 {
 	struct iio_event_interface *ev_int = filep->private_data;
 	struct iio_detected_event_list *el, *t;
+
 	mutex_lock(&ev_int->event_list_lock);
-	clear_bit(IIO_BUSY_BIT_POS, &ev_int->handler.flags);
+	clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
 	/*
 	 * In order to maintain a clean state for reopening,
 	 * clear out any awaiting events. The mask will prevent
@@ -296,7 +298,7 @@ int iio_event_getfd(struct iio_dev *indio_dev) {
 
 	mutex_lock(&indio_dev->event_interfaces->event_list_lock);
 	if (test_and_set_bit(IIO_BUSY_BIT_POS,
-			     &indio_dev->event_interfaces->handler.flags )) {
+			     &indio_dev->event_interfaces->flags )) {
 		mutex_unlock(&indio_dev->event_interfaces->event_list_lock);
 		return -EBUSY;
 	}
@@ -306,11 +308,7 @@ int iio_event_getfd(struct iio_dev *indio_dev) {
 				      &indio_dev->event_interfaces[0], O_RDONLY);
 }
 
-static void iio_setup_ev_int(struct iio_event_interface *ev_int,
-			    const char *dev_name,
-			    int index,
-			    struct module *owner,
-			    struct device *dev)
+static void iio_setup_ev_int(struct iio_event_interface *ev_int)
 {
 	mutex_init(&ev_int->event_list_lock);
 	/* discussion point - make this variable? */
@@ -318,8 +316,6 @@ static void iio_setup_ev_int(struct iio_event_interface *ev_int,
 	ev_int->current_events = 0;
 	INIT_LIST_HEAD(&ev_int->det_events);
 	init_waitqueue_head(&ev_int->wait);
-	ev_int->handler.private = ev_int;
-	ev_int->handler.flags = 0;
 }
 
 static int __init iio_init(void)
@@ -1002,13 +998,7 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
 	}
 
 	for (i = 0; i < dev_info->info->num_interrupt_lines; i++) {
-		//clean up parameters for this
-		iio_setup_ev_int(&dev_info->event_interfaces[i],
-				 dev_name(&dev_info->dev),
-				 i,
-				 dev_info->info->driver_module,
-				 &dev_info->dev);
-
+		iio_setup_ev_int(&dev_info->event_interfaces[i]);
 		if (dev_info->info->event_attrs != NULL)
 			ret = sysfs_create_group(&dev_info->dev.kobj,
 						 &dev_info->info
diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index 3c1b7f7..e478a5c 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -32,11 +32,10 @@
  **/
 static int iio_ring_open(struct inode *inode, struct file *filp)
 {
-	struct iio_handler *hand
-		= container_of(inode->i_cdev, struct iio_handler, chrdev);
-	struct iio_ring_buffer *rb = hand->private;
-
-	filp->private_data = hand->private;
+	struct iio_ring_buffer *rb
+		= container_of(inode->i_cdev,
+			       struct iio_ring_buffer, chrdev);
+	filp->private_data = rb;
 	if (rb->access->mark_in_use)
 		rb->access->mark_in_use(rb);
 
@@ -51,11 +50,11 @@ static int iio_ring_open(struct inode *inode, struct file *filp)
  **/
 static int iio_ring_release(struct inode *inode, struct file *filp)
 {
-	struct cdev *cd = inode->i_cdev;
-	struct iio_handler *hand = iio_cdev_to_handler(cd);
-	struct iio_ring_buffer *rb = hand->private;
+	struct iio_ring_buffer *rb
+		= container_of(inode->i_cdev,
+			       struct iio_ring_buffer, chrdev);
 
-	clear_bit(IIO_BUSY_BIT_POS, &rb->access_handler.flags);
+	clear_bit(IIO_BUSY_BIT_POS, &rb->flags);
 	if (rb->access->unmark_in_use)
 		rb->access->unmark_in_use(rb);
 
@@ -101,10 +100,9 @@ static long iio_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
 	struct iio_ring_buffer *rb = f->private_data;
 	struct iio_dev *indio_dev = rb->indio_dev;
 	int __user *ip = (int __user *)arg;
+	int fd;
 
-	
-	if (cmd == 0) { //cleanup
-		int fd;
+	if (cmd == 0) {
 		fd = iio_event_getfd(indio_dev);
 		if (copy_to_user(ip, &fd, sizeof(fd)))
 			return -EFAULT;
@@ -127,7 +125,7 @@ void iio_ring_access_release(struct device *dev)
 {
 	struct iio_ring_buffer *buf
 		= container_of(dev, struct iio_ring_buffer, dev);
-	cdev_del(&buf->access_handler.chrdev);
+	cdev_del(&buf->chrdev);
 	iio_device_free_chrdev_minor(MINOR(dev->devt));
 }
 EXPORT_SYMBOL(iio_ring_access_release);
@@ -139,7 +137,7 @@ __iio_request_ring_buffer_chrdev(struct iio_ring_buffer *buf,
 {
 	int ret;
 
-	buf->access_handler.flags = 0;
+	buf->flags = 0;
 	buf->dev.bus = &iio_bus_type;
 	device_initialize(&buf->dev);
 
@@ -156,9 +154,9 @@ __iio_request_ring_buffer_chrdev(struct iio_ring_buffer *buf,
 		printk(KERN_ERR "failed to add the ring dev\n");
 		goto error_device_put;
 	}
-	cdev_init(&buf->access_handler.chrdev, &iio_ring_fileops);
-	buf->access_handler.chrdev.owner = owner;
-	ret = cdev_add(&buf->access_handler.chrdev, buf->dev.devt, 1);
+	cdev_init(&buf->chrdev, &iio_ring_fileops);
+	buf->chrdev.owner = owner;
+	ret = cdev_add(&buf->chrdev, buf->dev.devt, 1);
 	if (ret) {
 		printk(KERN_ERR "failed to allocate ring chrdev\n");
 		goto error_device_unregister;
@@ -182,7 +180,6 @@ void iio_ring_buffer_init(struct iio_ring_buffer *ring,
 			  struct iio_dev *dev_info)
 {
 	ring->indio_dev = dev_info;
-	ring->access_handler.private = ring;
 	init_waitqueue_head(&ring->pollq);
 }
 EXPORT_SYMBOL(iio_ring_buffer_init);
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index d103262..2efebb7 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -85,13 +85,13 @@ struct iio_ring_setup_ops {
  * @scan_count:	[INTERN] the number of elements in the current scan mode
  * @scan_mask:		[INTERN] bitmask used in masking scan mode elements
  * @scan_timestamp:	[INTERN] does the scan mode include a timestamp
- * @access_handler:	[INTERN] chrdev access handling
  * @access:		[DRIVER] ring access functions associated with the
  *			implementation.
  * @preenable:		[DRIVER] function to run prior to marking ring enabled
  * @postenable:		[DRIVER] function to run after marking ring enabled
  * @predisable:		[DRIVER] function to run prior to marking ring disabled
  * @postdisable:	[DRIVER] function to run after marking ring disabled
+ * @flags:		[INTERN] file operations related flags including busy flag.
  **/
 struct iio_ring_buffer {
 	struct device				dev;
@@ -104,13 +104,14 @@ struct iio_ring_buffer {
 	int					scan_count;
 	unsigned long				scan_mask;
 	bool					scan_timestamp;
-	struct iio_handler			access_handler;
 	const struct iio_ring_access_funcs	*access;
 	const struct iio_ring_setup_ops		*setup_ops;
 	struct list_head			scan_el_dev_attr_list;
 
 	wait_queue_head_t			pollq;
 	bool					stufftoread;
+	unsigned long				flags;
+	struct cdev				chrdev;
 };
 
 /**
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 6/7] staging:iio: push the main buffer chrdev down to the top level.
  2011-07-18 13:49 [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device Jonathan Cameron
                   ` (4 preceding siblings ...)
  2011-07-18 13:50 ` [PATCH 5/7] staging:iio: squash chrdev handler remains into users Jonathan Cameron
@ 2011-07-18 13:50 ` Jonathan Cameron
  2011-07-18 13:50 ` [PATCH 7/7] staging:iio: remove now defunct header definitions and add some statics Jonathan Cameron
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Jonathan Cameron @ 2011-07-18 13:50 UTC (permalink / raw)
  To: linux-iio; +Cc: arnd, manuel.stahl, device-drivers-devel, Jonathan Cameron

Sorry all, this one is very invasive, though the driver changes are
just trivial interface fixes. Not all done yet.
---
 drivers/staging/iio/Documentation/generic_buffer.c |   11 +-
 drivers/staging/iio/Documentation/iio_utils.h      |    2 +-
 drivers/staging/iio/accel/adis16201_core.c         |    6 +-
 drivers/staging/iio/accel/adis16203_core.c         |    6 +-
 drivers/staging/iio/accel/adis16204_core.c         |    6 +-
 drivers/staging/iio/accel/adis16209_core.c         |    6 +-
 drivers/staging/iio/accel/adis16240_core.c         |    6 +-
 drivers/staging/iio/accel/lis3l02dq_core.c         |    6 +-
 drivers/staging/iio/accel/sca3000_core.c           |    4 +-
 drivers/staging/iio/adc/ad7298_core.c              |    4 +-
 drivers/staging/iio/adc/ad7476_core.c              |    4 +-
 drivers/staging/iio/adc/ad7606_core.c              |    4 +-
 drivers/staging/iio/adc/ad7793.c                   |    6 +-
 drivers/staging/iio/adc/ad7887_core.c              |    4 +-
 drivers/staging/iio/adc/ad799x_core.c              |    4 +-
 drivers/staging/iio/adc/max1363_core.c             |    6 +-
 drivers/staging/iio/gyro/adis16260_core.c          |    6 +-
 drivers/staging/iio/iio.h                          |    1 +
 drivers/staging/iio/iio_core.h                     |   32 +++
 drivers/staging/iio/imu/adis16400_core.c           |    6 +-
 drivers/staging/iio/industrialio-core.c            |   62 +++++-
 drivers/staging/iio/industrialio-ring.c            |  236 ++++++--------------
 drivers/staging/iio/kfifo_buf.c                    |   35 ++--
 drivers/staging/iio/meter/ade7758_core.c           |    2 +-
 drivers/staging/iio/ring_generic.h                 |   24 +--
 drivers/staging/iio/ring_sw.c                      |   23 +--
 26 files changed, 245 insertions(+), 267 deletions(-)

diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c
index f82894f..c6f5822 100644
--- a/drivers/staging/iio/Documentation/generic_buffer.c
+++ b/drivers/staging/iio/Documentation/generic_buffer.c
@@ -173,7 +173,7 @@ int main(int argc, char **argv)
 		return -1;
 
 	/* Find the device requested */
-	dev_num = find_type_by_name(device_name, "device");
+	dev_num = find_type_by_name(device_name, "iio:device");
 	if (dev_num < 0) {
 		printf("Failed to find the %s\n", device_name);
 		ret = -ENODEV;
@@ -181,7 +181,7 @@ int main(int argc, char **argv)
 	}
 	printf("iio device number being used is %d\n", dev_num);
 
-	asprintf(&dev_dir_name, "%sdevice%d", iio_dir, dev_num);
+	asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num);
 	if (trigger_name == NULL) {
 		/*
 		 * Build the trigger name. If it is device associated it's
@@ -212,6 +212,7 @@ int main(int argc, char **argv)
 	ret = build_channel_array(dev_dir_name, &infoarray, &num_channels);
 	if (ret) {
 		printf("Problem reading scan element information\n");
+		printf("diag %s\n", dev_dir_name);
 		goto error_free_triggername;
 	}
 
@@ -220,7 +221,7 @@ int main(int argc, char **argv)
 	 * As we know that the lis3l02dq has only one buffer this may
 	 * be built rather than found.
 	 */
-	ret = asprintf(&buf_dir_name, "%sdevice%d:buffer0", iio_dir, dev_num);
+	ret = asprintf(&buf_dir_name, "%siio:device%d/buffer", iio_dir, dev_num);
 	if (ret < 0) {
 		ret = -ENOMEM;
 		goto error_free_triggername;
@@ -251,9 +252,7 @@ int main(int argc, char **argv)
 		goto error_free_buf_dir_name;
 	}
 
-	ret = asprintf(&buffer_access,
-		       "/dev/device%d:buffer0",
-		       dev_num);
+	ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num);
 	if (ret < 0) {
 		ret = -ENOMEM;
 		goto error_free_data;
diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h
index 150f440..75938b2 100644
--- a/drivers/staging/iio/Documentation/iio_utils.h
+++ b/drivers/staging/iio/Documentation/iio_utils.h
@@ -16,7 +16,7 @@
 
 #define IIO_MAX_NAME_LENGTH 30
 
-#define FORMAT_SCAN_ELEMENTS_DIR "%s:buffer0/scan_elements"
+#define FORMAT_SCAN_ELEMENTS_DIR "%s/scan_elements"
 #define FORMAT_TYPE_FILE "%s_type"
 
 const char *iio_dir = "/sys/bus/iio/devices/";
diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c
index 16b388b..07d2bc9 100644
--- a/drivers/staging/iio/accel/adis16201_core.c
+++ b/drivers/staging/iio/accel/adis16201_core.c
@@ -496,7 +496,7 @@ static int __devinit adis16201_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  adis16201_channels,
 					  ARRAY_SIZE(adis16201_channels));
 	if (ret) {
@@ -519,7 +519,7 @@ static int __devinit adis16201_probe(struct spi_device *spi)
 error_remove_trigger:
 	adis16201_remove_trigger(indio_dev);
 error_uninitialize_ring:
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 error_unreg_ring_funcs:
 	adis16201_unconfigure_ring(indio_dev);
 error_free_dev:
@@ -536,7 +536,7 @@ static int adis16201_remove(struct spi_device *spi)
 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
 
 	adis16201_remove_trigger(indio_dev);
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	adis16201_unconfigure_ring(indio_dev);
 
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c
index 034115a..2e03b48 100644
--- a/drivers/staging/iio/accel/adis16203_core.c
+++ b/drivers/staging/iio/accel/adis16203_core.c
@@ -446,7 +446,7 @@ static int __devinit adis16203_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  adis16203_channels,
 					  ARRAY_SIZE(adis16203_channels));
 	if (ret) {
@@ -469,7 +469,7 @@ static int __devinit adis16203_probe(struct spi_device *spi)
 error_remove_trigger:
 	adis16203_remove_trigger(indio_dev);
 error_uninitialize_ring:
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 error_unreg_ring_funcs:
 	adis16203_unconfigure_ring(indio_dev);
 error_free_dev:
@@ -486,7 +486,7 @@ static int adis16203_remove(struct spi_device *spi)
 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
 
 	adis16203_remove_trigger(indio_dev);
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	adis16203_unconfigure_ring(indio_dev);
 
diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c
index c5a46fd..f7cd9d1 100644
--- a/drivers/staging/iio/accel/adis16204_core.c
+++ b/drivers/staging/iio/accel/adis16204_core.c
@@ -521,7 +521,7 @@ static int __devinit adis16204_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  adis16204_channels,
 					  ARRAY_SIZE(adis16204_channels));
 	if (ret) {
@@ -544,7 +544,7 @@ static int __devinit adis16204_probe(struct spi_device *spi)
 error_remove_trigger:
 	adis16204_remove_trigger(indio_dev);
 error_uninitialize_ring:
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 error_unreg_ring_funcs:
 	adis16204_unconfigure_ring(indio_dev);
 error_free_dev:
@@ -561,7 +561,7 @@ static int adis16204_remove(struct spi_device *spi)
 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
 
 	adis16204_remove_trigger(indio_dev);
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	adis16204_unconfigure_ring(indio_dev);
 
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index 70a7e29..8b8ba5a 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -494,7 +494,7 @@ static int __devinit adis16209_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  adis16209_channels,
 					  ARRAY_SIZE(adis16209_channels));
 	if (ret) {
@@ -517,7 +517,7 @@ static int __devinit adis16209_probe(struct spi_device *spi)
 error_remove_trigger:
 	adis16209_remove_trigger(indio_dev);
 error_uninitialize_ring:
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 error_unreg_ring_funcs:
 	adis16209_unconfigure_ring(indio_dev);
 error_free_dev:
@@ -536,7 +536,7 @@ static int adis16209_remove(struct spi_device *spi)
 	flush_scheduled_work();
 
 	adis16209_remove_trigger(indio_dev);
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	adis16209_unconfigure_ring(indio_dev);
 
diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c
index b9dd92d..a5c3ed7 100644
--- a/drivers/staging/iio/accel/adis16240_core.c
+++ b/drivers/staging/iio/accel/adis16240_core.c
@@ -547,7 +547,7 @@ static int __devinit adis16240_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  adis16240_channels,
 					  ARRAY_SIZE(adis16240_channels));
 	if (ret) {
@@ -570,7 +570,7 @@ static int __devinit adis16240_probe(struct spi_device *spi)
 error_remove_trigger:
 	adis16240_remove_trigger(indio_dev);
 error_uninitialize_ring:
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 error_unreg_ring_funcs:
 	adis16240_unconfigure_ring(indio_dev);
 error_free_dev:
@@ -590,7 +590,7 @@ static int adis16240_remove(struct spi_device *spi)
 	flush_scheduled_work();
 
 	adis16240_remove_trigger(indio_dev);
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	adis16240_unconfigure_ring(indio_dev);
 
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 7f946aa..062632b 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -695,7 +695,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  lis3l02dq_channels,
 					  ARRAY_SIZE(lis3l02dq_channels));
 	if (ret) {
@@ -731,7 +731,7 @@ error_free_interrupt:
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
 		free_irq(st->us->irq, indio_dev);
 error_uninitialize_ring:
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 error_unreg_ring_funcs:
 	lis3l02dq_unconfigure_ring(indio_dev);
 error_free_dev:
@@ -788,7 +788,7 @@ static int lis3l02dq_remove(struct spi_device *spi)
 		free_irq(st->us->irq, indio_dev);
 
 	lis3l02dq_remove_trigger(indio_dev);
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 	lis3l02dq_unconfigure_ring(indio_dev);
 	iio_device_unregister(indio_dev);
 
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index d5684fc..1669eaf 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -1155,7 +1155,7 @@ static int __devinit sca3000_probe(struct spi_device *spi)
 	if (ret < 0)
 		goto error_free_dev;
 	regdone = 1;
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  sca3000_channels,
 					  ARRAY_SIZE(sca3000_channels));
 	if (ret < 0)
@@ -1180,7 +1180,7 @@ error_free_irq:
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
 		free_irq(spi->irq, indio_dev);
 error_unregister_ring:
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 error_unregister_dev:
 error_free_dev:
 	if (regdone)
diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c
index 21d1931..d0bcdb1 100644
--- a/drivers/staging/iio/adc/ad7298_core.c
+++ b/drivers/staging/iio/adc/ad7298_core.c
@@ -222,7 +222,7 @@ static int __devinit ad7298_probe(struct spi_device *spi)
 		goto error_disable_reg;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  &ad7298_channels[1], /* skip temp0 */
 					  ARRAY_SIZE(ad7298_channels) - 1);
 	if (ret)
@@ -252,7 +252,7 @@ static int __devexit ad7298_remove(struct spi_device *spi)
 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
 	struct ad7298_state *st = iio_priv(indio_dev);
 
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 	ad7298_ring_cleanup(indio_dev);
 	iio_device_unregister(indio_dev);
 	if (!IS_ERR(st->reg)) {
diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c
index f2fdd48..3ff2924 100644
--- a/drivers/staging/iio/adc/ad7476_core.c
+++ b/drivers/staging/iio/adc/ad7476_core.c
@@ -185,7 +185,7 @@ static int __devinit ad7476_probe(struct spi_device *spi)
 	if (ret)
 		goto error_disable_reg;
 
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  st->chip_info->channel,
 					  ARRAY_SIZE(st->chip_info->channel));
 	if (ret)
@@ -214,7 +214,7 @@ static int ad7476_remove(struct spi_device *spi)
 	/* copy needed as st will have been freed */
 	struct regulator *reg = st->reg;
 
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 	ad7476_ring_cleanup(indio_dev);
 	iio_device_unregister(indio_dev);
 	if (!IS_ERR(reg)) {
diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c
index dcdb180..f7840cf 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -505,7 +505,7 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
 		goto error_free_irq;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  indio_dev->channels,
 					  indio_dev->num_channels);
 	if (ret)
@@ -540,7 +540,7 @@ int ad7606_remove(struct iio_dev *indio_dev)
 {
 	struct ad7606_state *st = iio_priv(indio_dev);
 
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 	ad7606_ring_cleanup(indio_dev);
 
 	free_irq(st->irq, indio_dev);
diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c
index 1bcb3eb..ed993e3 100644
--- a/drivers/staging/iio/adc/ad7793.c
+++ b/drivers/staging/iio/adc/ad7793.c
@@ -895,7 +895,7 @@ static int __devinit ad7793_probe(struct spi_device *spi)
 	if (ret)
 		goto error_unreg_ring;
 
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  indio_dev->channels,
 					  indio_dev->num_channels);
 	if (ret)
@@ -908,7 +908,7 @@ static int __devinit ad7793_probe(struct spi_device *spi)
 	return 0;
 
 error_uninitialize_ring:
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 error_remove_trigger:
 	ad7793_remove_trigger(indio_dev);
 error_unreg_ring:
@@ -933,7 +933,7 @@ static int ad7793_remove(struct spi_device *spi)
 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
 	struct ad7793_state *st = iio_priv(indio_dev);
 
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 	ad7793_remove_trigger(indio_dev);
 	ad7793_ring_cleanup(indio_dev);
 
diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c
index a7da9e6..99c8828 100644
--- a/drivers/staging/iio/adc/ad7887_core.c
+++ b/drivers/staging/iio/adc/ad7887_core.c
@@ -193,7 +193,7 @@ static int __devinit ad7887_probe(struct spi_device *spi)
 		goto error_disable_reg;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  indio_dev->channels,
 					  indio_dev->num_channels);
 	if (ret)
@@ -221,7 +221,7 @@ static int ad7887_remove(struct spi_device *spi)
 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
 	struct ad7887_state *st = iio_priv(indio_dev);
 
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 	ad7887_ring_cleanup(indio_dev);
 	if (!IS_ERR(st->reg)) {
 		regulator_disable(st->reg);
diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c
index 2438ed5..a509e3d 100644
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/staging/iio/adc/ad799x_core.c
@@ -705,7 +705,7 @@ static int __devinit ad799x_probe(struct i2c_client *client,
 		goto error_cleanup_ring;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  indio_dev->channels,
 					  indio_dev->num_channels);
 	if (ret)
@@ -749,7 +749,7 @@ static __devexit int ad799x_remove(struct i2c_client *client)
 	if (client->irq > 0)
 		free_irq(client->irq, indio_dev);
 
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 	ad799x_ring_cleanup(indio_dev);
 	if (!IS_ERR(st->reg)) {
 		regulator_disable(st->reg);
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index 79ae4a0..037fcc1 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -1310,7 +1310,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
 	if (ret)
 		goto error_cleanup_ring;
 	regdone = 1;
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  st->chip_info->channels,
 					  st->chip_info->num_channels);
 	if (ret)
@@ -1331,7 +1331,7 @@ static int __devinit max1363_probe(struct i2c_client *client,
 	return 0;
 
 error_uninit_ring:
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 error_cleanup_ring:
 	max1363_ring_cleanup(indio_dev);
 error_free_available_scan_masks:
@@ -1357,7 +1357,7 @@ static int max1363_remove(struct i2c_client *client)
 
 	if (client->irq)
 		free_irq(st->client->irq, indio_dev);
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 	max1363_ring_cleanup(indio_dev);
 	kfree(indio_dev->available_scan_masks);
 	if (!IS_ERR(reg)) {
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c
index b09b367..0938afd 100644
--- a/drivers/staging/iio/gyro/adis16260_core.c
+++ b/drivers/staging/iio/gyro/adis16260_core.c
@@ -624,7 +624,7 @@ static int __devinit adis16260_probe(struct spi_device *spi)
 	if (ret)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  indio_dev->channels,
 					  ARRAY_SIZE(adis16260_channels_x));
 	if (ret) {
@@ -647,7 +647,7 @@ static int __devinit adis16260_probe(struct spi_device *spi)
 error_remove_trigger:
 	adis16260_remove_trigger(indio_dev);
 error_uninitialize_ring:
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 error_unreg_ring_funcs:
 	adis16260_unconfigure_ring(indio_dev);
 error_free_dev:
@@ -671,7 +671,7 @@ static int adis16260_remove(struct spi_device *spi)
 	flush_scheduled_work();
 
 	adis16260_remove_trigger(indio_dev);
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	adis16260_unconfigure_ring(indio_dev);
 
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
index 308b100..b4f0989 100644
--- a/drivers/staging/iio/iio.h
+++ b/drivers/staging/iio/iio.h
@@ -290,6 +290,7 @@ struct iio_dev {
 	struct list_head channel_attr_list;
 	const char *name;
 	const struct iio_info *info;
+	struct cdev				chrdev;
 };
 
 /**
diff --git a/drivers/staging/iio/iio_core.h b/drivers/staging/iio/iio_core.h
index 00e894d..380d782 100644
--- a/drivers/staging/iio/iio_core.h
+++ b/drivers/staging/iio/iio_core.h
@@ -10,6 +10,9 @@
  * drivers.
  */
 
+#ifndef _IIO_CORE_H_
+#define _IIO_CORE_H_
+
 /**
  * iio_device_get_chrdev_minor() - get an unused minor number
  **/
@@ -46,3 +49,32 @@ int __iio_add_chan_devattr(const char *postfix,
 
 /* Event interface flags */
 #define IIO_BUSY_BIT_POS 1
+
+#ifdef CONFIG_IIO_RING_BUFFER
+struct poll_table_struct;
+
+void iio_chrdev_ring_open(struct iio_dev *indio_dev);
+void iio_chrdev_ring_release(struct iio_dev *indio_dev);
+
+unsigned int iio_ring_poll(struct file *filp,
+			   struct poll_table_struct *wait);
+ssize_t iio_ring_read_first_n_outer(struct file *filp, char __user *buf,
+				    size_t n, loff_t *f_ps);
+
+
+#define iio_ring_poll_addr &iio_ring_poll
+#define iio_ring_read_first_n_outer_addr &iio_ring_read_first_n_outer
+
+#else
+
+static inline void iio_chrdev_ring_open(struct iio_dev *indio_dev)
+{}
+static inline void iio_chrdev_ring_release(struct iio_dev *indio_dev)
+{}
+
+#define iio_ring_poll_addr NULL
+#define iio_ring_read_first_n_outer_addr NULL
+
+#endif
+
+#endif
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index 371eb01..bc740b0 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -852,7 +852,7 @@ static int __devinit adis16400_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  st->variant->channels,
 					  st->variant->num_channels);
 	if (ret) {
@@ -876,7 +876,7 @@ error_remove_trigger:
 	if (indio_dev->modes & INDIO_RING_TRIGGERED)
 		adis16400_remove_trigger(indio_dev);
 error_uninitialize_ring:
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 error_unreg_ring_funcs:
 	adis16400_unconfigure_ring(indio_dev);
 error_free_dev:
@@ -899,7 +899,7 @@ static int adis16400_remove(struct spi_device *spi)
 		goto err_ret;
 
 	adis16400_remove_trigger(indio_dev);
-	iio_ring_buffer_unregister(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev);
 	adis16400_unconfigure_ring(indio_dev);
 	iio_device_unregister(indio_dev);
 
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index ca0ad61..7cd0485 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -1063,6 +1063,8 @@ static void iio_device_unregister_eventset(struct iio_dev *dev_info)
 static void iio_dev_release(struct device *device)
 {
 	struct iio_dev *dev_info = container_of(device, struct iio_dev, dev);
+	cdev_del(&dev_info->chrdev);
+	iio_device_free_chrdev_minor(MINOR(device->devt));
 	iio_put();
 	kfree(dev_info);
 }
@@ -1107,6 +1109,55 @@ void iio_free_device(struct iio_dev *dev)
 }
 EXPORT_SYMBOL(iio_free_device);
 
+/**
+ * iio_chrdev_open() - chrdev file open for ring buffer access and ioctls
+ **/
+static int iio_chrdev_open(struct inode *inode, struct file *filp)
+{
+	struct iio_dev *dev_info = container_of(inode->i_cdev,
+						struct iio_dev, chrdev);
+	filp->private_data = dev_info;
+	iio_chrdev_ring_open(dev_info);
+	return 0;
+}
+
+/**
+ * iio_chrdev_release() - chrdev file close ring buffer access and ioctls
+ **/
+static int iio_chrdev_release(struct inode *inode, struct file *filp)
+{
+	iio_chrdev_ring_release(container_of(inode->i_cdev,
+					     struct iio_dev, chrdev));
+	return 0;
+}
+
+/* Somewhat of a cross file organization violation - ioctls here are actually
+ * event related */
+static long iio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	struct iio_dev *indio_dev = filp->private_data;
+	int __user *ip = (int __user *)arg;
+	int fd;
+
+	if (cmd == 0) {
+		fd = iio_event_getfd(indio_dev);
+		if (copy_to_user(ip, &fd, sizeof(fd)))
+			return -EFAULT;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static const struct file_operations iio_ring_fileops = {
+	.read = iio_ring_read_first_n_outer_addr,
+	.release = iio_chrdev_release,
+	.open = iio_chrdev_open,
+	.poll = iio_ring_poll_addr,
+	.owner = THIS_MODULE,
+	.llseek = noop_llseek,
+	.unlocked_ioctl = iio_ioctl,
+};
+
 int iio_device_register(struct iio_dev *dev_info)
 {
 	int ret;
@@ -1117,8 +1168,14 @@ int iio_device_register(struct iio_dev *dev_info)
 		dev_err(&dev_info->dev, "Failed to get id\n");
 		goto error_ret;
 	}
-	dev_set_name(&dev_info->dev, "device%d", dev_info->id);
+	dev_set_name(&dev_info->dev, "iio:device%d", dev_info->id);
+	ret = iio_device_get_chrdev_minor();
+	if (ret < 0)
+		goto error_free_ida;
 
+	/* configure elements for the chrdev */
+	dev_info->dev.devt = MKDEV(MAJOR(iio_devt), ret);
+	
 	ret = device_add(&dev_info->dev);
 	if (ret)
 		goto error_free_ida;
@@ -1137,6 +1194,9 @@ int iio_device_register(struct iio_dev *dev_info)
 	if (dev_info->modes & INDIO_RING_TRIGGERED)
 		iio_device_register_trigger_consumer(dev_info);
 
+	cdev_init(&dev_info->chrdev, &iio_ring_fileops);
+	dev_info->chrdev.owner = dev_info->info->driver_module;
+	ret = cdev_add(&dev_info->chrdev, dev_info->dev.devt, 1);
 	return 0;
 
 error_free_sysfs:
diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
index e478a5c..8ae53d8 100644
--- a/drivers/staging/iio/industrialio-ring.c
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -24,42 +24,6 @@
 #include "iio_core.h"
 #include "ring_generic.h"
 
-/**
- * iio_ring_open() - chrdev file open for ring buffer access
- *
- * This function relies on all ring buffer implementations having an
- * iio_ring_buffer as their first element.
- **/
-static int iio_ring_open(struct inode *inode, struct file *filp)
-{
-	struct iio_ring_buffer *rb
-		= container_of(inode->i_cdev,
-			       struct iio_ring_buffer, chrdev);
-	filp->private_data = rb;
-	if (rb->access->mark_in_use)
-		rb->access->mark_in_use(rb);
-
-	return 0;
-}
-
-/**
- * iio_ring_release() - chrdev file close ring buffer access
- *
- * This function relies on all ring buffer implementations having an
- * iio_ring_buffer as their first element.
- **/
-static int iio_ring_release(struct inode *inode, struct file *filp)
-{
-	struct iio_ring_buffer *rb
-		= container_of(inode->i_cdev,
-			       struct iio_ring_buffer, chrdev);
-
-	clear_bit(IIO_BUSY_BIT_POS, &rb->flags);
-	if (rb->access->unmark_in_use)
-		rb->access->unmark_in_use(rb);
-
-	return 0;
-}
 
 /**
  * iio_ring_read_first_n_outer() - chrdev read for ring buffer access
@@ -67,10 +31,11 @@ static int iio_ring_release(struct inode *inode, struct file *filp)
  * This function relies on all ring buffer implementations having an
  * iio_ring _bufer as their first element.
  **/
-static ssize_t iio_ring_read_first_n_outer(struct file *filp, char __user *buf,
-				  size_t n, loff_t *f_ps)
+ssize_t iio_ring_read_first_n_outer(struct file *filp, char __user *buf,
+				    size_t n, loff_t *f_ps)
 {
-	struct iio_ring_buffer *rb = filp->private_data;
+	struct iio_dev *indio_dev = filp->private_data;
+	struct iio_ring_buffer *rb = indio_dev->ring;
 
 	if (!rb->access->read_first_n)
 		return -EINVAL;
@@ -80,10 +45,11 @@ static ssize_t iio_ring_read_first_n_outer(struct file *filp, char __user *buf,
 /**
  * iio_ring_poll() - poll the ring to find out if it has data
  */
-static unsigned int iio_ring_poll(struct file *filp,
-				  struct poll_table_struct *wait)
+unsigned int iio_ring_poll(struct file *filp,
+			   struct poll_table_struct *wait)
 {
-	struct iio_ring_buffer *rb = filp->private_data;
+	struct iio_dev *indio_dev = filp->private_data;
+	struct iio_ring_buffer *rb = indio_dev->ring;
 
 	poll_wait(filp, &rb->pollq, wait);
 	if (rb->stufftoread)
@@ -92,88 +58,22 @@ static unsigned int iio_ring_poll(struct file *filp,
 	return 0;
 }
 
-/* Somewhat of a cross file organization violation - ioctls here are actually
- * event related */
-static long iio_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+void iio_chrdev_ring_open(struct iio_dev *indio_dev)
 {
+	struct iio_ring_buffer *rb = indio_dev->ring;
+	if (rb && rb->access->mark_in_use)
+		rb->access->mark_in_use(rb);
 
-	struct iio_ring_buffer *rb = f->private_data;
-	struct iio_dev *indio_dev = rb->indio_dev;
-	int __user *ip = (int __user *)arg;
-	int fd;
-
-	if (cmd == 0) {
-		fd = iio_event_getfd(indio_dev);
-		if (copy_to_user(ip, &fd, sizeof(fd)))
-			return -EFAULT;
-		return 0;
-	}
-	return -EINVAL;
 }
 
- const struct file_operations iio_ring_fileops = {
-	.read = iio_ring_read_first_n_outer,
-	.release = iio_ring_release,
-	.open = iio_ring_open,
-	.poll = iio_ring_poll,
-	.owner = THIS_MODULE,
-	.llseek = noop_llseek,
-	.unlocked_ioctl = iio_ioctl,
-};
-
-void iio_ring_access_release(struct device *dev)
+void iio_chrdev_ring_release(struct iio_dev *indio_dev)
 {
-	struct iio_ring_buffer *buf
-		= container_of(dev, struct iio_ring_buffer, dev);
-	cdev_del(&buf->chrdev);
-	iio_device_free_chrdev_minor(MINOR(dev->devt));
-}
-EXPORT_SYMBOL(iio_ring_access_release);
+	struct iio_ring_buffer *rb = indio_dev->ring;
 
-static inline int
-__iio_request_ring_buffer_chrdev(struct iio_ring_buffer *buf,
-				 struct module *owner,
-				 int id)
-{
-	int ret;
-
-	buf->flags = 0;
-	buf->dev.bus = &iio_bus_type;
-	device_initialize(&buf->dev);
-
-	ret = iio_device_get_chrdev_minor();
-	if (ret < 0)
-		goto error_device_put;
-
-	buf->dev.devt = MKDEV(MAJOR(iio_devt), ret);
-	dev_set_name(&buf->dev, "%s:buffer%d",
-		     dev_name(buf->dev.parent),
-		     id);
-	ret = device_add(&buf->dev);
-	if (ret < 0) {
-		printk(KERN_ERR "failed to add the ring dev\n");
-		goto error_device_put;
-	}
-	cdev_init(&buf->chrdev, &iio_ring_fileops);
-	buf->chrdev.owner = owner;
-	ret = cdev_add(&buf->chrdev, buf->dev.devt, 1);
-	if (ret) {
-		printk(KERN_ERR "failed to allocate ring chrdev\n");
-		goto error_device_unregister;
-	}
-	return 0;
-
-error_device_unregister:
-	device_unregister(&buf->dev);
-error_device_put:
-	put_device(&buf->dev);
-
-	return ret;
-}
+	clear_bit(IIO_BUSY_BIT_POS, &rb->flags);
+	if (rb->access->unmark_in_use)
+		rb->access->unmark_in_use(rb);
 
-static void __iio_free_ring_buffer_chrdev(struct iio_ring_buffer *buf)
-{
-	device_unregister(&buf->dev);
 }
 
 void iio_ring_buffer_init(struct iio_ring_buffer *ring,
@@ -208,9 +108,10 @@ static ssize_t iio_scan_el_show(struct device *dev,
 				char *buf)
 {
 	int ret;
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
 
-	ret = iio_scan_mask_query(ring, to_iio_dev_attr(attr)->address);
+	ret = iio_scan_mask_query(dev_info->ring,
+				  to_iio_dev_attr(attr)->address);
 	if (ret < 0)
 		return ret;
 	return sprintf(buf, "%d\n", ret);
@@ -232,8 +133,8 @@ static ssize_t iio_scan_el_store(struct device *dev,
 {
 	int ret = 0;
 	bool state;
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 
 	state = !(buf[0] == '0');
@@ -266,8 +167,8 @@ static ssize_t iio_scan_el_ts_show(struct device *dev,
 				   struct device_attribute *attr,
 				   char *buf)
 {
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	return sprintf(buf, "%d\n", ring->scan_timestamp);
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	return sprintf(buf, "%d\n", dev_info->ring->scan_timestamp);
 }
 
 static ssize_t iio_scan_el_ts_store(struct device *dev,
@@ -276,26 +177,27 @@ static ssize_t iio_scan_el_ts_store(struct device *dev,
 				    size_t len)
 {
 	int ret = 0;
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	bool state;
+
 	state = !(buf[0] == '0');
 	mutex_lock(&indio_dev->mlock);
 	if (indio_dev->currentmode == INDIO_RING_TRIGGERED) {
 		ret = -EBUSY;
 		goto error_ret;
 	}
-	ring->scan_timestamp = state;
+	indio_dev->ring->scan_timestamp = state;
 error_ret:
 	mutex_unlock(&indio_dev->mlock);
 
 	return ret ? ret : len;
 }
 
-static int iio_ring_add_channel_sysfs(struct iio_ring_buffer *ring,
+static int iio_ring_add_channel_sysfs(struct iio_dev *indio_dev,
 				      const struct iio_chan_spec *chan)
 {
 	int ret;
+	struct iio_ring_buffer *ring = indio_dev->ring;
 
 	ret = __iio_add_chan_devattr("index", "scan_elements",
 				     chan,
@@ -303,7 +205,7 @@ static int iio_ring_add_channel_sysfs(struct iio_ring_buffer *ring,
 				     NULL,
 				     0,
 				     0,
-				     &ring->dev,
+				     &indio_dev->dev,
 				     &ring->scan_el_dev_attr_list);
 	if (ret)
 		goto error_ret;
@@ -314,7 +216,7 @@ static int iio_ring_add_channel_sysfs(struct iio_ring_buffer *ring,
 				     NULL,
 				     0,
 				     0,
-				     &ring->dev,
+				     &indio_dev->dev,
 				     &ring->scan_el_dev_attr_list);
 	if (ret)
 		goto error_ret;
@@ -326,7 +228,7 @@ static int iio_ring_add_channel_sysfs(struct iio_ring_buffer *ring,
 					     &iio_scan_el_store,
 					     chan->scan_index,
 					     0,
-					     &ring->dev,
+					     &indio_dev->dev,
 					     &ring->scan_el_dev_attr_list);
 	else
 		ret = __iio_add_chan_devattr("en", "scan_elements",
@@ -335,16 +237,16 @@ static int iio_ring_add_channel_sysfs(struct iio_ring_buffer *ring,
 					     &iio_scan_el_ts_store,
 					     chan->scan_index,
 					     0,
-					     &ring->dev,
+					     &indio_dev->dev,
 					     &ring->scan_el_dev_attr_list);
 error_ret:
 	return ret;
 }
 
-static void iio_ring_remove_and_free_scan_dev_attr(struct iio_ring_buffer *ring,
+static void iio_ring_remove_and_free_scan_dev_attr(struct iio_dev *indio_dev,
 						   struct iio_dev_attr *p)
 {
-	sysfs_remove_file_from_group(&ring->dev.kobj,
+	sysfs_remove_file_from_group(&indio_dev->dev.kobj,
 				     &p->dev_attr.attr, "scan_elements");
 	kfree(p->dev_attr.attr.name);
 	kfree(p);
@@ -359,71 +261,78 @@ static struct attribute_group iio_scan_el_dummy_group = {
 	.attrs = iio_scan_el_dummy_attrs
 };
 
-static void __iio_ring_attr_cleanup(struct iio_ring_buffer *ring)
+static void __iio_ring_attr_cleanup(struct iio_dev *indio_dev)
 {
 	struct iio_dev_attr *p, *n;
+	struct iio_ring_buffer *ring = indio_dev->ring;
 	int anydynamic = !list_empty(&ring->scan_el_dev_attr_list);
 	list_for_each_entry_safe(p, n,
 				 &ring->scan_el_dev_attr_list, l)
-		iio_ring_remove_and_free_scan_dev_attr(ring, p);
+		iio_ring_remove_and_free_scan_dev_attr(indio_dev, p);
 
 	if (ring->scan_el_attrs)
-		sysfs_remove_group(&ring->dev.kobj,
+		sysfs_remove_group(&indio_dev->dev.kobj,
 				   ring->scan_el_attrs);
 	else if (anydynamic)
-		sysfs_remove_group(&ring->dev.kobj,
+		sysfs_remove_group(&indio_dev->dev.kobj,
 				   &iio_scan_el_dummy_group);
 }
 
-int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
+int iio_ring_buffer_register_ex(struct iio_dev *indio_dev, int id,
 				const struct iio_chan_spec *channels,
 				int num_channels)
 {
+	struct iio_ring_buffer *ring = indio_dev->ring;
 	int ret, i;
 
-	ret = __iio_request_ring_buffer_chrdev(ring, ring->owner, id);
-	if (ret)
-		goto error_ret;
-
 	if (ring->scan_el_attrs) {
-		ret = sysfs_create_group(&ring->dev.kobj,
+		ret = sysfs_create_group(&indio_dev->dev.kobj,
 					 ring->scan_el_attrs);
 		if (ret) {
-			dev_err(&ring->dev,
+			dev_err(&indio_dev->dev,
 				"Failed to add sysfs scan elements\n");
-			goto error_free_ring_buffer_chrdev;
+			goto error_ret;
 		}
 	} else if (channels) {
-		ret = sysfs_create_group(&ring->dev.kobj,
+		ret = sysfs_create_group(&indio_dev->dev.kobj,
 					 &iio_scan_el_dummy_group);
 		if (ret)
-			goto error_free_ring_buffer_chrdev;
+			goto error_ret;
+	}
+	if (ring->attrs) {
+		ret = sysfs_create_group(&indio_dev->dev.kobj,
+					 ring->attrs);
+		if (ret)
+			goto error_cleanup_dynamic;
 	}
 
 	INIT_LIST_HEAD(&ring->scan_el_dev_attr_list);
 	if (channels) {
 		/* new magic */
 		for (i = 0; i < num_channels; i++) {
-			ret = iio_ring_add_channel_sysfs(ring, &channels[i]);
+			ret = iio_ring_add_channel_sysfs(indio_dev, &channels[i]);
 			if (ret < 0)
-				goto error_cleanup_dynamic;
+				goto error_cleanup_group;
 		}
 	}
 
 	return 0;
+error_cleanup_group:
+	if (ring->attrs)
+		sysfs_remove_group(&indio_dev->dev.kobj, ring->attrs);
 error_cleanup_dynamic:
-	__iio_ring_attr_cleanup(ring);
-error_free_ring_buffer_chrdev:
-	__iio_free_ring_buffer_chrdev(ring);
+	__iio_ring_attr_cleanup(indio_dev);
 error_ret:
 	return ret;
 }
 EXPORT_SYMBOL(iio_ring_buffer_register_ex);
 
-void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
+void iio_ring_buffer_unregister(struct iio_dev *indio_dev)
 {
-	__iio_ring_attr_cleanup(ring);
-	__iio_free_ring_buffer_chrdev(ring);
+	if (indio_dev->ring->attrs)
+		sysfs_remove_group(&indio_dev->dev.kobj,
+				   indio_dev->ring->attrs);
+	__iio_ring_attr_cleanup(indio_dev);
 }
 EXPORT_SYMBOL(iio_ring_buffer_unregister);
 
@@ -431,7 +340,8 @@ ssize_t iio_read_ring_length(struct device *dev,
 			     struct device_attribute *attr,
 			     char *buf)
 {
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 
 	if (ring->access->get_length)
 		return sprintf(buf, "%d\n",
@@ -448,7 +358,8 @@ ssize_t iio_write_ring_length(struct device *dev,
 {
 	int ret;
 	ulong val;
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 
 	ret = strict_strtoul(buf, 10, &val);
 	if (ret)
@@ -472,7 +383,8 @@ ssize_t iio_read_ring_bytes_per_datum(struct device *dev,
 			  struct device_attribute *attr,
 			  char *buf)
 {
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 
 	if (ring->access->get_bytes_per_datum)
 		return sprintf(buf, "%d\n",
@@ -490,8 +402,8 @@ ssize_t iio_store_ring_enable(struct device *dev,
 	int ret;
 	bool requested_state, current_state;
 	int previous_mode;
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *dev_info = ring->indio_dev;
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct iio_ring_buffer *ring = dev_info->ring;
 
 	mutex_lock(&dev_info->mlock);
 	previous_mode = dev_info->currentmode;
@@ -583,8 +495,8 @@ ssize_t iio_show_ring_enable(struct device *dev,
 				    struct device_attribute *attr,
 				    char *buf)
 {
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	return sprintf(buf, "%d\n", !!(ring->indio_dev->currentmode
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	return sprintf(buf, "%d\n", !!(dev_info->currentmode
 				       & INDIO_ALL_RING_MODES));
 }
 EXPORT_SYMBOL(iio_show_ring_enable);
diff --git a/drivers/staging/iio/kfifo_buf.c b/drivers/staging/iio/kfifo_buf.c
index 3c9516b..dcd5e36 100644
--- a/drivers/staging/iio/kfifo_buf.c
+++ b/drivers/staging/iio/kfifo_buf.c
@@ -87,25 +87,22 @@ static struct attribute *iio_kfifo_attributes[] = {
 
 static struct attribute_group iio_kfifo_attribute_group = {
 	.attrs = iio_kfifo_attributes,
+	.name = "buffer",
 };
 
-static const struct attribute_group *iio_kfifo_attribute_groups[] = {
-	&iio_kfifo_attribute_group,
-	NULL
-};
 
-static void iio_kfifo_release(struct device *dev)
-{
-	struct iio_ring_buffer *r = to_iio_ring_buffer(dev);
-	struct iio_kfifo *kf = iio_to_kfifo(r);
-	kfifo_free(&kf->kf);
-	kfree(kf);
-}
+//static void iio_kfifo_release(struct device *dev)
+//{
+//	struct iio_ring_buffer *r = to_iio_ring_buffer(dev);
+//	struct iio_kfifo *kf = iio_to_kfifo(r);
+//	kfifo_free(&kf->kf);
+//	kfree(kf);
+//}
 
-static struct device_type iio_kfifo_type = {
-	.release = iio_kfifo_release,
-	.groups = iio_kfifo_attribute_groups,
-};
+//static struct device_type iio_kfifo_type = {
+//	.release = iio_kfifo_release,
+//	.groups = iio_kfifo_attribute_groups,
+//};
 
 struct iio_ring_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev)
 {
@@ -116,10 +113,8 @@ struct iio_ring_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev)
 		return NULL;
 	kf->update_needed = true;
 	iio_ring_buffer_init(&kf->ring, indio_dev);
+	kf->ring.attrs = &iio_kfifo_attribute_group;
 	__iio_init_kfifo(kf);
-	kf->ring.dev.type = &iio_kfifo_type;
-	kf->ring.dev.parent = &indio_dev->dev;
-	dev_set_drvdata(&kf->ring.dev, (void *)&(kf->ring));
 
 	return &kf->ring;
 }
@@ -159,8 +154,8 @@ static int iio_set_length_kfifo(struct iio_ring_buffer *r, int length)
 
 void iio_kfifo_free(struct iio_ring_buffer *r)
 {
-	if (r)
-		iio_put_ring_buffer(r);
+//	if (r)
+//		iio_put_ring_buffer(r);
 }
 EXPORT_SYMBOL(iio_kfifo_free);
 
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index 299b954..517ab89 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -779,7 +779,7 @@ static int __devinit ade7758_probe(struct spi_device *spi)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+	ret = iio_ring_buffer_register_ex(indio_dev, 0,
 					  &ade7758_channels[0],
 					  ARRAY_SIZE(ade7758_channels));
 	if (ret) {
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
index 2efebb7..e736dc1 100644
--- a/drivers/staging/iio/ring_generic.h
+++ b/drivers/staging/iio/ring_generic.h
@@ -94,7 +94,6 @@ struct iio_ring_setup_ops {
  * @flags:		[INTERN] file operations related flags including busy flag.
  **/
 struct iio_ring_buffer {
-	struct device				dev;
 	struct iio_dev				*indio_dev;
 	struct module				*owner;
 	int					length;
@@ -111,7 +110,7 @@ struct iio_ring_buffer {
 	wait_queue_head_t			pollq;
 	bool					stufftoread;
 	unsigned long				flags;
-	struct cdev				chrdev;
+	const struct attribute_group *attrs;
 };
 
 /**
@@ -200,24 +199,15 @@ static inline int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit)
 	return 0;
 };
 
-/**
- * iio_put_ring_buffer() - notify done with buffer
- * @ring: the buffer we are done with.
- **/
-static inline void iio_put_ring_buffer(struct iio_ring_buffer *ring)
-{
-	put_device(&ring->dev);
-};
-
 #define to_iio_ring_buffer(d)				\
 	container_of(d, struct iio_ring_buffer, dev)
 
 /**
  * iio_ring_buffer_register_ex() - register the buffer with IIO core
- * @ring: the buffer to be registered
+ * @indio_dev: device with the buffer to be registered
  * @id: the id of the buffer (typically 0)
  **/
-int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
+int iio_ring_buffer_register_ex(struct iio_dev *indio_dev, int id,
 				const struct iio_chan_spec *channels,
 				int num_channels);
 
@@ -225,9 +215,9 @@ void iio_ring_access_release(struct device *dev);
 
 /**
  * iio_ring_buffer_unregister() - unregister the buffer from IIO core
- * @ring: the buffer to be unregistered
+ * @indio_dev: the device with the buffer to be unregistered
  **/
-void iio_ring_buffer_unregister(struct iio_ring_buffer *ring);
+void iio_ring_buffer_unregister(struct iio_dev *indio_dev);
 
 /**
  * iio_read_ring_length() - attr func to get number of datums in the buffer
@@ -274,7 +264,7 @@ int iio_sw_ring_preenable(struct iio_dev *indio_dev);
 
 #else /* CONFIG_IIO_RING_BUFFER */
 
-static inline int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring,
+static inline int iio_ring_buffer_register_ex(struct iio_dev *indio_dev,
 					      int id,
 					      struct iio_chan_spec *channels,
 					      int num_channels)
@@ -282,7 +272,7 @@ static inline int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring,
 	return 0;
 }
 
-static inline void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
+static inline void iio_ring_buffer_unregister(struct iio_dev *indio_dev)
 {};
 
 #endif /* CONFIG_IIO_RING_BUFFER */
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index feb84e2..ddc752d 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -394,8 +394,8 @@ static int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r)
 
 static void iio_sw_rb_release(struct device *dev)
 {
-	struct iio_ring_buffer *r = to_iio_ring_buffer(dev);
-	iio_ring_access_release(&r->dev);
+	struct iio_dev *indio_dev =  container_of(dev, struct iio_dev, dev);
+	struct iio_ring_buffer *r = indio_dev->ring;
 	kfree(iio_to_sw_ring(r));
 }
 
@@ -413,16 +413,7 @@ static struct attribute *iio_ring_attributes[] = {
 
 static struct attribute_group iio_ring_attribute_group = {
 	.attrs = iio_ring_attributes,
-};
-
-static const struct attribute_group *iio_ring_attribute_groups[] = {
-	&iio_ring_attribute_group,
-	NULL
-};
-
-static struct device_type iio_sw_ring_type = {
-	.release = iio_sw_rb_release,
-	.groups = iio_ring_attribute_groups,
+	.name = "buffer",
 };
 
 struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev)
@@ -437,9 +428,7 @@ struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev)
 	buf = &ring->buf;
 	iio_ring_buffer_init(buf, indio_dev);
 	__iio_init_sw_ring_buffer(ring);
-	buf->dev.type = &iio_sw_ring_type;
-	buf->dev.parent = &indio_dev->dev;
-	dev_set_drvdata(&buf->dev, (void *)buf);
+	buf->attrs = &iio_ring_attribute_group;
 
 	return buf;
 }
@@ -447,8 +436,8 @@ EXPORT_SYMBOL(iio_sw_rb_allocate);
 
 void iio_sw_rb_free(struct iio_ring_buffer *r)
 {
-	if (r)
-		iio_put_ring_buffer(r);
+	//if (r)
+	//	iio_put_ring_buffer(r);
 }
 EXPORT_SYMBOL(iio_sw_rb_free);
 
-- 
1.7.3.4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 7/7] staging:iio: remove now defunct header definitions and add some statics
  2011-07-18 13:49 [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device Jonathan Cameron
                   ` (5 preceding siblings ...)
  2011-07-18 13:50 ` [PATCH 6/7] staging:iio: push the main buffer chrdev down to the top level Jonathan Cameron
@ 2011-07-18 13:50 ` Jonathan Cameron
  2011-07-19  8:53 ` [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device Jonathan Cameron
  2011-07-19 14:27 ` Arnd Bergmann
  8 siblings, 0 replies; 12+ messages in thread
From: Jonathan Cameron @ 2011-07-18 13:50 UTC (permalink / raw)
  To: linux-iio; +Cc: arnd, manuel.stahl, device-drivers-devel, Jonathan Cameron

Now we have combined all chrdevs into one, some bits and bobs are only
needed in industrialio-core.c and don't need to be in the core header.

Also remove some unused defines.

Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/staging/iio/iio_core.h          |    9 ---------
 drivers/staging/iio/industrialio-core.c |    9 +++------
 2 files changed, 3 insertions(+), 15 deletions(-)

diff --git a/drivers/staging/iio/iio_core.h b/drivers/staging/iio/iio_core.h
index 380d782..9ba5498 100644
--- a/drivers/staging/iio/iio_core.h
+++ b/drivers/staging/iio/iio_core.h
@@ -14,13 +14,6 @@
 #define _IIO_CORE_H_
 
 /**
- * iio_device_get_chrdev_minor() - get an unused minor number
- **/
-int iio_device_get_chrdev_minor(void);
-void iio_device_free_chrdev_minor(int val);
-
-
-/**
  * iio_put() - internal module reference count reduce
  **/
 void iio_put(void);
@@ -30,8 +23,6 @@ void iio_put(void);
  **/
 void iio_get(void);
 
-extern dev_t iio_devt;
-
 int __iio_add_chan_devattr(const char *postfix,
 			   const char *group,
 			   struct iio_chan_spec const *chan,
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 7cd0485..595764e 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -27,9 +27,6 @@
 #include "iio_core_trigger.h"
 #include "chrdev.h"
 
-#define IIO_ID_PREFIX "device"
-#define IIO_ID_FORMAT IIO_ID_PREFIX "%d"
-
 /* IDR to assign each registered device a unique id*/
 static DEFINE_IDA(iio_ida);
 /* IDR to allocate character device minor numbers */
@@ -37,7 +34,7 @@ static DEFINE_IDA(iio_chrdev_ida);
 /* Lock used to protect both of the above */
 static DEFINE_SPINLOCK(iio_ida_lock);
 
-dev_t iio_devt;
+static dev_t iio_devt;
 
 #define IIO_DEV_MAX 256
 struct bus_type iio_bus_type = {
@@ -276,7 +273,7 @@ static const struct file_operations iio_event_chrdev_fileops = {
 	.llseek = noop_llseek,
 };
 
-int iio_device_get_chrdev_minor(void)
+static int iio_device_get_chrdev_minor(void)
 {
 	int ret;
 
@@ -287,7 +284,7 @@ int iio_device_get_chrdev_minor(void)
 		return -ENOMEM;
 }
 
-void iio_device_free_chrdev_minor(int val)
+static void iio_device_free_chrdev_minor(int val)
 {
 	iio_free_ida_val(&iio_chrdev_ida, val);
 }
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device
  2011-07-18 13:49 [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device Jonathan Cameron
                   ` (6 preceding siblings ...)
  2011-07-18 13:50 ` [PATCH 7/7] staging:iio: remove now defunct header definitions and add some statics Jonathan Cameron
@ 2011-07-19  8:53 ` Jonathan Cameron
  2011-07-19 14:27 ` Arnd Bergmann
  8 siblings, 0 replies; 12+ messages in thread
From: Jonathan Cameron @ 2011-07-19  8:53 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, arnd, manuel.stahl, device-drivers-devel

I forgot to mention that this series also thoroughly breaks the sca3000.
I'll fix that one up before reposting.

> This is another of Arnd's suggestions.
> 
> Some of the patches here are just pre conversion reworks to make the important
> bit easier and some are cleanups of headers etc as a result of things not
> being needed any more.
> 
> One little change I slipped in here:
> 
> devices now have iio:deviceX as their name so that we have something
> sensibly named under /dev/
> 
> The important patches are 4 and 6.
> 
> 4 uses Arnd's suggestion of an annon_fd obtained via ioctl on the buffer
> chrdev to get a file for easy use for reading events.  This is a very neat
> solution that lets us keep the actual event system separate from the data
> stream without two chrdevs.
> 
> 6. Moves the remaining single chrdev so it associated with the iio_dev rather
> than the buffer.  This means we now only have two types of device (other than
> weird ones like the sysfs trigger management node), triggers and devices.
> Given either can exist independently, those two don't make sense to merge.
> 
> Anyhow, I'm far from convinced that the allocation / deallocation is now
> correct and that there aren't any race conditions on removal od devices.
> (then again I'm not convinced there weren't any of those before.)
> 
> Note I haven't ammended the nature of either 'chrdev' at all. There
> is more to be done there.
> 
> Note, this is 3.2 material so no particular rush for comments.
> Having said that, please do pull it into local trees and hammer it
> nice and hard to see where I messed up.
> 
> For reference a minimal test app is:
> 
> #include <stdio.h>
> /* little dirty test prog */
>  #include <sys/ioctl.h>
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <stdint.h>
> 
> struct iio_event_data {
> 	int	id;
> 	int64_t	timestamp;
> };
> 
> 
> int main(int argc, char **argv)
> {
> 	int ret;
> 	int fp;
> 	int data;
> 	int i = 0;
> 	FILE *evfp;
> 	struct iio_event_data ev;
> 	fp = open(argv[1], O_RDONLY);
> 	ret = ioctl(fp, 0, &data);
> 	/* So we have the fd (in theory) of the anon file */
> 	evfp = fdopen(data, "r");
> 
> 	if (evfp)
> 		for (i = 0; i < 100; i++) {
> 			ret = fread( &ev, sizeof(ev), 1, evfp);
> 			printf("%d %lld\n", ev.id, ev.timestamp);
> 		}
> 	return 0;
> }
> 
> Jonathan
> 
> Jonathan Cameron (7):
>   staging:iio:trigger push functions that don't need to be generaly
>     available down into the core.
>   staging:iio:kfifo buffer - push structure definition down into
>     implementation.
>   staging:iio:chrdev.h rationalization.
>   staging:iio: remove specific chrdev for event reading. Get fd from
>     ioctl on buffer.
>   staging:iio: squash chrdev handler remains into users.
>   staging:iio: push the main buffer chrdev down to the top level.
>   staging:iio: remove now defunct header definitions and add some
>     statics
> 
>  drivers/staging/iio/Documentation/generic_buffer.c |   11 +-
>  drivers/staging/iio/Documentation/iio_utils.h      |    2 +-
>  drivers/staging/iio/accel/adis16201_core.c         |    6 +-
>  drivers/staging/iio/accel/adis16203_core.c         |    6 +-
>  drivers/staging/iio/accel/adis16204_core.c         |    6 +-
>  drivers/staging/iio/accel/adis16209_core.c         |    6 +-
>  drivers/staging/iio/accel/adis16240_core.c         |    6 +-
>  drivers/staging/iio/accel/lis3l02dq_core.c         |    6 +-
>  drivers/staging/iio/accel/sca3000_core.c           |    4 +-
>  drivers/staging/iio/adc/ad7298_core.c              |    4 +-
>  drivers/staging/iio/adc/ad7476_core.c              |    4 +-
>  drivers/staging/iio/adc/ad7606_core.c              |    4 +-
>  drivers/staging/iio/adc/ad7793.c                   |    6 +-
>  drivers/staging/iio/adc/ad7887_core.c              |    4 +-
>  drivers/staging/iio/adc/ad799x_core.c              |    4 +-
>  drivers/staging/iio/adc/max1363_core.c             |    6 +-
>  drivers/staging/iio/chrdev.h                       |   51 ----
>  drivers/staging/iio/gyro/adis16260_core.c          |    6 +-
>  drivers/staging/iio/iio.h                          |    4 +-
>  drivers/staging/iio/iio_core.h                     |   39 +++-
>  drivers/staging/iio/imu/adis16400_core.c           |    6 +-
>  drivers/staging/iio/industrialio-core.c            |  273 +++++++++++---------
>  drivers/staging/iio/industrialio-ring.c            |  220 ++++++-----------
>  drivers/staging/iio/industrialio-trigger.c         |   30 ++-
>  drivers/staging/iio/kfifo_buf.c                    |   43 ++--
>  drivers/staging/iio/kfifo_buf.h                    |    8 -
>  drivers/staging/iio/meter/ade7758_core.c           |    2 +-
>  drivers/staging/iio/ring_generic.h                 |   28 +--
>  drivers/staging/iio/ring_sw.c                      |   23 +--
>  drivers/staging/iio/trigger.h                      |   39 ---
>  30 files changed, 368 insertions(+), 489 deletions(-)
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device
  2011-07-18 13:49 [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device Jonathan Cameron
                   ` (7 preceding siblings ...)
  2011-07-19  8:53 ` [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device Jonathan Cameron
@ 2011-07-19 14:27 ` Arnd Bergmann
  2011-07-19 14:30   ` Jonathan Cameron
  8 siblings, 1 reply; 12+ messages in thread
From: Arnd Bergmann @ 2011-07-19 14:27 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, manuel.stahl, device-drivers-devel

On Monday 18 July 2011, Jonathan Cameron wrote:
> 4 uses Arnd's suggestion of an annon_fd obtained via ioctl on the buffer
> chrdev to get a file for easy use for reading events.  This is a very neat
> solution that lets us keep the actual event system separate from the data
> stream without two chrdevs.

IMHO, the series looks good overall, but you need to fix the iio_ioctl
function to take a proper ioctl command: you check for 'cmd == 0', which is
not allowed by convention.
Please use the _IOR() macro to define a number and document the command
range in Documentation/ioctl/ioctl-number.txt.

Also, you should have a .compat_ioctl file operation that points to
the same function, to make sure that the interface works in 32 bit
processes running on a 64 bit kernel.

	Arnd

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device
  2011-07-19 14:27 ` Arnd Bergmann
@ 2011-07-19 14:30   ` Jonathan Cameron
  0 siblings, 0 replies; 12+ messages in thread
From: Jonathan Cameron @ 2011-07-19 14:30 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linux-iio, manuel.stahl, device-drivers-devel

On 07/19/11 15:27, Arnd Bergmann wrote:
> On Monday 18 July 2011, Jonathan Cameron wrote:
>> 4 uses Arnd's suggestion of an annon_fd obtained via ioctl on the buffer
>> chrdev to get a file for easy use for reading events.  This is a very neat
>> solution that lets us keep the actual event system separate from the data
>> stream without two chrdevs.
> 
> IMHO, the series looks good overall, but you need to fix the iio_ioctl
> function to take a proper ioctl command: you check for 'cmd == 0', which is
> not allowed by convention.
> Please use the _IOR() macro to define a number and document the command
> range in Documentation/ioctl/ioctl-number.txt.
> 
> Also, you should have a .compat_ioctl file operation that points to
> the same function, to make sure that the interface works in 32 bit
> processes running on a 64 bit kernel.
> 
> 	Arnd
> 
Cool. Thanks for those pointers.  I hacked that bit in a bit fast without
really looking into it.. :)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 4/7] staging:iio: remove specific chrdev for event reading. Get fd from ioctl on buffer.
  2011-07-18 13:50 ` [PATCH 4/7] staging:iio: remove specific chrdev for event reading. Get fd from ioctl on buffer Jonathan Cameron
@ 2011-07-21  8:57   ` Jonathan Cameron
  0 siblings, 0 replies; 12+ messages in thread
From: Jonathan Cameron @ 2011-07-21  8:57 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, arnd, manuel.stahl, device-drivers-devel

On 07/18/11 14:50, Jonathan Cameron wrote:
> Change suggested by Arnd Bergmann.
> 
> No real reason to have two chrdevs per device. This step merges them into one.
> Currently this means that events will only work on devices with buffers. THat will
> be remedied shortly.
Ooops. Big bug in here.  Any driver that has an event_attrs_group needs to give it the
name "events".  Otherwise all sorts of nasty to track down errors occur.
> 
> Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/staging/iio/iio.h               |    1 +
>  drivers/staging/iio/industrialio-core.c |  174 ++++++++++--------------------
>  drivers/staging/iio/industrialio-ring.c |   23 ++++-
>  3 files changed, 81 insertions(+), 117 deletions(-)
> 
> diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
> index cf43e71..308b100 100644
> --- a/drivers/staging/iio/iio.h
> +++ b/drivers/staging/iio/iio.h
> @@ -247,6 +247,7 @@ struct iio_info {
>  
>  };
>  
> +int iio_event_getfd(struct iio_dev *indio_dev);
>  /**
>   * struct iio_dev - industrial I/O device
>   * @id:			[INTERN] used to identify device internally
> diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
> index f9d1744..31ebc3a 100644
> --- a/drivers/staging/iio/industrialio-core.c
> +++ b/drivers/staging/iio/industrialio-core.c
> @@ -21,6 +21,7 @@
>  #include <linux/wait.h>
>  #include <linux/cdev.h>
>  #include <linux/slab.h>
> +#include <linux/anon_inodes.h>
>  #include "iio.h"
>  #include "iio_core.h"
>  #include "iio_core_trigger.h"
> @@ -128,6 +129,7 @@ struct iio_detected_event_list {
>  	struct iio_event_data		ev;
>  };
>  
> +
>  /**
>   * struct iio_event_interface - chrdev interface for an event line
>   * @dev:		device assocated with event interface
> @@ -139,7 +141,6 @@ struct iio_detected_event_list {
>   * @current_events:	number of events in detected list
>   */
>  struct iio_event_interface {
> -	struct device				dev;
>  	struct iio_handler			handler;
>  	wait_queue_head_t			wait;
>  	struct mutex				event_list_lock;
> @@ -187,7 +188,6 @@ error_ret:
>  }
>  EXPORT_SYMBOL(iio_push_event);
>  
> -
>  /* This turns up an awful lot */
>  ssize_t iio_read_const_attr(struct device *dev,
>  			    struct device_attribute *attr,
> @@ -207,7 +207,6 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
>  	struct iio_detected_event_list *el;
>  	int ret;
>  	size_t len;
> -
>  	mutex_lock(&ev_int->event_list_lock);
>  	if (list_empty(&ev_int->det_events)) {
>  		if (filep->f_flags & O_NONBLOCK) {
> @@ -249,10 +248,8 @@ error_ret:
>  
>  static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
>  {
> -	struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev);
> -	struct iio_event_interface *ev_int = hand->private;
> +	struct iio_event_interface *ev_int = filep->private_data;
>  	struct iio_detected_event_list *el, *t;
> -
>  	mutex_lock(&ev_int->event_list_lock);
>  	clear_bit(IIO_BUSY_BIT_POS, &ev_int->handler.flags);
>  	/*
> @@ -264,23 +261,7 @@ static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
>  		list_del(&el->list);
>  		kfree(el);
>  	}
> -	mutex_unlock(&ev_int->event_list_lock);
> -
> -	return 0;
> -}
> -
> -static int iio_event_chrdev_open(struct inode *inode, struct file *filep)
> -{
> -	struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev);
> -	struct iio_event_interface *ev_int = hand->private;
> -
> -	mutex_lock(&ev_int->event_list_lock);
> -	if (test_and_set_bit(IIO_BUSY_BIT_POS, &hand->flags)) {
> -		fops_put(filep->f_op);
> -		mutex_unlock(&ev_int->event_list_lock);
> -		return -EBUSY;
> -	}
> -	filep->private_data = hand->private;
> +	ev_int->current_events = 0;
>  	mutex_unlock(&ev_int->event_list_lock);
>  
>  	return 0;
> @@ -289,23 +270,10 @@ static int iio_event_chrdev_open(struct inode *inode, struct file *filep)
>  static const struct file_operations iio_event_chrdev_fileops = {
>  	.read =  iio_event_chrdev_read,
>  	.release = iio_event_chrdev_release,
> -	.open = iio_event_chrdev_open,
>  	.owner = THIS_MODULE,
>  	.llseek = noop_llseek,
>  };
>  
> -static void iio_event_dev_release(struct device *dev)
> -{
> -	struct iio_event_interface *ev_int
> -		= container_of(dev, struct iio_event_interface, dev);
> -	cdev_del(&ev_int->handler.chrdev);
> -	iio_device_free_chrdev_minor(MINOR(dev->devt));
> -};
> -
> -static struct device_type iio_event_type = {
> -	.release = iio_event_dev_release,
> -};
> -
>  int iio_device_get_chrdev_minor(void)
>  {
>  	int ret;
> @@ -322,34 +290,28 @@ void iio_device_free_chrdev_minor(int val)
>  	iio_free_ida_val(&iio_chrdev_ida, val);
>  }
>  
> -static int iio_setup_ev_int(struct iio_event_interface *ev_int,
> +int iio_event_getfd(struct iio_dev *indio_dev) {
> +	if (indio_dev->event_interfaces == NULL)
> +		return -ENODEV;
> +
> +	mutex_lock(&indio_dev->event_interfaces->event_list_lock);
> +	if (test_and_set_bit(IIO_BUSY_BIT_POS,
> +			     &indio_dev->event_interfaces->handler.flags )) {
> +		mutex_unlock(&indio_dev->event_interfaces->event_list_lock);
> +		return -EBUSY;
> +	}
> +	mutex_unlock(&indio_dev->event_interfaces->event_list_lock);
> +	return anon_inode_getfd("iio:event",
> +				      &iio_event_chrdev_fileops,
> +				      &indio_dev->event_interfaces[0], O_RDONLY);
> +}
> +
> +static void iio_setup_ev_int(struct iio_event_interface *ev_int,
>  			    const char *dev_name,
>  			    int index,
>  			    struct module *owner,
>  			    struct device *dev)
>  {
> -	int ret, minor;
> -
> -	ev_int->dev.bus = &iio_bus_type;
> -	ev_int->dev.parent = dev;
> -	ev_int->dev.type = &iio_event_type;
> -	device_initialize(&ev_int->dev);
> -
> -	minor = iio_device_get_chrdev_minor();
> -	if (minor < 0) {
> -		ret = minor;
> -		goto error_device_put;
> -	}
> -	ev_int->dev.devt = MKDEV(MAJOR(iio_devt), minor);
> -	dev_set_name(&ev_int->dev, "%s:event%d", dev_name, index);
> -
> -	ret = device_add(&ev_int->dev);
> -	if (ret)
> -		goto error_free_minor;
> -
> -	cdev_init(&ev_int->handler.chrdev, &iio_event_chrdev_fileops);
> -	ev_int->handler.chrdev.owner = owner;
> -
>  	mutex_init(&ev_int->event_list_lock);
>  	/* discussion point - make this variable? */
>  	ev_int->max_events = 10;
> @@ -358,27 +320,6 @@ static int iio_setup_ev_int(struct iio_event_interface *ev_int,
>  	init_waitqueue_head(&ev_int->wait);
>  	ev_int->handler.private = ev_int;
>  	ev_int->handler.flags = 0;
> -
> -	ret = cdev_add(&ev_int->handler.chrdev, ev_int->dev.devt, 1);
> -	if (ret)
> -		goto error_unreg_device;
> -
> -	return 0;
> -
> -error_unreg_device:
> -	device_unregister(&ev_int->dev);
> -error_free_minor:
> -	iio_device_free_chrdev_minor(minor);
> -error_device_put:
> -	put_device(&ev_int->dev);
> -
> -	return ret;
> -}
> -
> -static void iio_free_ev_int(struct iio_event_interface *ev_int)
> -{
> -	device_unregister(&ev_int->dev);
> -	put_device(&ev_int->dev);
>  }
>  
>  static int __init iio_init(void)
> @@ -955,7 +896,7 @@ static int iio_device_add_event_sysfs(struct iio_dev *dev_info,
>  			printk(KERN_INFO "currently unhandled type of event\n");
>  		}
>  		ret = __iio_add_chan_devattr(postfix,
> -					     NULL,
> +					     "events",
>  					     chan,
>  					     &iio_ev_state_show,
>  					     iio_ev_state_store,
> @@ -965,7 +906,7 @@ static int iio_device_add_event_sysfs(struct iio_dev *dev_info,
>  					       extending the bitmask - but
>  					       how far*/
>  					     0,
> -					     &dev_info->event_interfaces[0].dev,
> +					     &dev_info->dev,
>  					     &dev_info->event_interfaces[0].
>  					     dev_attr_list);
>  		kfree(postfix);
> @@ -979,13 +920,12 @@ static int iio_device_add_event_sysfs(struct iio_dev *dev_info,
>  			ret = -ENOMEM;
>  			goto error_ret;
>  		}
> -		ret = __iio_add_chan_devattr(postfix, NULL, chan,
> +		ret = __iio_add_chan_devattr(postfix, "events", chan,
>  					     iio_ev_value_show,
>  					     iio_ev_value_store,
>  					     mask,
>  					     0,
> -					     &dev_info->event_interfaces[0]
> -					     .dev,
> +					     &dev_info->dev,
>  					     &dev_info->event_interfaces[0]
>  					     .dev_attr_list);
>  		kfree(postfix);
> @@ -1005,8 +945,7 @@ static inline void __iio_remove_event_config_attrs(struct iio_dev *dev_info,
>  	list_for_each_entry_safe(p, n,
>  				 &dev_info->event_interfaces[i].
>  				 dev_attr_list, l) {
> -		sysfs_remove_file_from_group(&dev_info
> -					     ->event_interfaces[i].dev.kobj,
> +		sysfs_remove_file_from_group(&dev_info->dev.kobj,
>  					     &p->dev_attr.attr,
>  					     NULL);
>  		kfree(p->dev_attr.attr.name);
> @@ -1037,6 +976,15 @@ error_clear_attrs:
>  	return ret;
>  }
>  
> +static struct attribute *iio_events_dummy_attrs[] = {
> +	NULL
> +};
> +
> +static struct attribute_group iio_events_dummy_group = {
> +	.name = "events",
> +	.attrs = iio_events_dummy_attrs
> +};
> +
>  static int iio_device_register_eventset(struct iio_dev *dev_info)
>  {
>  	int ret = 0, i, j;
> @@ -1054,42 +1002,34 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
>  	}
>  
>  	for (i = 0; i < dev_info->info->num_interrupt_lines; i++) {
> -		ret = iio_setup_ev_int(&dev_info->event_interfaces[i],
> -				       dev_name(&dev_info->dev),
> -				       i,
> -				       dev_info->info->driver_module,
> -				       &dev_info->dev);
> -		if (ret) {
> -			dev_err(&dev_info->dev,
> -				"Could not get chrdev interface\n");
> -			goto error_free_setup_event_lines;
> -		}
> -
> -		dev_set_drvdata(&dev_info->event_interfaces[i].dev,
> -				(void *)dev_info);
> +		//clean up parameters for this
> +		iio_setup_ev_int(&dev_info->event_interfaces[i],
> +				 dev_name(&dev_info->dev),
> +				 i,
> +				 dev_info->info->driver_module,
> +				 &dev_info->dev);
>  
>  		if (dev_info->info->event_attrs != NULL)
> -			ret = sysfs_create_group(&dev_info
> -						 ->event_interfaces[i]
> -						 .dev.kobj,
> +			ret = sysfs_create_group(&dev_info->dev.kobj,
>  						 &dev_info->info
>  						 ->event_attrs[i]);
> -
> +		else
> +			ret = sysfs_create_group(&dev_info->dev.kobj,
> +						 &iio_events_dummy_group);
>  		if (ret) {
>  			dev_err(&dev_info->dev,
>  				"Failed to register sysfs for event attrs");
> -			iio_free_ev_int(&dev_info->event_interfaces[i]);
>  			goto error_free_setup_event_lines;
>  		}
>  		ret = __iio_add_event_config_attrs(dev_info, i);
>  		if (ret) {
>  			if (dev_info->info->event_attrs != NULL)
> -				sysfs_remove_group(&dev_info
> -						   ->event_interfaces[i]
> -						   .dev.kobj,
> +				sysfs_remove_group(&dev_info->dev.kobj,
>  						   &dev_info->info
>  						   ->event_attrs[i]);
> -			iio_free_ev_int(&dev_info->event_interfaces[i]);
> +			else
> +				sysfs_remove_group(&dev_info->dev.kobj,
> +						   &iio_events_dummy_group);
>  			goto error_free_setup_event_lines;
>  		}
>  	}
> @@ -1099,11 +1039,12 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
>  error_free_setup_event_lines:
>  	for (j = 0; j < i; j++) {
>  		__iio_remove_event_config_attrs(dev_info, j);
> -		if (dev_info->info->event_attrs != NULL)
> -			sysfs_remove_group(&dev_info
> -					   ->event_interfaces[j].dev.kobj,
> +		if (dev_info->info->event_attrs != NULL) {
> +			sysfs_remove_group(&dev_info->dev.kobj,
>  					   &dev_info->info->event_attrs[j]);
> -		iio_free_ev_int(&dev_info->event_interfaces[j]);
> +			sysfs_remove_group(&dev_info->dev.kobj,
> +					   &iio_events_dummy_group);
> +		}
>  	}
>  	kfree(dev_info->event_interfaces);
>  error_ret:
> @@ -1120,10 +1061,11 @@ static void iio_device_unregister_eventset(struct iio_dev *dev_info)
>  	for (i = 0; i < dev_info->info->num_interrupt_lines; i++) {
>  		__iio_remove_event_config_attrs(dev_info, i);
>  		if (dev_info->info->event_attrs != NULL)
> -			sysfs_remove_group(&dev_info
> -					   ->event_interfaces[i].dev.kobj,
> +			sysfs_remove_group(&dev_info->dev.kobj,
>  					   &dev_info->info->event_attrs[i]);
> -		iio_free_ev_int(&dev_info->event_interfaces[i]);
> +		else
> +			sysfs_remove_group(&dev_info->dev.kobj,
> +					   &iio_events_dummy_group);
>  	}
>  	kfree(dev_info->event_interfaces);
>  }
> diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
> index dce50b1..3c1b7f7 100644
> --- a/drivers/staging/iio/industrialio-ring.c
> +++ b/drivers/staging/iio/industrialio-ring.c
> @@ -93,13 +93,34 @@ static unsigned int iio_ring_poll(struct file *filp,
>  	return 0;
>  }
>  
> -static const struct file_operations iio_ring_fileops = {
> +/* Somewhat of a cross file organization violation - ioctls here are actually
> + * event related */
> +static long iio_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
> +{
> +
> +	struct iio_ring_buffer *rb = f->private_data;
> +	struct iio_dev *indio_dev = rb->indio_dev;
> +	int __user *ip = (int __user *)arg;
> +
> +	
> +	if (cmd == 0) { //cleanup
> +		int fd;
> +		fd = iio_event_getfd(indio_dev);
> +		if (copy_to_user(ip, &fd, sizeof(fd)))
> +			return -EFAULT;
> +		return 0;
> +	}
> +	return -EINVAL;
> +}
> +
> + const struct file_operations iio_ring_fileops = {
>  	.read = iio_ring_read_first_n_outer,
>  	.release = iio_ring_release,
>  	.open = iio_ring_open,
>  	.poll = iio_ring_poll,
>  	.owner = THIS_MODULE,
>  	.llseek = noop_llseek,
> +	.unlocked_ioctl = iio_ioctl,
>  };
>  
>  void iio_ring_access_release(struct device *dev)


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2011-07-21  8:57 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-18 13:49 [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device Jonathan Cameron
2011-07-18 13:49 ` [PATCH 1/7] staging:iio:trigger push functions that don't need to be generaly available down into the core Jonathan Cameron
2011-07-18 13:49 ` [PATCH 2/7] staging:iio:kfifo buffer - push structure definition down into implementation Jonathan Cameron
2011-07-18 13:50 ` [PATCH 3/7] staging:iio:chrdev.h rationalization Jonathan Cameron
2011-07-18 13:50 ` [PATCH 4/7] staging:iio: remove specific chrdev for event reading. Get fd from ioctl on buffer Jonathan Cameron
2011-07-21  8:57   ` Jonathan Cameron
2011-07-18 13:50 ` [PATCH 5/7] staging:iio: squash chrdev handler remains into users Jonathan Cameron
2011-07-18 13:50 ` [PATCH 6/7] staging:iio: push the main buffer chrdev down to the top level Jonathan Cameron
2011-07-18 13:50 ` [PATCH 7/7] staging:iio: remove now defunct header definitions and add some statics Jonathan Cameron
2011-07-19  8:53 ` [RFC PATCH 0/7] IIO: Reduce to 1 the number of chrdevs per device Jonathan Cameron
2011-07-19 14:27 ` Arnd Bergmann
2011-07-19 14:30   ` Jonathan Cameron

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.