From 2369df933f1c632ec3f230774019e37c3969b7ec Mon Sep 17 00:00:00 2001 From: "Mark M. Hoffman" Date: Sat, 1 Jul 2006 17:01:59 +0200 Subject: [PATCH] i2c: Fix 'ignore' module parameter handling in i2c-core This patch fixes a bug in the handling of 'ignore' module parameters of I2C client drivers. Signed-off-by: Mark M. Hoffman Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/i2c-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index a45155f799d..9cb277d6aa4 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -756,9 +756,9 @@ int i2c_probe(struct i2c_adapter *adapter, "parameter for adapter %d, " "addr 0x%02x\n", adap_id, address_data->ignore[j + 1]); + ignore = 1; + break; } - ignore = 1; - break; } if (ignore) continue; -- cgit v1.2.3 From 39288e1ac10b3b9a68a629be67d81a0b53512c4e Mon Sep 17 00:00:00 2001 From: Peter Milne Date: Sat, 1 Jul 2006 17:03:20 +0200 Subject: [PATCH] i2c-iop3xx: Avoid addressing self Avoid addressing self when sending a slave address. Follows instruction in Intel 80331/80321 manuals. Ignoring this worked previously on 80321, but causes a hang on i2cdetect on 80331. Signed-off-by: Peter Milne Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-iop3xx.c | 17 ++++++++++------- drivers/i2c/busses/i2c-iop3xx.h | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index aca7e166860..48c56939c86 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -21,6 +21,9 @@ * - Make it work with IXP46x chips * - Cleanup function names, coding style, etc * + * - writing to slave address causes latchup on iop331. + * fix: driver refuses to address self. + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2. @@ -72,12 +75,6 @@ iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap) __raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET); } -static void -iop3xx_i2c_set_slave_addr(struct i2c_algo_iop3xx_data *iop3xx_adap) -{ - __raw_writel(MYSAR, iop3xx_adap->ioaddr + SAR_OFFSET); -} - static void iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap) { @@ -248,6 +245,13 @@ iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap, int status; int rc; + /* avoid writing to my slave address (hangs on 80331), + * forbidden in Intel developer manual + */ + if (msg->addr == MYSAR) { + return -EBUSY; + } + __raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET); cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK); @@ -498,7 +502,6 @@ iop3xx_i2c_probe(struct platform_device *pdev) spin_lock_init(&adapter_data->lock); iop3xx_i2c_reset(adapter_data); - iop3xx_i2c_set_slave_addr(adapter_data); iop3xx_i2c_enable(adapter_data); platform_set_drvdata(pdev, new_adapter); diff --git a/drivers/i2c/busses/i2c-iop3xx.h b/drivers/i2c/busses/i2c-iop3xx.h index e46ebaea7b1..8485861f6a3 100644 --- a/drivers/i2c/busses/i2c-iop3xx.h +++ b/drivers/i2c/busses/i2c-iop3xx.h @@ -80,7 +80,7 @@ #define IOP3XX_GPOD_I2C0 0x00c0 /* clear these bits to enable ch0 */ #define IOP3XX_GPOD_I2C1 0x0030 /* clear these bits to enable ch1 */ -#define MYSAR 0x02 /* SWAG a suitable slave address */ +#define MYSAR 0 /* default slave address */ #define I2C_ERR 321 #define I2C_ERR_BERR (I2C_ERR+0) -- cgit v1.2.3 From fd627a01477dadaef3bc8556e5e9d0ef80310c3a Mon Sep 17 00:00:00 2001 From: Thomas Andrews Date: Sat, 1 Jul 2006 17:05:12 +0200 Subject: [PATCH] scx200_acb: Fix the state machine Fix the scx200_acb state machine: * Nack was sent one byte too late on reads >= 2 bytes. * Stop bit was set one byte too late on reads. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/scx200_acb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 22a3eda0416..454086affaa 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -184,21 +184,21 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status) break; case state_read: - /* Set ACK if receiving the last byte */ - if (iface->len == 1) + /* Set ACK if _next_ byte will be the last one */ + if (iface->len == 2) outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1); else outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1); - *iface->ptr++ = inb(ACBSDA); - --iface->len; - - if (iface->len == 0) { + if (iface->len == 1) { iface->result = 0; iface->state = state_idle; outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1); } + *iface->ptr++ = inb(ACBSDA); + --iface->len; + break; case state_write: -- cgit v1.2.3 From c3efacaa68a75049a859cbfd03d52dfdebb7527b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 1 Jul 2006 17:06:43 +0200 Subject: [PATCH] scx200_acb: Fix the block transactions The scx200_acb i2c bus driver pretends to support SMBus block transactions, but in fact it implements the more simple I2C block transactions. Additionally, it lacks sanity checks on the length of the block transactions, which could lead to a buffer overrun. This fixes an oops reported by Alexander Atanasov: http://marc.theaimsgroup.com/?l=linux-kernel&m=114970382125094 Thanks to Ben Gardner for fixing my bugs :) Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/scx200_acb.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 454086affaa..ced309ff056 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -307,8 +307,12 @@ static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter, buffer = (u8 *)&cur_word; break; - case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + if (rw == I2C_SMBUS_READ) + data->block[0] = I2C_SMBUS_BLOCK_MAX; /* For now */ len = data->block[0]; + if (len == 0 || len > I2C_SMBUS_BLOCK_MAX) + return -EINVAL; buffer = &data->block[1]; break; @@ -372,7 +376,7 @@ static u32 scx200_acb_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_I2C_BLOCK; } /* For now, we only handle combined mode (smbus) */ -- cgit v1.2.3 From 8ced8eee8537b52ef5d77e28d7676ce81bc62359 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 1 Jul 2006 17:12:53 +0200 Subject: [PATCH] i2c-powermac: Fix master_xfer return value Fix the value returned by the i2c-powermac's master_xfer method. It should return the number of messages processed successfully, but instead returns the number of data bytes in the first (and only) processed message. Also explicitly mention the master_xfer convention so that future implementations get it right directly. Signed-off-by: Jean Delvare Acked-by: Benjamin Herrenschmidt Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-powermac.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index 2a0b3be7cdd..53bb4359386 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c @@ -148,8 +148,6 @@ static int i2c_powermac_master_xfer( struct i2c_adapter *adap, int read; int addrdir; - if (num != 1) - return -EINVAL; if (msgs->flags & I2C_M_TEN) return -EINVAL; read = (msgs->flags & I2C_M_RD) != 0; @@ -166,7 +164,7 @@ static int i2c_powermac_master_xfer( struct i2c_adapter *adap, rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len); bail: pmac_i2c_close(bus); - return rc < 0 ? rc : msgs->len; + return rc < 0 ? rc : 1; } static u32 i2c_powermac_func(struct i2c_adapter * adapter) -- cgit v1.2.3 From b39ad0cf7c19fc14e8f823b1b36245f7a3711655 Mon Sep 17 00:00:00 2001 From: "Mark M. Hoffman" Date: Sat, 1 Jul 2006 17:16:06 +0200 Subject: [PATCH] i2c: Handle i2c_add_adapter failure in i2c algorithm drivers Content-Disposition: inline; filename=i2c-algo-error-handling-fix.patch It is possible for i2c_add_adapter() to fail. Several I2C algorithm drivers ignore that fact. This (compile-tested only) patch fixes them. Signed-off-by: Mark M. Hoffman Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/algos/i2c-algo-bit.c | 3 +-- drivers/i2c/algos/i2c-algo-ite.c | 4 +--- drivers/i2c/algos/i2c-algo-pca.c | 6 +++--- drivers/i2c/algos/i2c-algo-pcf.c | 8 +++++--- drivers/i2c/algos/i2c-algo-sibyte.c | 4 +--- 5 files changed, 11 insertions(+), 14 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index df05df1a0ef..3d6fc82c2cf 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -544,8 +544,7 @@ int i2c_bit_add_bus(struct i2c_adapter *adap) adap->timeout = 100; /* default values, should */ adap->retries = 3; /* be replaced by defines */ - i2c_add_adapter(adap); - return 0; + return i2c_add_adapter(adap); } diff --git a/drivers/i2c/algos/i2c-algo-ite.c b/drivers/i2c/algos/i2c-algo-ite.c index 2db7bfc8522..70d8eefb5ef 100644 --- a/drivers/i2c/algos/i2c-algo-ite.c +++ b/drivers/i2c/algos/i2c-algo-ite.c @@ -742,10 +742,8 @@ int i2c_iic_add_bus(struct i2c_adapter *adap) adap->retries = 3; /* be replaced by defines */ adap->flags = 0; - i2c_add_adapter(adap); iic_init(iic_adap); - - return 0; + return i2c_add_adapter(adap); } diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index 82946acab4c..b88a6fcf7bd 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -374,10 +374,10 @@ int i2c_pca_add_bus(struct i2c_adapter *adap) adap->timeout = 100; /* default values, should */ adap->retries = 3; /* be replaced by defines */ - rval = pca_init(pca_adap); + if ((rval = pca_init(pca_adap))) + return rval; - if (!rval) - i2c_add_adapter(adap); + rval = i2c_add_adapter(adap); return rval; } diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index 6e498df1f71..5b24930adb5 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c @@ -479,9 +479,11 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap) adap->timeout = 100; /* default values, should */ adap->retries = 3; /* be replaced by defines */ - rval = pcf_init_8584(pcf_adap); - if (!rval) - i2c_add_adapter(adap); + if ((rval = pcf_init_8584(pcf_adap))) + return rval; + + rval = i2c_add_adapter(adap); + return rval; } diff --git a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c index 3df3f09995c..32d41c6fac0 100644 --- a/drivers/i2c/algos/i2c-algo-sibyte.c +++ b/drivers/i2c/algos/i2c-algo-sibyte.c @@ -173,9 +173,7 @@ int i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed) printk("\n"); } - i2c_add_adapter(i2c_adap); - - return 0; + return i2c_add_adapter(i2c_adap); } -- cgit v1.2.3 From 5313775f18f22f1dac2b548b598d47d65f90e6b0 Mon Sep 17 00:00:00 2001 From: Uwe Bugla Date: Sat, 1 Jul 2006 17:25:08 +0200 Subject: [PATCH] i2c-algo-bit: Wipe out dead code i2c-algo-bit: Wipe out dead code Signed-off-by: Uwe Bugla Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/algos/i2c-algo-bit.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 3d6fc82c2cf..ab230c033f9 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -372,7 +372,6 @@ static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) while (count > 0) { inval = i2c_inb(i2c_adap); -/*printk("%#02x ",inval); if ( ! (count % 16) ) printk("\n"); */ if (inval>=0) { *temp = inval; rdcount++; -- cgit v1.2.3 From 50436a47c6b10c6e4e84e24ea44c5cb85bbcd290 Mon Sep 17 00:00:00 2001 From: Ben Gardner Date: Sat, 1 Jul 2006 17:22:18 +0200 Subject: [PATCH] pca9539: Honor the force parameter The pca9539 driver doesn't honor the force parameter; it always does detection. This patch will skip detection if forced. Signed-off-by: Ben Gardner Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/chips/pca9539.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/chips/pca9539.c b/drivers/i2c/chips/pca9539.c index 54b6e6a4bee..cb22280cdd2 100644 --- a/drivers/i2c/chips/pca9539.c +++ b/drivers/i2c/chips/pca9539.c @@ -134,11 +134,13 @@ static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind) new_client->driver = &pca9539_driver; new_client->flags = 0; - /* Detection: the pca9539 only has 8 registers (0-7). - A read of 7 should succeed, but a read of 8 should fail. */ - if ((i2c_smbus_read_byte_data(new_client, 7) < 0) || - (i2c_smbus_read_byte_data(new_client, 8) >= 0)) - goto exit_kfree; + if (kind < 0) { + /* Detection: the pca9539 only has 8 registers (0-7). + A read of 7 should succeed, but a read of 8 should fail. */ + if ((i2c_smbus_read_byte_data(new_client, 7) < 0) || + (i2c_smbus_read_byte_data(new_client, 8) >= 0)) + goto exit_kfree; + } strlcpy(new_client->name, "pca9539", I2C_NAME_SIZE); -- cgit v1.2.3