All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <42261BCD.6030301@acm.org>

diff --git a/a/1.txt b/N1/1.txt
index c6f6b81..a2cc655 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -1,227 +1 @@
 See part 1 for details on what this does...
-
--------------- next part --------------
-Add a timer to the I2C layer.  This doesn't do much until the
-non-blocking code shows up.
-
-Signed-off-by: Corey Minyard <minyard@acm.org>
-
-Index: linux-2.6.11-rc5-mm1/drivers/i2c/i2c-core.c
-=================================--- linux-2.6.11-rc5-mm1.orig/drivers/i2c/i2c-core.c
-+++ linux-2.6.11-rc5-mm1/drivers/i2c/i2c-core.c
-@@ -30,9 +30,16 @@
- #include <linux/init.h>
- #include <linux/idr.h>
- #include <linux/seq_file.h>
-+#include <linux/rcupdate.h>
- #include <asm/uaccess.h>
- 
- 
-+static int i2c_stop_timer(struct i2c_adapter * adap);
-+static void i2c_start_timer(struct i2c_adapter * adap,
-+			    struct i2c_op_q_entry * entry);
-+
-+#define USEC_PER_JIFFIE (1000000 / HZ)
-+
- static LIST_HEAD(adapters);
- static LIST_HEAD(drivers);
- static DECLARE_MUTEX(core_lists);
-@@ -174,6 +181,19 @@
- 	list_add_tail(&adap->list,&adapters);
- 	INIT_LIST_HEAD(&adap->clients);
- 
-+	adap->timer = kmalloc(sizeof(*adap->timer), GFP_KERNEL);
-+	if (!adap->timer) {
-+		res = -ENOMEM;
-+		goto out_unlock;
-+	}
-+		
-+	init_timer(&adap->timer->timer);
-+	spin_lock_init(&adap->timer->lock);
-+	adap->timer->deleted = 0;
-+	adap->timer->running = 0;
-+	adap->timer->next_call_time = 0;
-+	adap->timer->adapter = adap;
-+
- 	/* Add the adapter to the driver core.
- 	 * If the parent pointer is not set up,
- 	 * we add this adapter to the host bus.
-@@ -216,6 +236,7 @@
- 	struct i2c_driver *driver;
- 	struct i2c_client *client;
- 	int res = 0;
-+	unsigned long flags;
- 
- 	down(&core_lists);
- 
-@@ -260,6 +281,19 @@
- 		}
- 	}
- 
-+	/* Stop the timer and free its memory */
-+	spin_lock_irqsave(&adap->timer->lock, flags);
-+	if (i2c_stop_timer(adap)) {
-+		spin_unlock_irqrestore(&adap->timer->lock, flags);
-+		kfree(adap->timer);
-+	} else {
-+		adap->timer->deleted = 1;
-+		spin_unlock_irqrestore(&adap->timer->lock, flags);
-+	}
-+	/* Wait to make sure the timer is done. */
-+	synchronize_kernel();
-+	adap->timer = NULL;
-+
- 	/* clean up the sysfs representation */
- 	init_completion(&adap->dev_released);
- 	init_completion(&adap->class_dev_released);
-@@ -582,6 +616,83 @@
- module_exit(i2c_exit);
- 
- /* ----------------------------------------------------
-+ * Timer operations
-+ * ----------------------------------------------------
-+ */
-+static void i2c_handle_timer(unsigned long data);
-+
-+static void i2c_start_timer(struct i2c_adapter * adap,
-+			    struct i2c_op_q_entry * entry)
-+{
-+	unsigned int wait_jiffies;
-+	struct i2c_timer *t = adap->timer;
-+	unsigned long flags;
-+
-+	wait_jiffies = ((entry->call_again_us + USEC_PER_JIFFIE - 1)
-+			/ USEC_PER_JIFFIE);
-+	if (wait_jiffies = 0)
-+		wait_jiffies = 1;
-+	/* This won't be polled from the user code, so
-+	   start a timer to poll it. */
-+	spin_lock_irqsave(&t->lock, flags);
-+	if (! t->running) {
-+		t->timer.expires = jiffies + wait_jiffies;
-+		t->timer.data = (unsigned long) t;
-+		t->timer.function = i2c_handle_timer;
-+		t->running = 1;
-+		t->next_call_time = wait_jiffies * USEC_PER_JIFFIE;
-+		add_timer(&t->timer);
-+		t->sequence = adap->timer_sequence;
-+	}
-+	spin_unlock_irqrestore(&t->lock, flags);
-+}
-+
-+/* Returns true if the timer is stopped (or was not running), false if
-+   not.  Must be called with the timer lock held. */
-+static int i2c_stop_timer(struct i2c_adapter * adap)
-+{
-+	return (!adap->timer->running || del_timer(&adap->timer->timer));
-+}
-+
-+static void i2c_handle_timer(unsigned long data)
-+{
-+	struct i2c_timer      * t = (void *) data;
-+	struct i2c_adapter    * adap;
-+	unsigned long         flags;
-+	struct i2c_op_q_entry * entry;
-+	unsigned int          sequence_match;
-+
-+	spin_lock_irqsave(&t->lock, flags);
-+	if (t->deleted) {
-+		spin_unlock_irqrestore(&t->lock, flags);
-+		kfree(t);
-+		return;
-+	}
-+
-+	adap = t->adapter;
-+	t->running = 0;
-+	sequence_match = adap->timer_sequence = t->sequence;
-+	spin_unlock_irqrestore(&t->lock, flags);
-+
-+	entry = i2c_entry_get(adap);
-+	pr_debug("i2c_handle_timer: %p %p\n", adap, entry);
-+	if (!entry)
-+		return;
-+
-+	if (sequence_match) {
-+		/* Poll will go here. */
-+
-+		if (!entry_completed(entry))
-+			i2c_start_timer(adap, entry);
-+	} else if (entry->use_timer)
-+		/* We raced in timer deletion, just restart the
-+		   timer if necessary. */
-+		i2c_start_timer(adap, entry);
-+
-+	i2c_entry_put(adap, entry);
-+}
-+
-+/* ----------------------------------------------------
-  * the functional interface to the i2c busses.
-  * ----------------------------------------------------
-  */
-@@ -1419,6 +1530,21 @@
- 	if (atomic_dec_and_test(&e->completed)) {
- 		/* We are the lucky winner!  We get to clean up the
- 		   entry. */
-+		if (e->use_timer) {
-+			unsigned long    flags;
-+			struct i2c_timer *t = adap->timer;
-+			spin_lock_irqsave(&t->lock, flags);
-+			if (!i2c_stop_timer(adap))
-+				/* If we are unable to stop the timer, that
-+				   means the timer has gone off but has not
-+				   yet run the first part of the handler call.
-+				   Increment the sequence so the timer handler
-+				   can detect this. */
-+				adap->timer_sequence++;
-+			else
-+				t->running = 0;
-+			spin_unlock_irqrestore(&t->lock, flags);
-+		}
- 		if (e->complete)
- 			e->complete(adap, e);
- 	}
-Index: linux-2.6.11-rc5-mm1/include/linux/i2c.h
-=================================--- linux-2.6.11-rc5-mm1.orig/include/linux/i2c.h
-+++ linux-2.6.11-rc5-mm1/include/linux/i2c.h
-@@ -36,6 +36,7 @@
- #include <linux/kref.h>
- #include <linux/list.h>
- #include <linux/spinlock.h>
-+#include <linux/timer.h>
- #include <asm/semaphore.h>
- #include <asm/atomic.h>
- 
-@@ -242,6 +243,21 @@
- };
- 
- /*
-+ * The timer has it's own separately allocated data structure because
-+ * it needs to be able to exist even if the adapter is deleted (due to
-+ * timer cancellation races).
-+ */
-+struct i2c_timer {
-+	spinlock_t lock;
-+	int deleted;
-+	struct timer_list timer;
-+	int running;
-+	unsigned int next_call_time;
-+	struct i2c_adapter *adapter;
-+	unsigned int sequence;
-+};
-+
-+/*
-  * i2c_adapter is the structure used to identify a physical i2c bus along
-  * with the access algorithms necessary to access it.
-  */
-@@ -263,6 +279,11 @@
- 
- 	struct semaphore bus_lock;
- 
-+	/* Used to time non-blocking operations.  The sequence is used
-+	   to handle race conditions in the timer handler. */
-+	struct i2c_timer *timer;
-+	unsigned int timer_sequence;
-+
- 	int timeout;
- 	int retries;
- 	struct device dev;		/* the adapter device */
diff --git a/N1/2.hdr b/N1/2.hdr
new file mode 100644
index 0000000..f67de0e
--- /dev/null
+++ b/N1/2.hdr
@@ -0,0 +1,5 @@
+Content-Type: text/plain;
+ name="i2c_add_timer.diff"
+Content-Transfer-Encoding: 7bit
+Content-Disposition: inline;
+ filename="i2c_add_timer.diff"
diff --git a/N1/2.txt b/N1/2.txt
new file mode 100644
index 0000000..4184108
--- /dev/null
+++ b/N1/2.txt
@@ -0,0 +1,226 @@
+Add a timer to the I2C layer.  This doesn't do much until the
+non-blocking code shows up.
+
+Signed-off-by: Corey Minyard <minyard@acm.org>
+
+Index: linux-2.6.11-rc5-mm1/drivers/i2c/i2c-core.c
+===================================================================
+--- linux-2.6.11-rc5-mm1.orig/drivers/i2c/i2c-core.c
++++ linux-2.6.11-rc5-mm1/drivers/i2c/i2c-core.c
+@@ -30,9 +30,16 @@
+ #include <linux/init.h>
+ #include <linux/idr.h>
+ #include <linux/seq_file.h>
++#include <linux/rcupdate.h>
+ #include <asm/uaccess.h>
+ 
+ 
++static int i2c_stop_timer(struct i2c_adapter * adap);
++static void i2c_start_timer(struct i2c_adapter * adap,
++			    struct i2c_op_q_entry * entry);
++
++#define USEC_PER_JIFFIE (1000000 / HZ)
++
+ static LIST_HEAD(adapters);
+ static LIST_HEAD(drivers);
+ static DECLARE_MUTEX(core_lists);
+@@ -174,6 +181,19 @@
+ 	list_add_tail(&adap->list,&adapters);
+ 	INIT_LIST_HEAD(&adap->clients);
+ 
++	adap->timer = kmalloc(sizeof(*adap->timer), GFP_KERNEL);
++	if (!adap->timer) {
++		res = -ENOMEM;
++		goto out_unlock;
++	}
++		
++	init_timer(&adap->timer->timer);
++	spin_lock_init(&adap->timer->lock);
++	adap->timer->deleted = 0;
++	adap->timer->running = 0;
++	adap->timer->next_call_time = 0;
++	adap->timer->adapter = adap;
++
+ 	/* Add the adapter to the driver core.
+ 	 * If the parent pointer is not set up,
+ 	 * we add this adapter to the host bus.
+@@ -216,6 +236,7 @@
+ 	struct i2c_driver *driver;
+ 	struct i2c_client *client;
+ 	int res = 0;
++	unsigned long flags;
+ 
+ 	down(&core_lists);
+ 
+@@ -260,6 +281,19 @@
+ 		}
+ 	}
+ 
++	/* Stop the timer and free its memory */
++	spin_lock_irqsave(&adap->timer->lock, flags);
++	if (i2c_stop_timer(adap)) {
++		spin_unlock_irqrestore(&adap->timer->lock, flags);
++		kfree(adap->timer);
++	} else {
++		adap->timer->deleted = 1;
++		spin_unlock_irqrestore(&adap->timer->lock, flags);
++	}
++	/* Wait to make sure the timer is done. */
++	synchronize_kernel();
++	adap->timer = NULL;
++
+ 	/* clean up the sysfs representation */
+ 	init_completion(&adap->dev_released);
+ 	init_completion(&adap->class_dev_released);
+@@ -582,6 +616,83 @@
+ module_exit(i2c_exit);
+ 
+ /* ----------------------------------------------------
++ * Timer operations
++ * ----------------------------------------------------
++ */
++static void i2c_handle_timer(unsigned long data);
++
++static void i2c_start_timer(struct i2c_adapter * adap,
++			    struct i2c_op_q_entry * entry)
++{
++	unsigned int wait_jiffies;
++	struct i2c_timer *t = adap->timer;
++	unsigned long flags;
++
++	wait_jiffies = ((entry->call_again_us + USEC_PER_JIFFIE - 1)
++			/ USEC_PER_JIFFIE);
++	if (wait_jiffies == 0)
++		wait_jiffies = 1;
++	/* This won't be polled from the user code, so
++	   start a timer to poll it. */
++	spin_lock_irqsave(&t->lock, flags);
++	if (! t->running) {
++		t->timer.expires = jiffies + wait_jiffies;
++		t->timer.data = (unsigned long) t;
++		t->timer.function = i2c_handle_timer;
++		t->running = 1;
++		t->next_call_time = wait_jiffies * USEC_PER_JIFFIE;
++		add_timer(&t->timer);
++		t->sequence = adap->timer_sequence;
++	}
++	spin_unlock_irqrestore(&t->lock, flags);
++}
++
++/* Returns true if the timer is stopped (or was not running), false if
++   not.  Must be called with the timer lock held. */
++static int i2c_stop_timer(struct i2c_adapter * adap)
++{
++	return (!adap->timer->running || del_timer(&adap->timer->timer));
++}
++
++static void i2c_handle_timer(unsigned long data)
++{
++	struct i2c_timer      * t = (void *) data;
++	struct i2c_adapter    * adap;
++	unsigned long         flags;
++	struct i2c_op_q_entry * entry;
++	unsigned int          sequence_match;
++
++	spin_lock_irqsave(&t->lock, flags);
++	if (t->deleted) {
++		spin_unlock_irqrestore(&t->lock, flags);
++		kfree(t);
++		return;
++	}
++
++	adap = t->adapter;
++	t->running = 0;
++	sequence_match = adap->timer_sequence == t->sequence;
++	spin_unlock_irqrestore(&t->lock, flags);
++
++	entry = i2c_entry_get(adap);
++	pr_debug("i2c_handle_timer: %p %p\n", adap, entry);
++	if (!entry)
++		return;
++
++	if (sequence_match) {
++		/* Poll will go here. */
++
++		if (!entry_completed(entry))
++			i2c_start_timer(adap, entry);
++	} else if (entry->use_timer)
++		/* We raced in timer deletion, just restart the
++		   timer if necessary. */
++		i2c_start_timer(adap, entry);
++
++	i2c_entry_put(adap, entry);
++}
++
++/* ----------------------------------------------------
+  * the functional interface to the i2c busses.
+  * ----------------------------------------------------
+  */
+@@ -1419,6 +1530,21 @@
+ 	if (atomic_dec_and_test(&e->completed)) {
+ 		/* We are the lucky winner!  We get to clean up the
+ 		   entry. */
++		if (e->use_timer) {
++			unsigned long    flags;
++			struct i2c_timer *t = adap->timer;
++			spin_lock_irqsave(&t->lock, flags);
++			if (!i2c_stop_timer(adap))
++				/* If we are unable to stop the timer, that
++				   means the timer has gone off but has not
++				   yet run the first part of the handler call.
++				   Increment the sequence so the timer handler
++				   can detect this. */
++				adap->timer_sequence++;
++			else
++				t->running = 0;
++			spin_unlock_irqrestore(&t->lock, flags);
++		}
+ 		if (e->complete)
+ 			e->complete(adap, e);
+ 	}
+Index: linux-2.6.11-rc5-mm1/include/linux/i2c.h
+===================================================================
+--- linux-2.6.11-rc5-mm1.orig/include/linux/i2c.h
++++ linux-2.6.11-rc5-mm1/include/linux/i2c.h
+@@ -36,6 +36,7 @@
+ #include <linux/kref.h>
+ #include <linux/list.h>
+ #include <linux/spinlock.h>
++#include <linux/timer.h>
+ #include <asm/semaphore.h>
+ #include <asm/atomic.h>
+ 
+@@ -242,6 +243,21 @@
+ };
+ 
+ /*
++ * The timer has it's own separately allocated data structure because
++ * it needs to be able to exist even if the adapter is deleted (due to
++ * timer cancellation races).
++ */
++struct i2c_timer {
++	spinlock_t lock;
++	int deleted;
++	struct timer_list timer;
++	int running;
++	unsigned int next_call_time;
++	struct i2c_adapter *adapter;
++	unsigned int sequence;
++};
++
++/*
+  * i2c_adapter is the structure used to identify a physical i2c bus along
+  * with the access algorithms necessary to access it.
+  */
+@@ -263,6 +279,11 @@
+ 
+ 	struct semaphore bus_lock;
+ 
++	/* Used to time non-blocking operations.  The sequence is used
++	   to handle race conditions in the timer handler. */
++	struct i2c_timer *timer;
++	unsigned int timer_sequence;
++
+ 	int timeout;
+ 	int retries;
+ 	struct device dev;		/* the adapter device */
diff --git a/a/content_digest b/N1/content_digest
index f81e800..72363a2 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -1,22 +1,23 @@
- "ref\042261AFB.40001@acm.org\0"
- "From\0minyard@acm.org (Corey Minyard)\0"
+ "From\0Corey Minyard <minyard@acm.org>\0"
  "Subject\0[PATCH] Add a non-blocking interface to the I2C code, part 4\0"
