summaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r--drivers/i2c/busses/i2c-amd756.c2
-rw-r--r--drivers/i2c/busses/i2c-au1550.c2
-rw-r--r--drivers/i2c/busses/i2c-mpc.c16
-rw-r--r--drivers/i2c/busses/i2c-nforce2.c28
-rw-r--r--drivers/i2c/busses/i2c-piix4.c47
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c28
-rw-r--r--drivers/i2c/busses/i2c-sibyte.c6
7 files changed, 92 insertions, 37 deletions
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
index 2fa43183d37..43508d61eb7 100644
--- a/drivers/i2c/busses/i2c-amd756.c
+++ b/drivers/i2c/busses/i2c-amd756.c
@@ -290,7 +290,7 @@ static u32 amd756_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
- I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL;
+ I2C_FUNC_SMBUS_BLOCK_DATA;
}
static const struct i2c_algorithm smbus_algorithm = {
diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c
index 491718fe46b..cae9dc89d88 100644
--- a/drivers/i2c/busses/i2c-au1550.c
+++ b/drivers/i2c/busses/i2c-au1550.c
@@ -335,7 +335,7 @@ i2c_au1550_probe(struct platform_device *pdev)
goto out_mem;
}
- priv->psc_base = r->start;
+ priv->psc_base = CKSEG1ADDR(r->start);
priv->xfer_timeout = 200;
priv->ack_timeout = 200;
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 18beb0ad7bf..a076129de7e 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -99,7 +99,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
u32 x;
int result = 0;
- if (i2c->irq == 0)
+ if (i2c->irq == NO_IRQ)
{
while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
schedule();
@@ -329,10 +329,9 @@ static int fsl_i2c_probe(struct platform_device *pdev)
return -ENOMEM;
i2c->irq = platform_get_irq(pdev, 0);
- if (i2c->irq < 0) {
- result = -ENXIO;
- goto fail_get_irq;
- }
+ if (i2c->irq < 0)
+ i2c->irq = NO_IRQ; /* Use polling */
+
i2c->flags = pdata->device_flags;
init_waitqueue_head(&i2c->queue);
@@ -344,7 +343,7 @@ static int fsl_i2c_probe(struct platform_device *pdev)
goto fail_map;
}
- if (i2c->irq != 0)
+ if (i2c->irq != NO_IRQ)
if ((result = request_irq(i2c->irq, mpc_i2c_isr,
IRQF_SHARED, "i2c-mpc", i2c)) < 0) {
printk(KERN_ERR
@@ -367,12 +366,11 @@ static int fsl_i2c_probe(struct platform_device *pdev)
return result;
fail_add:
- if (i2c->irq != 0)
+ if (i2c->irq != NO_IRQ)
free_irq(i2c->irq, i2c);
fail_irq:
iounmap(i2c->base);
fail_map:
- fail_get_irq:
kfree(i2c);
return result;
};
@@ -384,7 +382,7 @@ static int fsl_i2c_remove(struct platform_device *pdev)
i2c_del_adapter(&i2c->adap);
platform_set_drvdata(pdev, NULL);
- if (i2c->irq != 0)
+ if (i2c->irq != NO_IRQ)
free_irq(i2c->irq, i2c);
iounmap(i2c->base);
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index 3dac920e53e..43c9f8df950 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -50,6 +50,7 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/delay.h>
+#include <linux/dmi.h>
#include <asm/io.h>
MODULE_LICENSE("GPL");
@@ -109,6 +110,18 @@ struct nforce2_smbus {
/* Misc definitions */
#define MAX_TIMEOUT 100
+/* We disable the second SMBus channel on these boards */
+static struct dmi_system_id __devinitdata nforce2_dmi_blacklist2[] = {
+ {
+ .ident = "DFI Lanparty NF4 Expert",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "DFI Corp,LTD"),
+ DMI_MATCH(DMI_BOARD_NAME, "LP UT NF4 Expert"),
+ },
+ },
+ { }
+};
+
static struct pci_driver nforce2_driver;
static void nforce2_abort(struct i2c_adapter *adap)
@@ -367,10 +380,17 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_
smbuses[0].base = 0; /* to have a check value */
}
/* SMBus adapter 2 */
- res2 = nforce2_probe_smb(dev, 5, NFORCE_PCI_SMB2, &smbuses[1], "SMB2");
- if (res2 < 0) {
- dev_err(&dev->dev, "Error probing SMB2.\n");
- smbuses[1].base = 0; /* to have a check value */
+ if (dmi_check_system(nforce2_dmi_blacklist2)) {
+ dev_err(&dev->dev, "Disabling SMB2 for safety reasons.\n");
+ res2 = -EPERM;
+ smbuses[1].base = 0;
+ } else {
+ res2 = nforce2_probe_smb(dev, 5, NFORCE_PCI_SMB2, &smbuses[1],
+ "SMB2");
+ if (res2 < 0) {
+ dev_err(&dev->dev, "Error probing SMB2.\n");
+ smbuses[1].base = 0; /* to have a check value */
+ }
}
if ((res1 < 0) && (res2 < 0)) {
/* we did not find even one of the SMBuses, so we give up */
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index fdc9ad805e3..ac916596858 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -104,10 +104,31 @@ MODULE_PARM_DESC(force_addr,
static int piix4_transaction(void);
static unsigned short piix4_smba;
+static int srvrworks_csb5_delay;
static struct pci_driver piix4_driver;
static struct i2c_adapter piix4_adapter;
-static struct dmi_system_id __devinitdata piix4_dmi_table[] = {
+static struct dmi_system_id __devinitdata piix4_dmi_blacklist[] = {
+ {
+ .ident = "Sapphire AM2RD790",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "SAPPHIRE Inc."),
+ DMI_MATCH(DMI_BOARD_NAME, "PC-AM2RD790"),
+ },
+ },
+ {
+ .ident = "DFI Lanparty UT 790FX",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "DFI Inc."),
+ DMI_MATCH(DMI_BOARD_NAME, "LP UT 790FX"),
+ },
+ },
+ { }
+};
+
+/* The IBM entry is in a separate table because we only check it
+ on Intel-based systems */
+static struct dmi_system_id __devinitdata piix4_dmi_ibm[] = {
{
.ident = "IBM",
.matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
@@ -122,8 +143,20 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev));
+ if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
+ (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5))
+ srvrworks_csb5_delay = 1;
+
+ /* On some motherboards, it was reported that accessing the SMBus
+ caused severe hardware problems */
+ if (dmi_check_system(piix4_dmi_blacklist)) {
+ dev_err(&PIIX4_dev->dev,
+ "Accessing the SMBus on this system is unsafe!\n");
+ return -EPERM;
+ }
+
/* Don't access SMBus on IBM systems which get corrupted eeproms */
- if (dmi_check_system(piix4_dmi_table) &&
+ if (dmi_check_system(piix4_dmi_ibm) &&
PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {
dev_err(&PIIX4_dev->dev, "IBM system detected; this module "
"may corrupt your serial eeprom! Refusing to load "
@@ -230,10 +263,14 @@ static int piix4_transaction(void)
outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
/* We will always wait for a fraction of a second! (See PIIX4 docs errata) */
- do {
+ if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */
+ msleep(2);
+ else
+ msleep(1);
+
+ while ((timeout++ < MAX_TIMEOUT) &&
+ ((temp = inb_p(SMBHSTSTS)) & 0x01))
msleep(1);
- temp = inb_p(SMBHSTSTS);
- } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
/* If the SMBus is still busy, we give up */
if (timeout >= MAX_TIMEOUT) {
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 1305ef190fc..9e8c875437b 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -290,12 +290,12 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
* bus, or started a new i2c message
*/
- if (iicstat & S3C2410_IICSTAT_LASTBIT &&
+ if (iicstat & S3C2410_IICSTAT_LASTBIT &&
!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
/* ack was not received... */
dev_dbg(i2c->dev, "ack was not received\n");
- s3c24xx_i2c_stop(i2c, -EREMOTEIO);
+ s3c24xx_i2c_stop(i2c, -ENXIO);
goto out_ack;
}
@@ -305,7 +305,7 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
i2c->state = STATE_WRITE;
/* terminate the transfer if there is nothing to do
- * (used by the i2c probe to find devices */
+ * as this is used by the i2c probe to find devices. */
if (is_lastmsg(i2c) && i2c->msg->len == 0) {
s3c24xx_i2c_stop(i2c, 0);
@@ -323,7 +323,17 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
* end of the message, and if so, work out what to do
*/
+ if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
+ if (iicstat & S3C2410_IICSTAT_LASTBIT) {
+ dev_dbg(i2c->dev, "WRITE: No Ack\n");
+
+ s3c24xx_i2c_stop(i2c, -ECONNREFUSED);
+ goto out_ack;
+ }
+ }
+
retry_write:
+
if (!is_msgend(i2c)) {
byte = i2c->msg->buf[i2c->msg_ptr++];
writeb(byte, i2c->regs + S3C2410_IICDS);
@@ -377,17 +387,6 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
* going to do any more read/write
*/
- if (!(i2c->msg->flags & I2C_M_IGNORE_NAK) &&
- !(is_msglast(i2c) && is_lastmsg(i2c))) {
-
- if (iicstat & S3C2410_IICSTAT_LASTBIT) {
- dev_dbg(i2c->dev, "READ: No Ack\n");
-
- s3c24xx_i2c_stop(i2c, -ECONNREFUSED);
- goto out_ack;
- }
- }
-
byte = readb(i2c->regs + S3C2410_IICDS);
i2c->msg->buf[i2c->msg_ptr++] = byte;
@@ -949,3 +948,4 @@ MODULE_DESCRIPTION("S3C24XX I2C Bus driver");
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:s3c2410-i2c");
+MODULE_ALIAS("platform:s3c2440-i2c");
diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c
index 8fbbdb4c2f3..114634da6c6 100644
--- a/drivers/i2c/busses/i2c-sibyte.c
+++ b/drivers/i2c/busses/i2c-sibyte.c
@@ -132,14 +132,14 @@ static const struct i2c_algorithm i2c_sibyte_algo = {
/*
* registering functions to load algorithms at runtime
*/
-int __init i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed)
+static int __init i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed)
{
struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data;
- /* register new adapter to i2c module... */
+ /* Register new adapter to i2c module... */
i2c_adap->algo = &i2c_sibyte_algo;
- /* Set the frequency to 100 kHz */
+ /* Set the requested frequency. */
csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ));
csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL));