Commit 4b16dac1 authored by Aristeu Sergio Rozanski Filho's avatar Aristeu Sergio Rozanski Filho Committed by Greg Kroah-Hartman

[PATCH] i2c-elektor: get rid of cli/sti

this patch get rid of cli()/sti(). while correcting this I found
that when a process wakes by an interrupt, pcf_pending doesn't
come back to 0 and next caller will return imediately. also,
there are other drivers with the exact same problem. if you
don't have any comments on this, I'll do the same for other
drivers.


[I2C] i2c-elektor: getting rid of cli()/sti() usage
Signed-off-by: default avatarAristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 1a48e7c7
...@@ -59,6 +59,7 @@ static int mmapped; ...@@ -59,6 +59,7 @@ static int mmapped;
static wait_queue_head_t pcf_wait; static wait_queue_head_t pcf_wait;
static int pcf_pending; static int pcf_pending;
static spinlock_t lock;
/* ----- local functions ---------------------------------------------- */ /* ----- local functions ---------------------------------------------- */
...@@ -111,14 +112,24 @@ static int pcf_isa_getclock(void *data) ...@@ -111,14 +112,24 @@ static int pcf_isa_getclock(void *data)
static void pcf_isa_waitforpin(void) { static void pcf_isa_waitforpin(void) {
int timeout = 2; int timeout = 2;
long flags;
if (irq > 0) { if (irq > 0) {
cli(); spin_lock_irqsave(&lock, flags);
if (pcf_pending == 0) { if (pcf_pending == 0) {
interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ ); spin_unlock_irqrestore(&lock, flags);
} else if (interruptible_sleep_on_timeout(&pcf_wait,
timeout*HZ)) {
spin_lock_irqsave(&lock, flags);
if (pcf_pending == 1) {
pcf_pending = 0;
}
spin_unlock_irqrestore(&lock, flags);
}
} else {
pcf_pending = 0; pcf_pending = 0;
sti(); spin_unlock_irqrestore(&lock, flags);
}
} else { } else {
udelay(100); udelay(100);
} }
...@@ -126,7 +137,9 @@ static void pcf_isa_waitforpin(void) { ...@@ -126,7 +137,9 @@ static void pcf_isa_waitforpin(void) {
static irqreturn_t pcf_isa_handler(int this_irq, void *dev_id, struct pt_regs *regs) { static irqreturn_t pcf_isa_handler(int this_irq, void *dev_id, struct pt_regs *regs) {
spin_lock(&lock);
pcf_pending = 1; pcf_pending = 1;
spin_unlock(&lock);
wake_up_interruptible(&pcf_wait); wake_up_interruptible(&pcf_wait);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -134,6 +147,7 @@ static irqreturn_t pcf_isa_handler(int this_irq, void *dev_id, struct pt_regs *r ...@@ -134,6 +147,7 @@ static irqreturn_t pcf_isa_handler(int this_irq, void *dev_id, struct pt_regs *r
static int pcf_isa_init(void) static int pcf_isa_init(void)
{ {
spin_lock_init(&lock);
if (!mmapped) { if (!mmapped) {
if (!request_region(base, 2, "i2c (isa bus adapter)")) { if (!request_region(base, 2, "i2c (isa bus adapter)")) {
printk(KERN_ERR printk(KERN_ERR
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment