X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fi2c%2Fbusses%2Fi2c-elektor.c;h=2fda2b8448a6bcb486e745cc5219eb298002e364;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=f6bd38b060eb65d6ca421ae17f42dba2e514870b;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c index f6bd38b06..2fda2b844 100644 --- a/drivers/i2c/busses/i2c-elektor.c +++ b/drivers/i2c/busses/i2c-elektor.c @@ -59,6 +59,7 @@ static int mmapped; static wait_queue_head_t pcf_wait; static int pcf_pending; +static spinlock_t lock; /* ----- local functions ---------------------------------------------- */ @@ -79,10 +80,10 @@ static void pcf_isa_setbyte(void *data, int ctl, int val) break; case 2: /* double mapped I/O needed for UP2000 board, I don't know why this... */ - writeb(val, address); + writeb(val, (void *)address); /* fall */ case 1: /* memory mapped I/O */ - writeb(val, address); + writeb(val, (void *)address); break; } } @@ -90,7 +91,7 @@ static void pcf_isa_setbyte(void *data, int ctl, int val) static int pcf_isa_getbyte(void *data, int ctl) { int address = ctl ? (base + 1) : base; - int val = mmapped ? readb(address) : inb(address); + int val = mmapped ? readb((void *)address) : inb(address); pr_debug("i2c-elektor: Read 0x%X 0x%02X\n", address, val); @@ -111,14 +112,24 @@ static int pcf_isa_getclock(void *data) static void pcf_isa_waitforpin(void) { int timeout = 2; + long flags; if (irq > 0) { - cli(); + spin_lock_irqsave(&lock, flags); if (pcf_pending == 0) { - interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ ); - } else + spin_unlock_irqrestore(&lock, flags); + 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; - sti(); + spin_unlock_irqrestore(&lock, flags); + } } else { udelay(100); } @@ -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) { + spin_lock(&lock); pcf_pending = 1; + spin_unlock(&lock); wake_up_interruptible(&pcf_wait); return IRQ_HANDLED; } @@ -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) { + spin_lock_init(&lock); if (!mmapped) { if (!request_region(base, 2, "i2c (isa bus adapter)")) { printk(KERN_ERR @@ -180,11 +194,10 @@ static int __init i2c_pcfisa_init(void) /* check to see we have memory mapped PCF8584 connected to the Cypress cy82c693 PCI-ISA bridge as on UP2000 board */ if (base == 0) { + struct pci_dev *cy693_dev; - struct pci_dev *cy693_dev = - pci_find_device(PCI_VENDOR_ID_CONTAQ, - PCI_DEVICE_ID_CONTAQ_82C693, NULL); - + cy693_dev = pci_get_device(PCI_VENDOR_ID_CONTAQ, + PCI_DEVICE_ID_CONTAQ_82C693, NULL); if (cy693_dev) { char config; /* yeap, we've found cypress, let's check config */ @@ -215,6 +228,7 @@ static int __init i2c_pcfisa_init(void) printk(KERN_INFO "i2c-elektor: found API UP2000 like board, will probe PCF8584 later.\n"); } } + pci_dev_put(cy693_dev); } } #endif