From 97140342e69d479a3ad82bfd4c154c0b08fe3eea Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 14 Jul 2008 22:38:25 +0200 Subject: i2c: Bus drivers return -Errno not -1 Tighten error paths used by various i2c adapters (mostly x86) so they return real fault/errno codes instead of a "-1" (which is most often interpreted as "-EPERM"). Build tested, with eyeball review. One minor initial goal is to have adapters consistently return the code "-ENXIO" when addressing a device doesn't get an ACK response, at least in the probe paths where they are already good at stifling related logspam. Signed-off-by: David Brownell Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-amd8111.c | 47 ++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 16 deletions(-) (limited to 'drivers/i2c/busses/i2c-amd8111.c') diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index 5d1a27e..a4f6879 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -77,7 +77,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 +93,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 +102,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 +125,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 +277,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 +301,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; -- cgit v1.1 From 3401b2fff38fbb8b73ea6bcc69a8370ae5d2a7a0 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:29 +0200 Subject: i2c: Let bus drivers add SPD to their class Let general purpose I2C/SMBus bus drivers add SPD to their class. Once this is done, we will be able to tell the eeprom driver to only probe for SPD EEPROMs and similar on these buses. Note that I took a conservative approach here, adding I2C_CLASS_SPD to many drivers that have no idea whether they can host SPD EEPROMs or not. This is to make sure that the eeprom driver doesn't stop probing buses where SPD EEPROMs or equivalent live. So, bus driver maintainers and users should feel free to remove the SPD class from drivers those buses never have SPD EEPROMs or they don't want the eeprom driver to bind to them. Likewise, feel free to add the SPD class to any bus driver I might have missed. Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-amd8111.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/i2c/busses/i2c-amd8111.c') diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index a4f6879..0e18fe8 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -383,7 +383,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; -- cgit v1.1 From 54fb4a05af0a4b814e6716cfdf3fa97fc6be7a32 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 22:38:33 +0200 Subject: i2c: Check for ACPI resource conflicts Check for ACPI resource conflicts in i2c bus drivers. I've included all recent SMBus master drivers for PC hardware. I've voluntarily left out: * Drivers that don't run on PCs: they can't conflict with ACPI. * Bit-banged bus device drivers: it's very unlikely that ACPI would deal with such buses. Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-amd8111.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/i2c/busses/i2c-amd8111.c') diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index 0e18fe8..3972208 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -16,6 +16,7 @@ #include #include #include +#include #include MODULE_LICENSE("GPL"); @@ -374,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; -- cgit v1.1