summaryrefslogtreecommitdiff
path: root/drivers/i2c/busses/i2c-amd8111.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-15 18:16:05 (GMT)
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-15 18:16:05 (GMT)
commitdc221eae08eea3b0db127d1f152fac24d10b6a52 (patch)
treeeea4cc64f2568db6aea94b9491120525ebcd738f /drivers/i2c/busses/i2c-amd8111.c
parent98339cbd360b77c3167db287fd611468c2c44559 (diff)
parent4735c98f8447acb1c8977e2b8024640f7bf36dd6 (diff)
downloadlinux-fsl-qoriq-dc221eae08eea3b0db127d1f152fac24d10b6a52.tar.xz
Merge branch 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6
* 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6: (56 commits) i2c: Add detection capability to new-style drivers i2c: Call client_unregister for new-style devices too i2c: Clean up old chip drivers i2c-ibm_iic: Register child nodes i2c: New-style EEPROM driver using device IDs i2c: Export the i2c_bus_type symbol i2c-au1550: Fix PM support i2c-dev: Delete empty detach_client callback i2c: Drop stray references to lm_sensors i2c: Check for ACPI resource conflicts i2c-ocores: basic PM support i2c-sibyte: SWARM I2C board initialization i2c-i801: Fix handling of error conditions i2c-i801: Rename local variable temp to status i2c-i801: Properly report bus arbitration loss i2c-i801: Remove verbose debugging messages i2c-algo-pcf: Drop unused struct members i2c-algo-pcf: Multi-master lost-arbitration improvement i2c: Deprecate the legacy gpio drivers i2c-pxa: Initialize early ...
Diffstat (limited to 'drivers/i2c/busses/i2c-amd8111.c')
-rw-r--r--drivers/i2c/busses/i2c-amd8111.c54
1 files changed, 37 insertions, 17 deletions
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
index 5d1a27e..3972208 100644
--- a/drivers/i2c/busses/i2c-amd8111.c
+++ b/drivers/i2c/busses/i2c-amd8111.c
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/delay.h>
+#include <linux/acpi.h>
#include <asm/io.h>
MODULE_LICENSE("GPL");
@@ -77,7 +78,7 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus)
if (!timeout) {
dev_warn(&smbus->dev->dev,
"Timeout while waiting for IBF to clear\n");
- return -1;
+ return -ETIMEDOUT;
}
return 0;
@@ -93,7 +94,7 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus)
if (!timeout) {
dev_warn(&smbus->dev->dev,
"Timeout while waiting for OBF to set\n");
- return -1;
+ return -ETIMEDOUT;
}
return 0;
@@ -102,16 +103,21 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus)
static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
unsigned char *data)
{
- if (amd_ec_wait_write(smbus))
- return -1;
+ int status;
+
+ status = amd_ec_wait_write(smbus);
+ if (status)
+ return status;
outb(AMD_EC_CMD_RD, smbus->base + AMD_EC_CMD);
- if (amd_ec_wait_write(smbus))
- return -1;
+ status = amd_ec_wait_write(smbus);
+ if (status)
+ return status;
outb(address, smbus->base + AMD_EC_DATA);
- if (amd_ec_wait_read(smbus))
- return -1;
+ status = amd_ec_wait_read(smbus);
+ if (status)
+ return status;
*data = inb(smbus->base + AMD_EC_DATA);
return 0;
@@ -120,16 +126,21 @@ static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address,
unsigned char data)
{
- if (amd_ec_wait_write(smbus))
- return -1;
+ int status;
+
+ status = amd_ec_wait_write(smbus);
+ if (status)
+ return status;
outb(AMD_EC_CMD_WR, smbus->base + AMD_EC_CMD);
- if (amd_ec_wait_write(smbus))
- return -1;
+ status = amd_ec_wait_write(smbus);
+ if (status)
+ return status;
outb(address, smbus->base + AMD_EC_DATA);
- if (amd_ec_wait_write(smbus))
- return -1;
+ status = amd_ec_wait_write(smbus);
+ if (status)
+ return status;
outb(data, smbus->base + AMD_EC_DATA);
return 0;
@@ -267,12 +278,17 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
default:
dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
- return -1;
+ return -EOPNOTSUPP;
}
amd_ec_write(smbus, AMD_SMB_ADDR, addr << 1);
amd_ec_write(smbus, AMD_SMB_PRTCL, protocol);
+ /* FIXME this discards status from ec_read(); so temp[0] will
+ * hold stack garbage ... the rest of this routine will act
+ * nonsensically. Ignored ec_write() status might explain
+ * some such failures...
+ */
amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
if (~temp[0] & AMD_SMB_STS_DONE) {
@@ -286,7 +302,7 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
}
if ((~temp[0] & AMD_SMB_STS_DONE) || (temp[0] & AMD_SMB_STS_STATUS))
- return -1;
+ return -EIO;
if (read_write == I2C_SMBUS_WRITE)
return 0;
@@ -359,6 +375,10 @@ static int __devinit amd8111_probe(struct pci_dev *dev,
smbus->base = pci_resource_start(dev, 0);
smbus->size = pci_resource_len(dev, 0);
+ error = acpi_check_resource_conflict(&dev->resource[0]);
+ if (error)
+ goto out_kfree;
+
if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) {
error = -EBUSY;
goto out_kfree;
@@ -368,7 +388,7 @@ static int __devinit amd8111_probe(struct pci_dev *dev,
snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
"SMBus2 AMD8111 adapter at %04x", smbus->base);
smbus->adapter.id = I2C_HW_SMBUS_AMD8111;
- smbus->adapter.class = I2C_CLASS_HWMON;
+ smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
smbus->adapter.algo = &smbus_algorithm;
smbus->adapter.algo_data = smbus;