diff options
| author | <jgarzik@pretzel.yyz.us> | 2005-06-04 00:40:40 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-06-04 00:40:40 -0400 |
| commit | ae20ea8525a80a863f70d332cf47b71bd9f54c1f (patch) | |
| tree | 9d3cedeb65db521a8436b545bd91641549a18d24 /drivers/i2c | |
| parent | f497ba735fc9ff4e35a19641143708b3be1c7061 (diff) | |
| parent | 8be3de3fd8469154a2b3e18a4712032dac5b4a53 (diff) | |
Automatic merge of /spare/repo/linux-2.6/.git branch HEAD
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/i2c-ali1563.c | 46 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-keywest.c | 5 |
2 files changed, 36 insertions, 15 deletions
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 35710818fe47..fdd881aee618 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | * i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge | 2 | * i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2004 Patrick Mochel | 4 | * Copyright (C) 2004 Patrick Mochel |
| 5 | * 2005 Rudolf Marek <r.marek@sh.cvut.cz> | ||
| 5 | * | 6 | * |
| 6 | * The 1563 southbridge is deceptively similar to the 1533, with a | 7 | * The 1563 southbridge is deceptively similar to the 1533, with a |
| 7 | * few notable exceptions. One of those happens to be the fact they | 8 | * few notable exceptions. One of those happens to be the fact they |
| @@ -57,10 +58,11 @@ | |||
| 57 | #define HST_CNTL2_BLOCK 0x05 | 58 | #define HST_CNTL2_BLOCK 0x05 |
| 58 | 59 | ||
| 59 | 60 | ||
| 61 | #define HST_CNTL2_SIZEMASK 0x38 | ||
| 60 | 62 | ||
| 61 | static unsigned short ali1563_smba; | 63 | static unsigned short ali1563_smba; |
| 62 | 64 | ||
| 63 | static int ali1563_transaction(struct i2c_adapter * a) | 65 | static int ali1563_transaction(struct i2c_adapter * a, int size) |
| 64 | { | 66 | { |
| 65 | u32 data; | 67 | u32 data; |
| 66 | int timeout; | 68 | int timeout; |
| @@ -73,7 +75,7 @@ static int ali1563_transaction(struct i2c_adapter * a) | |||
| 73 | 75 | ||
| 74 | data = inb_p(SMB_HST_STS); | 76 | data = inb_p(SMB_HST_STS); |
| 75 | if (data & HST_STS_BAD) { | 77 | if (data & HST_STS_BAD) { |
| 76 | dev_warn(&a->dev,"ali1563: Trying to reset busy device\n"); | 78 | dev_err(&a->dev, "ali1563: Trying to reset busy device\n"); |
| 77 | outb_p(data | HST_STS_BAD,SMB_HST_STS); | 79 | outb_p(data | HST_STS_BAD,SMB_HST_STS); |
| 78 | data = inb_p(SMB_HST_STS); | 80 | data = inb_p(SMB_HST_STS); |
| 79 | if (data & HST_STS_BAD) | 81 | if (data & HST_STS_BAD) |
| @@ -94,19 +96,31 @@ static int ali1563_transaction(struct i2c_adapter * a) | |||
| 94 | 96 | ||
| 95 | if (timeout && !(data & HST_STS_BAD)) | 97 | if (timeout && !(data & HST_STS_BAD)) |
| 96 | return 0; | 98 | return 0; |
| 97 | dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n", | ||
| 98 | timeout ? "Timeout " : "", | ||
| 99 | data & HST_STS_FAIL ? "Transaction Failed " : "", | ||
| 100 | data & HST_STS_BUSERR ? "No response or Bus Collision " : "", | ||
| 101 | data & HST_STS_DEVERR ? "Device Error " : "", | ||
| 102 | !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); | ||
| 103 | 99 | ||
| 104 | if (!(data & HST_STS_DONE)) | 100 | if (!timeout) { |
| 101 | dev_err(&a->dev, "Timeout - Trying to KILL transaction!\n"); | ||
| 105 | /* Issue 'kill' to host controller */ | 102 | /* Issue 'kill' to host controller */ |
| 106 | outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2); | 103 | outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2); |
| 107 | else | 104 | data = inb_p(SMB_HST_STS); |
| 108 | /* Issue timeout to reset all devices on bus */ | 105 | } |
| 106 | |||
| 107 | /* device error - no response, ignore the autodetection case */ | ||
| 108 | if ((data & HST_STS_DEVERR) && (size != HST_CNTL2_QUICK)) { | ||
| 109 | dev_err(&a->dev, "Device error!\n"); | ||
| 110 | } | ||
| 111 | |||
| 112 | /* bus collision */ | ||
| 113 | if (data & HST_STS_BUSERR) { | ||
| 114 | dev_err(&a->dev, "Bus collision!\n"); | ||
| 115 | /* Issue timeout, hoping it helps */ | ||
| 109 | outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1); | 116 | outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1); |
| 117 | } | ||
| 118 | |||
| 119 | if (data & HST_STS_FAIL) { | ||
| 120 | dev_err(&a->dev, "Cleaning fail after KILL!\n"); | ||
| 121 | outb_p(0x0,SMB_HST_CNTL2); | ||
| 122 | } | ||
| 123 | |||
| 110 | return -1; | 124 | return -1; |
| 111 | } | 125 | } |
| 112 | 126 | ||
| @@ -149,7 +163,7 @@ static int ali1563_block_start(struct i2c_adapter * a) | |||
| 149 | 163 | ||
| 150 | if (timeout && !(data & HST_STS_BAD)) | 164 | if (timeout && !(data & HST_STS_BAD)) |
| 151 | return 0; | 165 | return 0; |
| 152 | dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n", | 166 | dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n", |
| 153 | timeout ? "Timeout " : "", | 167 | timeout ? "Timeout " : "", |
| 154 | data & HST_STS_FAIL ? "Transaction Failed " : "", | 168 | data & HST_STS_FAIL ? "Transaction Failed " : "", |
| 155 | data & HST_STS_BUSERR ? "No response or Bus Collision " : "", | 169 | data & HST_STS_BUSERR ? "No response or Bus Collision " : "", |
| @@ -242,13 +256,15 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr, | |||
| 242 | } | 256 | } |
| 243 | 257 | ||
| 244 | outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); | 258 | outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); |
| 245 | outb_p(inb_p(SMB_HST_CNTL2) | (size << 3), SMB_HST_CNTL2); | 259 | outb_p((inb_p(SMB_HST_CNTL2) & ~HST_CNTL2_SIZEMASK) | (size << 3), SMB_HST_CNTL2); |
| 246 | 260 | ||
| 247 | /* Write the command register */ | 261 | /* Write the command register */ |
| 262 | |||
| 248 | switch(size) { | 263 | switch(size) { |
| 249 | case HST_CNTL2_BYTE: | 264 | case HST_CNTL2_BYTE: |
| 250 | if (rw== I2C_SMBUS_WRITE) | 265 | if (rw== I2C_SMBUS_WRITE) |
| 251 | outb_p(cmd, SMB_HST_CMD); | 266 | /* Beware it uses DAT0 register and not CMD! */ |
| 267 | outb_p(cmd, SMB_HST_DAT0); | ||
| 252 | break; | 268 | break; |
| 253 | case HST_CNTL2_BYTE_DATA: | 269 | case HST_CNTL2_BYTE_DATA: |
| 254 | outb_p(cmd, SMB_HST_CMD); | 270 | outb_p(cmd, SMB_HST_CMD); |
| @@ -268,7 +284,7 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr, | |||
| 268 | goto Done; | 284 | goto Done; |
| 269 | } | 285 | } |
| 270 | 286 | ||
| 271 | if ((error = ali1563_transaction(a))) | 287 | if ((error = ali1563_transaction(a, size))) |
| 272 | goto Done; | 288 | goto Done; |
| 273 | 289 | ||
| 274 | if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK)) | 290 | if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK)) |
diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c index dd0d4c463146..867d443e7133 100644 --- a/drivers/i2c/busses/i2c-keywest.c +++ b/drivers/i2c/busses/i2c-keywest.c | |||
| @@ -516,6 +516,11 @@ create_iface(struct device_node *np, struct device *dev) | |||
| 516 | u32 *psteps, *prate; | 516 | u32 *psteps, *prate; |
| 517 | int rc; | 517 | int rc; |
| 518 | 518 | ||
| 519 | if (np->n_intrs < 1 || np->n_addrs < 1) { | ||
| 520 | printk(KERN_ERR "%s: Missing interrupt or address !\n", | ||
| 521 | np->full_name); | ||
| 522 | return -ENODEV; | ||
| 523 | } | ||
| 519 | if (pmac_low_i2c_lock(np)) | 524 | if (pmac_low_i2c_lock(np)) |
| 520 | return -ENODEV; | 525 | return -ENODEV; |
| 521 | 526 | ||
