diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-12 15:14:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-05-12 15:14:52 -0400 |
commit | be1fd94fd698e9dfa2676f688d4e9b034e0d4b9e (patch) | |
tree | fc19e966f53d2bc7202fd4565d999595515ce50b /drivers | |
parent | 0d38eddab9ce6de3a9d6d583043dfa97b6bc0d3b (diff) | |
parent | 95563d343fec8d3e2f667c95230ac4ab7674b757 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/i2c-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/i2c-2.6:
[PATCH] scx200_acb: Fix for the CS5535 errata
[PATCH] scx200_acb: Fix resource name use after free
[PATCH] scx200_acb: Fix return on init error
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/busses/scx200_acb.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 8bd305e47f0d..a140e4536a4e 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c | |||
@@ -133,6 +133,9 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status) | |||
133 | 133 | ||
134 | outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1); | 134 | outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1); |
135 | outb(ACBST_STASTR | ACBST_NEGACK, ACBST); | 135 | outb(ACBST_STASTR | ACBST_NEGACK, ACBST); |
136 | |||
137 | /* Reset the status register */ | ||
138 | outb(0, ACBST); | ||
136 | return; | 139 | return; |
137 | } | 140 | } |
138 | 141 | ||
@@ -228,6 +231,10 @@ static void scx200_acb_poll(struct scx200_acb_iface *iface) | |||
228 | timeout = jiffies + POLL_TIMEOUT; | 231 | timeout = jiffies + POLL_TIMEOUT; |
229 | while (time_before(jiffies, timeout)) { | 232 | while (time_before(jiffies, timeout)) { |
230 | status = inb(ACBST); | 233 | status = inb(ACBST); |
234 | |||
235 | /* Reset the status register to avoid the hang */ | ||
236 | outb(0, ACBST); | ||
237 | |||
231 | if ((status & (ACBST_SDAST|ACBST_BER|ACBST_NEGACK)) != 0) { | 238 | if ((status & (ACBST_SDAST|ACBST_BER|ACBST_NEGACK)) != 0) { |
232 | scx200_acb_machine(iface, status); | 239 | scx200_acb_machine(iface, status); |
233 | return; | 240 | return; |
@@ -415,7 +422,6 @@ static int __init scx200_acb_create(const char *text, int base, int index) | |||
415 | struct scx200_acb_iface *iface; | 422 | struct scx200_acb_iface *iface; |
416 | struct i2c_adapter *adapter; | 423 | struct i2c_adapter *adapter; |
417 | int rc; | 424 | int rc; |
418 | char description[64]; | ||
419 | 425 | ||
420 | iface = kzalloc(sizeof(*iface), GFP_KERNEL); | 426 | iface = kzalloc(sizeof(*iface), GFP_KERNEL); |
421 | if (!iface) { | 427 | if (!iface) { |
@@ -434,10 +440,7 @@ static int __init scx200_acb_create(const char *text, int base, int index) | |||
434 | 440 | ||
435 | mutex_init(&iface->mutex); | 441 | mutex_init(&iface->mutex); |
436 | 442 | ||
437 | snprintf(description, sizeof(description), "%s ACCESS.bus [%s]", | 443 | if (!request_region(base, 8, adapter->name)) { |
438 | text, adapter->name); | ||
439 | |||
440 | if (request_region(base, 8, description) == 0) { | ||
441 | printk(KERN_ERR NAME ": can't allocate io 0x%x-0x%x\n", | 444 | printk(KERN_ERR NAME ": can't allocate io 0x%x-0x%x\n", |
442 | base, base + 8-1); | 445 | base, base + 8-1); |
443 | rc = -EBUSY; | 446 | rc = -EBUSY; |
@@ -524,6 +527,9 @@ static int __init scx200_acb_init(void) | |||
524 | } else if (pci_dev_present(divil_pci)) | 527 | } else if (pci_dev_present(divil_pci)) |
525 | rc = scx200_add_cs553x(); | 528 | rc = scx200_add_cs553x(); |
526 | 529 | ||
530 | /* If at least one bus was created, init must succeed */ | ||
531 | if (scx200_acb_list) | ||
532 | return 0; | ||
527 | return rc; | 533 | return rc; |
528 | } | 534 | } |
529 | 535 | ||