Skip to contentSkip to conversation

Three drivers/i2c/ patches

PATCH Jan Dittmer 3 participants 4 messages Jul 12, 2003 – Jul 13, 2003 I2C

lore
Share & tools
lore
#0 lore raw

Hi Greg,

these are 2 patches to the drivers/i2c subdirectory.

The first patch removes a warning from i2c-algo-bit.c, which I get regularly with my tv cards. It's more an info than a failure and spamming the logs at a rate of about 1/min. It indicates a send failure on the i2c bus or a miss of the ACK. Technically I think, it should resend the message, shouldn't it?

The second patch removes the cli/sti usage from i2c-elektor. It's only used to protect pcf_pending from changing. I replaced it (hopefully correct) with a spinlock.

The third patch is actually a resend and converts w83781d to use milli Celsius instead of centi Celsius.

Thanks,

Jan

Signature · 1 line
Linux rubicon 2.5.75-mm1-jd10 #1 SMP Sat Jul 12 19:40:28 CEST 2003 i686
drivers/i2c/i2c-algo-bit.c +0 -1
@@ -347,7 +347,6 @@
 			temp++;
 			wrcount++;
 		} else { /* arbitration or no acknowledge */
-			dev_err(&i2c_adap->dev, "sendbytes: error - bailout.\n");
 			i2c_stop(adap);
 			return (retval<0)? retval : -EFAULT;
 			        /* got a better one ?? */

This removes cli/sti from i2c-elektor which protected pcf_pending from changing. Replaced by a spinlock instead.

Jan

drivers/i2c/i2c-elektor.c +7 -2
diff -urN -X exclude linux-bk/drivers/i2c/i2c-elektor.c 2.5.75-bk1/drivers/i2c/i2c-elektor.c
@@ -59,6 +59,8 @@
   need to be rewriten - but for now just remove this for simpler reading */
 
 static wait_queue_head_t pcf_wait;
+
+spinlock_t pcf_pending_lock = SPIN_LOCK_UNLOCKED;
 static int pcf_pending;
 
 /* ----- global defines -----------------------------------------------	*/
@@ -120,12 +122,12 @@
 	int timeout = 2;
 
 	if (irq > 0) {
-		cli();
+		spin_lock_irq(&pcf_pending_lock);
 		if (pcf_pending == 0) {
 			interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ );
 		} else
 			pcf_pending = 0;
-		sti();
+		spin_unlock_irq(&pcf_pending_lock);
 	} else {
 		udelay(100);
 	}
@@ -133,8 +135,11 @@
 
 
 static irqreturn_t pcf_isa_handler(int this_irq, void *dev_id, struct pt_regs *regs) {
+	unsigned long flags;
+	spin_lock_irqsave(&pcf_pending_lock, flags);
 	pcf_pending = 1;
 	wake_up_interruptible(&pcf_wait);
+	spin_unlock_irqrestore(&pcf_pending_lock, flags);
 	return IRQ_HANDLED;
 }
 
