diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-amd8111.c')
-rw-r--r-- | drivers/i2c/busses/i2c-amd8111.c | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index 5d1a27ef2504..3972208876b3 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/acpi.h> | ||
19 | #include <asm/io.h> | 20 | #include <asm/io.h> |
20 | 21 | ||
21 | MODULE_LICENSE("GPL"); | 22 | MODULE_LICENSE("GPL"); |
@@ -77,7 +78,7 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus) | |||
77 | if (!timeout) { | 78 | if (!timeout) { |
78 | dev_warn(&smbus->dev->dev, | 79 | dev_warn(&smbus->dev->dev, |
79 | "Timeout while waiting for IBF to clear\n"); | 80 | "Timeout while waiting for IBF to clear\n"); |
80 | return -1; | 81 | return -ETIMEDOUT; |
81 | } | 82 | } |
82 | 83 | ||
83 | return 0; | 84 | return 0; |
@@ -93,7 +94,7 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus) | |||
93 | if (!timeout) { | 94 | if (!timeout) { |
94 | dev_warn(&smbus->dev->dev, | 95 | dev_warn(&smbus->dev->dev, |
95 | "Timeout while waiting for OBF to set\n"); | 96 | "Timeout while waiting for OBF to set\n"); |
96 | return -1; | 97 | return -ETIMEDOUT; |
97 | } | 98 | } |
98 | 99 | ||
99 | return 0; | 100 | return 0; |
@@ -102,16 +103,21 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus) | |||
102 | static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address, | 103 | static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address, |
103 | unsigned char *data) | 104 | unsigned char *data) |
104 | { | 105 | { |
105 | if (amd_ec_wait_write(smbus)) | 106 | int status; |
106 | return -1; | 107 | |
108 | status = amd_ec_wait_write(smbus); | ||
109 | if (status) | ||
110 | return status; | ||
107 | outb(AMD_EC_CMD_RD, smbus->base + AMD_EC_CMD); | 111 | outb(AMD_EC_CMD_RD, smbus->base + AMD_EC_CMD); |
108 | 112 | ||
109 | if (amd_ec_wait_write(smbus)) | 113 | status = amd_ec_wait_write(smbus); |
110 | return -1; | 114 | if (status) |
115 | return status; | ||
111 | outb(address, smbus->base + AMD_EC_DATA); | 116 | outb(address, smbus->base + AMD_EC_DATA); |
112 | 117 | ||
113 | if (amd_ec_wait_read(smbus)) | 118 | status = amd_ec_wait_read(smbus); |
114 | return -1; | 119 | if (status) |
120 | return status; | ||
115 | *data = inb(smbus->base + AMD_EC_DATA); | 121 | *data = inb(smbus->base + AMD_EC_DATA); |
116 | 122 | ||
117 | return 0; | 123 | return 0; |
@@ -120,16 +126,21 @@ static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address, | |||
120 | static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address, | 126 | static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address, |
121 | unsigned char data) | 127 | unsigned char data) |
122 | { | 128 | { |
123 | if (amd_ec_wait_write(smbus)) | 129 | int status; |
124 | return -1; | 130 | |
131 | status = amd_ec_wait_write(smbus); | ||
132 | if (status) | ||
133 | return status; | ||
125 | outb(AMD_EC_CMD_WR, smbus->base + AMD_EC_CMD); | 134 | outb(AMD_EC_CMD_WR, smbus->base + AMD_EC_CMD); |
126 | 135 | ||
127 | if (amd_ec_wait_write(smbus)) | 136 | status = amd_ec_wait_write(smbus); |
128 | return -1; | 137 | if (status) |
138 | return status; | ||
129 | outb(address, smbus->base + AMD_EC_DATA); | 139 | outb(address, smbus->base + AMD_EC_DATA); |
130 | 140 | ||
131 | if (amd_ec_wait_write(smbus)) | 141 | status = amd_ec_wait_write(smbus); |
132 | return -1; | 142 | if (status) |
143 | return status; | ||
133 | outb(data, smbus->base + AMD_EC_DATA); | 144 | outb(data, smbus->base + AMD_EC_DATA); |
134 | 145 | ||
135 | return 0; | 146 | return 0; |
@@ -267,12 +278,17 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, | |||
267 | 278 | ||
268 | default: | 279 | default: |
269 | dev_warn(&adap->dev, "Unsupported transaction %d\n", size); | 280 | dev_warn(&adap->dev, "Unsupported transaction %d\n", size); |
270 | return -1; | 281 | return -EOPNOTSUPP; |
271 | } | 282 | } |
272 | 283 | ||
273 | amd_ec_write(smbus, AMD_SMB_ADDR, addr << 1); | 284 | amd_ec_write(smbus, AMD_SMB_ADDR, addr << 1); |
274 | amd_ec_write(smbus, AMD_SMB_PRTCL, protocol); | 285 | amd_ec_write(smbus, AMD_SMB_PRTCL, protocol); |
275 | 286 | ||
287 | /* FIXME this discards status from ec_read(); so temp[0] will | ||
288 | * hold stack garbage ... the rest of this routine will act | ||
289 | * nonsensically. Ignored ec_write() status might explain | ||
290 | * some such failures... | ||
291 | */ | ||
276 | amd_ec_read(smbus, AMD_SMB_STS, temp + 0); | 292 | amd_ec_read(smbus, AMD_SMB_STS, temp + 0); |
277 | 293 | ||
278 | if (~temp[0] & AMD_SMB_STS_DONE) { | 294 | if (~temp[0] & AMD_SMB_STS_DONE) { |
@@ -286,7 +302,7 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, | |||
286 | } | 302 | } |
287 | 303 | ||
288 | if ((~temp[0] & AMD_SMB_STS_DONE) || (temp[0] & AMD_SMB_STS_STATUS)) | 304 | if ((~temp[0] & AMD_SMB_STS_DONE) || (temp[0] & AMD_SMB_STS_STATUS)) |
289 | return -1; | 305 | return -EIO; |
290 | 306 | ||
291 | if (read_write == I2C_SMBUS_WRITE) | 307 | if (read_write == I2C_SMBUS_WRITE) |
292 | return 0; | 308 | return 0; |
@@ -359,6 +375,10 @@ static int __devinit amd8111_probe(struct pci_dev *dev, | |||
359 | smbus->base = pci_resource_start(dev, 0); | 375 | smbus->base = pci_resource_start(dev, 0); |
360 | smbus->size = pci_resource_len(dev, 0); | 376 | smbus->size = pci_resource_len(dev, 0); |
361 | 377 | ||
378 | error = acpi_check_resource_conflict(&dev->resource[0]); | ||
379 | if (error) | ||
380 | goto out_kfree; | ||
381 | |||
362 | if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) { | 382 | if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) { |
363 | error = -EBUSY; | 383 | error = -EBUSY; |
364 | goto out_kfree; | 384 | goto out_kfree; |
@@ -368,7 +388,7 @@ static int __devinit amd8111_probe(struct pci_dev *dev, | |||
368 | snprintf(smbus->adapter.name, sizeof(smbus->adapter.name), | 388 | snprintf(smbus->adapter.name, sizeof(smbus->adapter.name), |
369 | "SMBus2 AMD8111 adapter at %04x", smbus->base); | 389 | "SMBus2 AMD8111 adapter at %04x", smbus->base); |
370 | smbus->adapter.id = I2C_HW_SMBUS_AMD8111; | 390 | smbus->adapter.id = I2C_HW_SMBUS_AMD8111; |
371 | smbus->adapter.class = I2C_CLASS_HWMON; | 391 | smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; |
372 | smbus->adapter.algo = &smbus_algorithm; | 392 | smbus->adapter.algo = &smbus_algorithm; |
373 | smbus->adapter.algo_data = smbus; | 393 | smbus->adapter.algo_data = smbus; |
374 | 394 | ||