X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fi2c%2Fbusses%2Fi2c-elektor.c;h=2fda2b8448a6bcb486e745cc5219eb298002e364;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=c16d97e957b32bb36eb958ac484f86cc8d834ccd;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c index c16d97e95..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 @@ -143,7 +157,7 @@ static int pcf_isa_init(void) } } if (irq > 0) { - if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", 0) < 0) { + if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", NULL) < 0) { printk(KERN_ERR "i2c-elektor: Request irq%d failed\n", irq); irq = 0; } else @@ -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 @@ -244,7 +258,7 @@ static int __init i2c_pcfisa_init(void) fail: if (irq > 0) { disable_irq(irq); - free_irq(irq, 0); + free_irq(irq, NULL); } if (!mmapped) @@ -258,7 +272,7 @@ static void i2c_pcfisa_exit(void) if (irq > 0) { disable_irq(irq); - free_irq(irq, 0); + free_irq(irq, NULL); } if (!mmapped) @@ -269,11 +283,11 @@ MODULE_AUTHOR("Hans Berglund "); MODULE_DESCRIPTION("I2C-Bus adapter routines for PCF8584 ISA bus adapter"); MODULE_LICENSE("GPL"); -MODULE_PARM(base, "i"); -MODULE_PARM(irq, "i"); -MODULE_PARM(clock, "i"); -MODULE_PARM(own, "i"); -MODULE_PARM(mmapped, "i"); +module_param(base, int, 0); +module_param(irq, int, 0); +module_param(clock, int, 0); +module_param(own, int, 0); +module_param(mmapped, int, 0); module_init(i2c_pcfisa_init); module_exit(i2c_pcfisa_exit);