drivers/i2c/chips/w83781d.c +4 -4
@@ -496,13 +496,13 @@
 	if (nr >= 2) {	/* TEMP2 and TEMP3 */ \
 		if (data->type == as99127f) { \
 			return sprintf(buf,"%ld\n", \
-				(long)AS99127_TEMP_ADD_FROM_REG(data->reg##_add[nr-2])); \
+				(long)AS99127_TEMP_ADD_FROM_REG(data->reg##_add[nr-2])*10); \
 		} else { \
 			return sprintf(buf,"%ld\n", \
-				(long)TEMP_ADD_FROM_REG(data->reg##_add[nr-2])); \
+				(long)TEMP_ADD_FROM_REG(data->reg##_add[nr-2])*10); \
 		} \
 	} else {	/* TEMP1 */ \
-		return sprintf(buf,"%ld\n", (long)TEMP_FROM_REG(data->reg)); \
+		return sprintf(buf,"%ld\n", (long)TEMP_FROM_REG(data->reg)*10); \
 	} \
 }
 show_temp_reg(temp);
@@ -516,7 +516,7 @@
 	struct w83781d_data *data = i2c_get_clientdata(client); \
 	u32 val; \
 	 \
-	val = simple_strtoul(buf, NULL, 10); \
+	val = simple_strtoul(buf, NULL, 10)/10; \
 	 \
 	if (nr >= 2) {	/* TEMP2 and TEMP3 */ \
 		if (data->type == as99127f) \
#1 lore raw
Quoted 14 lines

diff -urN -X exclude linux-bk/drivers/i2c/i2c-elektor.c 2.5.75-bk1/drivers/i2c/i2c-elektor.c

drivers/i2c/i2c-elektor.c +2 -0
@@ -59,6 +59,8 @@
   need to be rewriten - but for now just remove this for simpler reading */
 
 static wait_queue_head_t pcf_wait;
+
+spinlock_t pcf_pending_lock = SPIN_LOCK_UNLOCKED;
 static int pcf_pending;
 
 /* ----- global defines -----------------------------------------------	*/
@@ -120,12 +122,12 @@
 	int timeout = 2;

drivers/i2c/i2c-elektor.c line 130

Quoted 10 lines
drivers/i2c/i2c-elektor.c +2 -2
 
 	if (irq > 0) {
-		cli();
+		spin_lock_irq(&pcf_pending_lock);
 		if (pcf_pending == 0) {
 			interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ );
 		} else
 			pcf_pending = 0;
-		sti();
+		spin_unlock_irq(&pcf_pending_lock);

Sleeping with interrupts disabled and a spinlock held still isn't exactly a good idea. As is sleep_on..

#2 lore raw
Quoted 3 lines · Christoph Hellwig

Sleeping with interrupts disabled and a spinlock held still isn't exactly a good idea. As is sleep_on..

So something like the following does make more sense?
I don't quite understand, how that code worked before - I suppose
interruptible_sleep_on_timeout activates irqs again, otherwise the interrupt handler would have never been called? But then, the sti() doesn't make much sense and should have been moved to the else path?

Thanks,

Jan

--- 2.5.75/drivers/i2c/i2c-elektor.c 2003-07-11 09:35:37.000000000 +0200
+++ 2.5.75-bk1/drivers/i2c/i2c-elektor.c 2003-07-13 12:06:06.000000000
+0200
@@ -59,6 +59,8 @@
need to be rewriten - but for now just remove this for simpler reading */

static wait_queue_head_t pcf_wait;
+
+spinlock_t pcf_pending_lock = SPIN_LOCK_UNLOCKED;
static int pcf_pending;

/* ----- global defines -----------------------------------------------
*/
@@ -120,12 +122,14 @@

        int timeout = 2;

        if (irq > 0) {
-               cli();
+               spin_lock_irq(&pcf_pending_lock);
                if (pcf_pending == 0) {
+                       spin_unlock_irq(&pcf_pending_lock);
                        interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ );
-               } else
+               } else {
                        pcf_pending = 0;
-               sti();
+                       spin_unlock_irq(&pcf_pending_lock);
+               }
        } else {
                udelay(100);
        }

@@ -133,7 +137,10 @@

static irqreturn_t pcf_isa_handler(int this_irq, void *dev_id, struct pt_regs
*regs) {
+ unsigned long flags;

+       spin_lock_irqsave(&pcf_pending_lock, flags);
        pcf_pending = 1;
+       spin_unlock_irqrestore(&pcf_pending_lock, flags);
        wake_up_interruptible(&pcf_wait);
        return IRQ_HANDLED;

}

Signature · 1 line
Linux rubicon 2.5.75-mm1-jd10 #1 SMP Sat Jul 12 19:40:28 CEST 2003 i686
#3 lore raw
In reply to Jan Dittmer
Quoted 9 lines · Jan Dittmer

Hi Greg,

these are 2 patches to the drivers/i2c subdirectory.

The first patch removes a warning from i2c-algo-bit.c, which I get regularly with my tv cards. It's more an info than a failure and spamming the logs at a rate of about 1/min. It indicates a send failure on the i2c bus or a miss of the ACK. Technically I think, it should resend the message, shouldn't it?

Can you just change this to dev_dbg() for people to still see it if they want to?

Quoted 3 lines

The second patch removes the cli/sti usage from i2c-elektor. It's only used to protect pcf_pending from changing. I replaced it (hopefully correct) with a spinlock.

Like Christoph said, this isn't correct.

Quoted 2 lines

The third patch is actually a resend and converts w83781d to use milli Celsius instead of centi Celsius.

Sorry for not getting to this previously, I have applied it and will send it on later this evening.

thanks,

greg k-h