- "Date\0Thu, 19 May 2005 06:25:40 +0000\0"
+ "Date\0Wed, 02 Mar 2005 14:02:21 -0600\0"
  "To\0Greg KH <greg@kroah.com>"
   lkml <linux-kernel@vger.kernel.org>
  " Sensors <sensors@stimpy.netroedge.com>\0"
- "\00:1\0"
+ "\01:1\0"
+ "b\0"
+ See part 1 for details on what this does...
+ "\01:2\0"
+ "fn\0i2c_add_timer.diff\0"
  "b\0"
- "See part 1 for details on what this does...\n"
- "\n"
- "-------------- next part --------------\n"
  "Add a timer to the I2C layer.  This doesn't do much until the\n"
  "non-blocking code shows up.\n"
  "\n"
  "Signed-off-by: Corey Minyard <minyard@acm.org>\n"
  "\n"
  "Index: linux-2.6.11-rc5-mm1/drivers/i2c/i2c-core.c\n"
- "=================================--- linux-2.6.11-rc5-mm1.orig/drivers/i2c/i2c-core.c\n"
+ "===================================================================\n"
+ "--- linux-2.6.11-rc5-mm1.orig/drivers/i2c/i2c-core.c\n"
  "+++ linux-2.6.11-rc5-mm1/drivers/i2c/i2c-core.c\n"
  "@@ -30,9 +30,16 @@\n"
  " #include <linux/init.h>\n"
