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 | |
| 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
| -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 | ||
