aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-amd756.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-amd756.c')
-rw-r--r--drivers/i2c/busses/i2c-amd756.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
index 43508d61eb7c..1ea39254dac6 100644
--- a/drivers/i2c/busses/i2c-amd756.c
+++ b/drivers/i2c/busses/i2c-amd756.c
@@ -1,7 +1,4 @@
1/* 1/*
2 amd756.c - Part of lm_sensors, Linux kernel modules for hardware
3 monitoring
4
5 Copyright (c) 1999-2002 Merlin Hughes <merlin@merlin.org> 2 Copyright (c) 1999-2002 Merlin Hughes <merlin@merlin.org>
6 3
7 Shamelessly ripped from i2c-piix4.c: 4 Shamelessly ripped from i2c-piix4.c:
@@ -45,6 +42,7 @@
45#include <linux/ioport.h> 42#include <linux/ioport.h>
46#include <linux/i2c.h> 43#include <linux/i2c.h>
47#include <linux/init.h> 44#include <linux/init.h>
45#include <linux/acpi.h>
48#include <asm/io.h> 46#include <asm/io.h>
49 47
50/* AMD756 SMBus address offsets */ 48/* AMD756 SMBus address offsets */
@@ -151,17 +149,17 @@ static int amd756_transaction(struct i2c_adapter *adap)
151 } 149 }
152 150
153 if (temp & GS_PRERR_STS) { 151 if (temp & GS_PRERR_STS) {
154 result = -1; 152 result = -ENXIO;
155 dev_dbg(&adap->dev, "SMBus Protocol error (no response)!\n"); 153 dev_dbg(&adap->dev, "SMBus Protocol error (no response)!\n");
156 } 154 }
157 155
158 if (temp & GS_COL_STS) { 156 if (temp & GS_COL_STS) {
159 result = -1; 157 result = -EIO;
160 dev_warn(&adap->dev, "SMBus collision!\n"); 158 dev_warn(&adap->dev, "SMBus collision!\n");
161 } 159 }
162 160
163 if (temp & GS_TO_STS) { 161 if (temp & GS_TO_STS) {
164 result = -1; 162 result = -ETIMEDOUT;
165 dev_dbg(&adap->dev, "SMBus protocol timeout!\n"); 163 dev_dbg(&adap->dev, "SMBus protocol timeout!\n");
166 } 164 }
167 165
@@ -189,22 +187,18 @@ static int amd756_transaction(struct i2c_adapter *adap)
189 outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE); 187 outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE);
190 msleep(100); 188 msleep(100);
191 outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS); 189 outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS);
192 return -1; 190 return -EIO;
193} 191}
194 192
195/* Return -1 on error. */ 193/* Return negative errno on error. */
196static s32 amd756_access(struct i2c_adapter * adap, u16 addr, 194static s32 amd756_access(struct i2c_adapter * adap, u16 addr,
197 unsigned short flags, char read_write, 195 unsigned short flags, char read_write,
198 u8 command, int size, union i2c_smbus_data * data) 196 u8 command, int size, union i2c_smbus_data * data)
199{ 197{
200 int i, len; 198 int i, len;
199 int status;
201 200
202 /** TODO: Should I supporte the 10-bit transfers? */
203 switch (size) { 201 switch (size) {
204 case I2C_SMBUS_PROC_CALL:
205 dev_dbg(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
206 /* TODO: Well... It is supported, I'm just not sure what to do here... */
207 return -1;
208 case I2C_SMBUS_QUICK: 202 case I2C_SMBUS_QUICK:
209 outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), 203 outw_p(((addr & 0x7f) << 1) | (read_write & 0x01),
210 SMB_HOST_ADDRESS); 204 SMB_HOST_ADDRESS);
@@ -251,13 +245,17 @@ static s32 amd756_access(struct i2c_adapter * adap, u16 addr,
251 } 245 }
252 size = AMD756_BLOCK_DATA; 246 size = AMD756_BLOCK_DATA;
253 break; 247 break;
248 default:
249 dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
250 return -EOPNOTSUPP;
254 } 251 }
255 252
256 /* How about enabling interrupts... */ 253 /* How about enabling interrupts... */
257 outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE); 254 outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE);
258 255
259 if (amd756_transaction(adap)) /* Error in transaction */ 256 status = amd756_transaction(adap);
260 return -1; 257 if (status)
258 return status;
261 259
262 if ((read_write == I2C_SMBUS_WRITE) || (size == AMD756_QUICK)) 260 if ((read_write == I2C_SMBUS_WRITE) || (size == AMD756_QUICK))
263 return 0; 261 return 0;
@@ -301,7 +299,7 @@ static const struct i2c_algorithm smbus_algorithm = {
301struct i2c_adapter amd756_smbus = { 299struct i2c_adapter amd756_smbus = {
302 .owner = THIS_MODULE, 300 .owner = THIS_MODULE,
303 .id = I2C_HW_SMBUS_AMD756, 301 .id = I2C_HW_SMBUS_AMD756,
304 .class = I2C_CLASS_HWMON, 302 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
305 .algo = &smbus_algorithm, 303 .algo = &smbus_algorithm,
306}; 304};
307 305
@@ -368,6 +366,11 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
368 amd756_ioport += SMB_ADDR_OFFSET; 366 amd756_ioport += SMB_ADDR_OFFSET;
369 } 367 }
370 368
369 error = acpi_check_region(amd756_ioport, SMB_IOSIZE,
370 amd756_driver.name);
371 if (error)
372 return error;
373
371 if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) { 374 if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) {
372 dev_err(&pdev->dev, "SMB region 0x%x already in use!\n", 375 dev_err(&pdev->dev, "SMB region 0x%x already in use!\n",
373 amd756_ioport); 376 amd756_ioport);