@@ -101,7 +102,7 @@
  "+\n"
  "+\twait_jiffies = ((entry->call_again_us + USEC_PER_JIFFIE - 1)\n"
  "+\t\t\t/ USEC_PER_JIFFIE);\n"
- "+\tif (wait_jiffies = 0)\n"
+ "+\tif (wait_jiffies == 0)\n"
  "+\t\twait_jiffies = 1;\n"
  "+\t/* This won't be polled from the user code, so\n"
  "+\t   start a timer to poll it. */\n"
@@ -142,7 +143,7 @@
  "+\n"
  "+\tadap = t->adapter;\n"
  "+\tt->running = 0;\n"
- "+\tsequence_match = adap->timer_sequence = t->sequence;\n"
+ "+\tsequence_match = adap->timer_sequence == t->sequence;\n"
  "+\tspin_unlock_irqrestore(&t->lock, flags);\n"
  "+\n"
  "+\tentry = i2c_entry_get(adap);\n"
@@ -190,7 +191,8 @@
  " \t\t\te->complete(adap, e);\n"
  " \t}\n"
  "Index: linux-2.6.11-rc5-mm1/include/linux/i2c.h\n"
- "=================================--- linux-2.6.11-rc5-mm1.orig/include/linux/i2c.h\n"
+ "===================================================================\n"
+ "--- linux-2.6.11-rc5-mm1.orig/include/linux/i2c.h\n"
  "+++ linux-2.6.11-rc5-mm1/include/linux/i2c.h\n"
  "@@ -36,6 +36,7 @@\n"
  " #include <linux/kref.h>\n"
@@ -235,4 +237,4 @@
  " \tint retries;\n"
  " \tstruct device dev;\t\t/* the adapter device */"
 
-9b795988c0836f7f24e782bd8321270092b0d92723fd6339c26868655fb13ef3
+e4ad13a6827baa3e05067d1d697c37516fa5f9c726f4487812636e0aa1abd979

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.