Commit bdaf12b4 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging

* 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
  i2c-viapro: Don't log nacks
  i2c/pca954x: Remove __devinit and __devexit from probe and remove functions
  MAINTAINERS: Add maintainer for PCA9541 I2C bus master selector driver
  i2c/mux: Driver for PCA9541 I2C Master Selector
  i2c: Optimize function i2c_detect()
  i2c: Discard warning message on device instantiation from user-space
  i2c-amd8111: Add proper error handling
  i2c: Change to new flag variable
  i2c: Remove unneeded inclusions of <linux/i2c-id.h>
  i2c: Let i2c_parent_is_i2c_adapter return the parent adapter
  i2c: Simplify i2c_parent_is_i2c_adapter
  i2c-pca-platform: Change device name of request_irq
  i2c: Fix Kconfig dependencies
parents 7c024e95 bf5d95c8
...@@ -4541,6 +4541,12 @@ S: Maintained ...@@ -4541,6 +4541,12 @@ S: Maintained
F: drivers/leds/leds-pca9532.c F: drivers/leds/leds-pca9532.c
F: include/linux/leds-pca9532.h F: include/linux/leds-pca9532.h
PCA9541 I2C BUS MASTER SELECTOR DRIVER
M: Guenter Roeck <guenter.roeck@ericsson.com>
L: linux-i2c@vger.kernel.org
S: Maintained
F: drivers/i2c/muxes/pca9541.c
PCA9564/PCA9665 I2C BUS DRIVER PCA9564/PCA9665 I2C BUS DRIVER
M: Wolfram Sang <w.sang@pengutronix.de> M: Wolfram Sang <w.sang@pengutronix.de>
L: linux-i2c@vger.kernel.org L: linux-i2c@vger.kernel.org
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#define __NOUVEAU_I2C_H__ #define __NOUVEAU_I2C_H__
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h> #include <linux/i2c-algo-bit.h>
#include "drm_dp_helper.h" #include "drm_dp_helper.h"
......
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#include <drm_dp_helper.h> #include <drm_dp_helper.h>
#include <drm_fixed.h> #include <drm_fixed.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h> #include <linux/i2c-algo-bit.h>
struct radeon_bo; struct radeon_bo;
......
...@@ -75,7 +75,8 @@ config I2C_HELPER_AUTO ...@@ -75,7 +75,8 @@ config I2C_HELPER_AUTO
In doubt, say Y. In doubt, say Y.
config I2C_SMBUS config I2C_SMBUS
tristate "SMBus-specific protocols" if !I2C_HELPER_AUTO tristate
prompt "SMBus-specific protocols" if !I2C_HELPER_AUTO
help help
Say Y here if you want support for SMBus extensions to the I2C Say Y here if you want support for SMBus extensions to the I2C
specification. At the moment, the only supported extension is specification. At the moment, the only supported extension is
......
...@@ -9,6 +9,4 @@ obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o ...@@ -9,6 +9,4 @@ obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o
obj-$(CONFIG_I2C_MUX) += i2c-mux.o obj-$(CONFIG_I2C_MUX) += i2c-mux.o
obj-y += algos/ busses/ muxes/ obj-y += algos/ busses/ muxes/
ifeq ($(CONFIG_I2C_DEBUG_CORE),y) ccflags-$(CONFIG_I2C_DEBUG_CORE) := -DDEBUG
EXTRA_CFLAGS += -DDEBUG
endif
...@@ -15,3 +15,15 @@ config I2C_ALGOPCA ...@@ -15,3 +15,15 @@ config I2C_ALGOPCA
tristate "I2C PCA 9564 interfaces" tristate "I2C PCA 9564 interfaces"
endmenu endmenu
# In automatic configuration mode, we still have to define the
# symbols to avoid unmet dependencies.
if I2C_HELPER_AUTO
config I2C_ALGOBIT
tristate
config I2C_ALGOPCF
tristate
config I2C_ALGOPCA
tristate
endif
...@@ -6,6 +6,4 @@ obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o ...@@ -6,6 +6,4 @@ obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o
obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o
obj-$(CONFIG_I2C_ALGOPCA) += i2c-algo-pca.o obj-$(CONFIG_I2C_ALGOPCA) += i2c-algo-pca.o
ifeq ($(CONFIG_I2C_DEBUG_ALGO),y) ccflags-$(CONFIG_I2C_DEBUG_ALGO) := -DDEBUG
EXTRA_CFLAGS += -DDEBUG
endif
...@@ -76,6 +76,4 @@ obj-$(CONFIG_I2C_STUB) += i2c-stub.o ...@@ -76,6 +76,4 @@ obj-$(CONFIG_I2C_STUB) += i2c-stub.o
obj-$(CONFIG_SCx200_ACB) += scx200_acb.o obj-$(CONFIG_SCx200_ACB) += scx200_acb.o
obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o
ifeq ($(CONFIG_I2C_DEBUG_BUS),y) ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG
EXTRA_CFLAGS += -DDEBUG
endif
...@@ -69,7 +69,7 @@ static struct pci_driver amd8111_driver; ...@@ -69,7 +69,7 @@ static struct pci_driver amd8111_driver;
* ACPI 2.0 chapter 13 access of registers of the EC * ACPI 2.0 chapter 13 access of registers of the EC
*/ */
static unsigned int amd_ec_wait_write(struct amd_smbus *smbus) static int amd_ec_wait_write(struct amd_smbus *smbus)
{ {
int timeout = 500; int timeout = 500;
...@@ -85,7 +85,7 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus) ...@@ -85,7 +85,7 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus)
return 0; return 0;
} }
static unsigned int amd_ec_wait_read(struct amd_smbus *smbus) static int amd_ec_wait_read(struct amd_smbus *smbus)
{ {
int timeout = 500; int timeout = 500;
...@@ -101,7 +101,7 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus) ...@@ -101,7 +101,7 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus)
return 0; return 0;
} }
static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address, static int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
unsigned char *data) unsigned char *data)
{ {
int status; int status;
...@@ -124,7 +124,7 @@ static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address, ...@@ -124,7 +124,7 @@ static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
return 0; return 0;
} }
static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address, static int amd_ec_write(struct amd_smbus *smbus, unsigned char address,
unsigned char data) unsigned char data)
{ {
int status; int status;
...@@ -196,7 +196,7 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, ...@@ -196,7 +196,7 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
{ {
struct amd_smbus *smbus = adap->algo_data; struct amd_smbus *smbus = adap->algo_data;
unsigned char protocol, len, pec, temp[2]; unsigned char protocol, len, pec, temp[2];
int i; int i, status;
protocol = (read_write == I2C_SMBUS_READ) ? AMD_SMB_PRTCL_READ protocol = (read_write == I2C_SMBUS_READ) ? AMD_SMB_PRTCL_READ
: AMD_SMB_PRTCL_WRITE; : AMD_SMB_PRTCL_WRITE;
...@@ -209,38 +209,62 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, ...@@ -209,38 +209,62 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
break; break;
case I2C_SMBUS_BYTE: case I2C_SMBUS_BYTE:
if (read_write == I2C_SMBUS_WRITE) if (read_write == I2C_SMBUS_WRITE) {
amd_ec_write(smbus, AMD_SMB_CMD, command); status = amd_ec_write(smbus, AMD_SMB_CMD,
command);
if (status)
return status;
}
protocol |= AMD_SMB_PRTCL_BYTE; protocol |= AMD_SMB_PRTCL_BYTE;
break; break;
case I2C_SMBUS_BYTE_DATA: case I2C_SMBUS_BYTE_DATA:
amd_ec_write(smbus, AMD_SMB_CMD, command); status = amd_ec_write(smbus, AMD_SMB_CMD, command);
if (read_write == I2C_SMBUS_WRITE) if (status)
amd_ec_write(smbus, AMD_SMB_DATA, data->byte); return status;
if (read_write == I2C_SMBUS_WRITE) {
status = amd_ec_write(smbus, AMD_SMB_DATA,
data->byte);
if (status)
return status;
}
protocol |= AMD_SMB_PRTCL_BYTE_DATA; protocol |= AMD_SMB_PRTCL_BYTE_DATA;
break; break;
case I2C_SMBUS_WORD_DATA: case I2C_SMBUS_WORD_DATA:
amd_ec_write(smbus, AMD_SMB_CMD, command); status = amd_ec_write(smbus, AMD_SMB_CMD, command);
if (status)
return status;
if (read_write == I2C_SMBUS_WRITE) { if (read_write == I2C_SMBUS_WRITE) {
amd_ec_write(smbus, AMD_SMB_DATA, status = amd_ec_write(smbus, AMD_SMB_DATA,
data->word & 0xff); data->word & 0xff);
amd_ec_write(smbus, AMD_SMB_DATA + 1, if (status)
return status;
status = amd_ec_write(smbus, AMD_SMB_DATA + 1,
data->word >> 8); data->word >> 8);
if (status)
return status;
} }
protocol |= AMD_SMB_PRTCL_WORD_DATA | pec; protocol |= AMD_SMB_PRTCL_WORD_DATA | pec;
break; break;
case I2C_SMBUS_BLOCK_DATA: case I2C_SMBUS_BLOCK_DATA:
amd_ec_write(smbus, AMD_SMB_CMD, command); status = amd_ec_write(smbus, AMD_SMB_CMD, command);
if (status)
return status;
if (read_write == I2C_SMBUS_WRITE) { if (read_write == I2C_SMBUS_WRITE) {
len = min_t(u8, data->block[0], len = min_t(u8, data->block[0],
I2C_SMBUS_BLOCK_MAX); I2C_SMBUS_BLOCK_MAX);
amd_ec_write(smbus, AMD_SMB_BCNT, len); status = amd_ec_write(smbus, AMD_SMB_BCNT, len);
for (i = 0; i < len; i++) if (status)
return status;
for (i = 0; i < len; i++) {
status =
amd_ec_write(smbus, AMD_SMB_DATA + i, amd_ec_write(smbus, AMD_SMB_DATA + i,
data->block[i + 1]); data->block[i + 1]);
if (status)
return status;
}
} }
protocol |= AMD_SMB_PRTCL_BLOCK_DATA | pec; protocol |= AMD_SMB_PRTCL_BLOCK_DATA | pec;
break; break;
...@@ -248,19 +272,35 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, ...@@ -248,19 +272,35 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
case I2C_SMBUS_I2C_BLOCK_DATA: case I2C_SMBUS_I2C_BLOCK_DATA:
len = min_t(u8, data->block[0], len = min_t(u8, data->block[0],
I2C_SMBUS_BLOCK_MAX); I2C_SMBUS_BLOCK_MAX);
amd_ec_write(smbus, AMD_SMB_CMD, command); status = amd_ec_write(smbus, AMD_SMB_CMD, command);
amd_ec_write(smbus, AMD_SMB_BCNT, len); if (status)
return status;
status = amd_ec_write(smbus, AMD_SMB_BCNT, len);
if (status)
return status;
if (read_write == I2C_SMBUS_WRITE) if (read_write == I2C_SMBUS_WRITE)
for (i = 0; i < len; i++) for (i = 0; i < len; i++) {
status =
amd_ec_write(smbus, AMD_SMB_DATA + i, amd_ec_write(smbus, AMD_SMB_DATA + i,
data->block[i + 1]); data->block[i + 1]);
if (status)
return status;
}
protocol |= AMD_SMB_PRTCL_I2C_BLOCK_DATA; protocol |= AMD_SMB_PRTCL_I2C_BLOCK_DATA;
break; break;
case I2C_SMBUS_PROC_CALL: case I2C_SMBUS_PROC_CALL:
amd_ec_write(smbus, AMD_SMB_CMD, command); status = amd_ec_write(smbus, AMD_SMB_CMD, command);
amd_ec_write(smbus, AMD_SMB_DATA, data->word & 0xff); if (status)
amd_ec_write(smbus, AMD_SMB_DATA + 1, data->word >> 8); return status;
status = amd_ec_write(smbus, AMD_SMB_DATA,
data->word & 0xff);
if (status)
return status;
status = amd_ec_write(smbus, AMD_SMB_DATA + 1,
data->word >> 8);
if (status)
return status;
protocol = AMD_SMB_PRTCL_PROC_CALL | pec; protocol = AMD_SMB_PRTCL_PROC_CALL | pec;
read_write = I2C_SMBUS_READ; read_write = I2C_SMBUS_READ;
break; break;
...@@ -268,11 +308,18 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, ...@@ -268,11 +308,18 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
case I2C_SMBUS_BLOCK_PROC_CALL: case I2C_SMBUS_BLOCK_PROC_CALL:
len = min_t(u8, data->block[0], len = min_t(u8, data->block[0],
I2C_SMBUS_BLOCK_MAX - 1); I2C_SMBUS_BLOCK_MAX - 1);
amd_ec_write(smbus, AMD_SMB_CMD, command); status = amd_ec_write(smbus, AMD_SMB_CMD, command);
amd_ec_write(smbus, AMD_SMB_BCNT, len); if (status)
for (i = 0; i < len; i++) return status;
amd_ec_write(smbus, AMD_SMB_DATA + i, status = amd_ec_write(smbus, AMD_SMB_BCNT, len);
if (status)
return status;
for (i = 0; i < len; i++) {
status = amd_ec_write(smbus, AMD_SMB_DATA + i,
data->block[i + 1]); data->block[i + 1]);
if (status)
return status;
}
protocol = AMD_SMB_PRTCL_BLOCK_PROC_CALL | pec; protocol = AMD_SMB_PRTCL_BLOCK_PROC_CALL | pec;
read_write = I2C_SMBUS_READ; read_write = I2C_SMBUS_READ;
break; break;
...@@ -282,24 +329,29 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, ...@@ -282,24 +329,29 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
amd_ec_write(smbus, AMD_SMB_ADDR, addr << 1); status = amd_ec_write(smbus, AMD_SMB_ADDR, addr << 1);
amd_ec_write(smbus, AMD_SMB_PRTCL, protocol); if (status)
return status;
status = amd_ec_write(smbus, AMD_SMB_PRTCL, protocol);
if (status)
return status;
/* FIXME this discards status from ec_read(); so temp[0] will status = amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
* hold stack garbage ... the rest of this routine will act if (status)
* nonsensically. Ignored ec_write() status might explain return status;
* some such failures...
*/
amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
if (~temp[0] & AMD_SMB_STS_DONE) { if (~temp[0] & AMD_SMB_STS_DONE) {
udelay(500); udelay(500);
amd_ec_read(smbus, AMD_SMB_STS, temp + 0); status = amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
if (status)
return status;
} }
if (~temp[0] & AMD_SMB_STS_DONE) { if (~temp[0] & AMD_SMB_STS_DONE) {
msleep(1); msleep(1);
amd_ec_read(smbus, AMD_SMB_STS, temp + 0); status = amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
if (status)
return status;
} }
if ((~temp[0] & AMD_SMB_STS_DONE) || (temp[0] & AMD_SMB_STS_STATUS)) if ((~temp[0] & AMD_SMB_STS_DONE) || (temp[0] & AMD_SMB_STS_STATUS))
...@@ -311,24 +363,35 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, ...@@ -311,24 +363,35 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
switch (size) { switch (size) {
case I2C_SMBUS_BYTE: case I2C_SMBUS_BYTE:
case I2C_SMBUS_BYTE_DATA: case I2C_SMBUS_BYTE_DATA:
amd_ec_read(smbus, AMD_SMB_DATA, &data->byte); status = amd_ec_read(smbus, AMD_SMB_DATA, &data->byte);
if (status)
return status;
break; break;
case I2C_SMBUS_WORD_DATA: case I2C_SMBUS_WORD_DATA:
case I2C_SMBUS_PROC_CALL: case I2C_SMBUS_PROC_CALL:
amd_ec_read(smbus, AMD_SMB_DATA, temp + 0); status = amd_ec_read(smbus, AMD_SMB_DATA, temp + 0);
amd_ec_read(smbus, AMD_SMB_DATA + 1, temp + 1); if (status)
return status;
status = amd_ec_read(smbus, AMD_SMB_DATA + 1, temp + 1);
if (status)
return status;
data->word = (temp[1] << 8) | temp[0]; data->word = (temp[1] << 8) | temp[0];
break; break;
case I2C_SMBUS_BLOCK_DATA: case I2C_SMBUS_BLOCK_DATA:
case I2C_SMBUS_BLOCK_PROC_CALL: case I2C_SMBUS_BLOCK_PROC_CALL:
amd_ec_read(smbus, AMD_SMB_BCNT, &len); status = amd_ec_read(smbus, AMD_SMB_BCNT, &len);
if (status)
return status;
len = min_t(u8, len, I2C_SMBUS_BLOCK_MAX); len = min_t(u8, len, I2C_SMBUS_BLOCK_MAX);
case I2C_SMBUS_I2C_BLOCK_DATA: case I2C_SMBUS_I2C_BLOCK_DATA:
for (i = 0; i < len; i++) for (i = 0; i < len; i++) {
amd_ec_read(smbus, AMD_SMB_DATA + i, status = amd_ec_read(smbus, AMD_SMB_DATA + i,
data->block + i + 1); data->block + i + 1);
if (status)
return status;
}
data->block[0] = len; data->block[0] = len;
break; break;
} }
......
...@@ -41,7 +41,6 @@ ...@@ -41,7 +41,6 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/of_i2c.h> #include <linux/of_i2c.h>
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
......
...@@ -224,7 +224,7 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev) ...@@ -224,7 +224,7 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev)
if (irq) { if (irq) {
ret = request_irq(irq, i2c_pca_pf_handler, ret = request_irq(irq, i2c_pca_pf_handler,
IRQF_TRIGGER_FALLING, i2c->adap.name, i2c); IRQF_TRIGGER_FALLING, pdev->name, i2c);
if (ret) if (ret)
goto e_reqirq; goto e_reqirq;
} }
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/sched.h> #include <linux/sched.h>
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
......
...@@ -185,14 +185,8 @@ static int vt596_transaction(u8 size) ...@@ -185,14 +185,8 @@ static int vt596_transaction(u8 size)
} }
if (temp & 0x04) { if (temp & 0x04) {
int read = inb_p(SMBHSTADD) & 0x01;
result = -ENXIO; result = -ENXIO;
/* The quick and receive byte commands are used to probe dev_dbg(&vt596_adapter.dev, "No response\n");
for chips, so errors are expected, and we don't want
to frighten the user. */
if (!((size == VT596_QUICK && !read) ||
(size == VT596_BYTE && read)))
dev_err(&vt596_adapter.dev, "Transaction error!\n");
} }
/* Resetting status register */ /* Resetting status register */
......
...@@ -425,14 +425,14 @@ static int __i2c_check_addr_busy(struct device *dev, void *addrp) ...@@ -425,14 +425,14 @@ static int __i2c_check_addr_busy(struct device *dev, void *addrp)
/* walk up mux tree */ /* walk up mux tree */
static int i2c_check_mux_parents(struct i2c_adapter *adapter, int addr) static int i2c_check_mux_parents(struct i2c_adapter *adapter, int addr)
{ {
struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
int result; int result;
result = device_for_each_child(&adapter->dev, &addr, result = device_for_each_child(&adapter->dev, &addr,
__i2c_check_addr_busy); __i2c_check_addr_busy);
if (!result && i2c_parent_is_i2c_adapter(adapter)) if (!result && parent)
result = i2c_check_mux_parents( result = i2c_check_mux_parents(parent, addr);
to_i2c_adapter(adapter->dev.parent), addr);
return result; return result;
} }
...@@ -453,11 +453,11 @@ static int i2c_check_mux_children(struct device *dev, void *addrp) ...@@ -453,11 +453,11 @@ static int i2c_check_mux_children(struct device *dev, void *addrp)
static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr) static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr)
{ {
struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
int result = 0; int result = 0;
if (i2c_parent_is_i2c_adapter(adapter)) if (parent)
result = i2c_check_mux_parents( result = i2c_check_mux_parents(parent, addr);
to_i2c_adapter(adapter->dev.parent), addr);
if (!result) if (!result)
result = device_for_each_child(&adapter->dev, &addr, result = device_for_each_child(&adapter->dev, &addr,
...@@ -472,8 +472,10 @@ static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr) ...@@ -472,8 +472,10 @@ static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr)
*/ */
void i2c_lock_adapter(struct i2c_adapter *adapter) void i2c_lock_adapter(struct i2c_adapter *adapter)
{ {
if (i2c_parent_is_i2c_adapter(adapter)) struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
i2c_lock_adapter(to_i2c_adapter(adapter->dev.parent));
if (parent)
i2c_lock_adapter(parent);
else else
rt_mutex_lock(&adapter->bus_lock); rt_mutex_lock(&adapter->bus_lock);
} }
...@@ -485,8 +487,10 @@ EXPORT_SYMBOL_GPL(i2c_lock_adapter); ...@@ -485,8 +487,10 @@ EXPORT_SYMBOL_GPL(i2c_lock_adapter);
*/ */
static int i2c_trylock_adapter(struct i2c_adapter *adapter) static int i2c_trylock_adapter(struct i2c_adapter *adapter)
{ {
if (i2c_parent_is_i2c_adapter(adapter)) struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
return i2c_trylock_adapter(to_i2c_adapter(adapter->dev.parent));
if (parent)
return i2c_trylock_adapter(parent);
else else
return rt_mutex_trylock(&adapter->bus_lock); return rt_mutex_trylock(&adapter->bus_lock);
} }
...@@ -497,8 +501,10 @@ static int i2c_trylock_adapter(struct i2c_adapter *adapter) ...@@ -497,8 +501,10 @@ static int i2c_trylock_adapter(struct i2c_adapter *adapter)
*/ */
void i2c_unlock_adapter(struct i2c_adapter *adapter) void i2c_unlock_adapter(struct i2c_adapter *adapter)
{ {
if (i2c_parent_is_i2c_adapter(adapter)) struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
i2c_unlock_adapter(to_i2c_adapter(adapter->dev.parent));
if (parent)
i2c_unlock_adapter(parent);
else else
rt_mutex_unlock(&adapter->bus_lock); rt_mutex_unlock(&adapter->bus_lock);
} }
...@@ -677,8 +683,6 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr, ...@@ -677,8 +683,6 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
char *blank, end; char *blank, end;
int res; int res;
dev_warn(dev, "The new_device interface is still experimental "
"and may change in a near future\n");
memset(&info, 0, sizeof(struct i2c_board_info)); memset(&info, 0, sizeof(struct i2c_board_info));
blank = strchr(buf, ' '); blank = strchr(buf, ' ');
...@@ -1504,26 +1508,25 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver) ...@@ -1504,26 +1508,25 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
if (!driver->detect || !address_list) if (!driver->detect || !address_list)
return 0; return 0;
/* Stop here if the classes do not match */
if (!(adapter->class & driver->class))
return 0;
/* Set up a temporary client to help detect callback */ /* Set up a temporary client to help detect callback */
temp_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); temp_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (!temp_client) if (!temp_client)
return -ENOMEM; return -ENOMEM;
temp_client->adapter = adapter; temp_client->adapter = adapter;
/* Stop here if the classes do not match */
if (!(adapter->class & driver->class))
goto exit_free;
for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) { for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
dev_dbg(&adapter->dev, "found normal entry for adapter %d, " dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
"addr 0x%02x\n", adap_id, address_list[i]); "addr 0x%02x\n", adap_id, address_list[i]);
temp_client->addr = address_list[i]; temp_client->addr = address_list[i];
err = i2c_detect_address(temp_client, driver); err = i2c_detect_address(temp_client, driver);
if (err) if (unlikely(err))
goto exit_free; break;
} }
exit_free:
kfree(temp_client); kfree(temp_client);
return err; return err;
} }
......
...@@ -192,13 +192,12 @@ static int i2cdev_check(struct device *dev, void *addrp) ...@@ -192,13 +192,12 @@ static int i2cdev_check(struct device *dev, void *addrp)
/* walk up mux tree */ /* walk up mux tree */
static int i2cdev_check_mux_parents(struct i2c_adapter *adapter, int addr) static int i2cdev_check_mux_parents(struct i2c_adapter *adapter, int addr)
{ {
struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
int result; int result;
result = device_for_each_child(&adapter->dev, &addr, i2cdev_check); result = device_for_each_child(&adapter->dev, &addr, i2cdev_check);
if (!result && parent)
if (!result && i2c_parent_is_i2c_adapter(adapter)) result = i2cdev_check_mux_parents(parent, addr);
result = i2cdev_check_mux_parents(
to_i2c_adapter(adapter->dev.parent), addr);
return result; return result;
} }
...@@ -222,11 +221,11 @@ static int i2cdev_check_mux_children(struct device *dev, void *addrp) ...@@ -222,11 +221,11 @@ static int i2cdev_check_mux_children(struct device *dev, void *addrp)
driver bound to it, as NOT busy. */ driver bound to it, as NOT busy. */
static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr) static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
{ {
struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
int result = 0; int result = 0;
if (i2c_parent_is_i2c_adapter(adapter)) if (parent)
result = i2cdev_check_mux_parents( result = i2cdev_check_mux_parents(parent, addr);
to_i2c_adapter(adapter->dev.parent), addr);
if (!result) if (!result)
result = device_for_each_child(&adapter->dev, &addr, result = device_for_each_child(&adapter->dev, &addr,
......
...@@ -5,6 +5,16 @@ ...@@ -5,6 +5,16 @@
menu "Multiplexer I2C Chip support" menu "Multiplexer I2C Chip support"
depends on I2C_MUX depends on I2C_MUX
config I2C_MUX_PCA9541
tristate "NXP PCA9541 I2C Master Selector"
depends on EXPERIMENTAL
help
If you say yes here you get support for the NXP PCA9541
I2C Master Selector.
This driver can also be built as a module. If so, the module
will be called pca9541.
config I2C_MUX_PCA954x config I2C_MUX_PCA954x
tristate "Philips PCA954x I2C Mux/switches" tristate "Philips PCA954x I2C Mux/switches"
depends on EXPERIMENTAL depends on EXPERIMENTAL
......
# #
# Makefile for multiplexer I2C chip drivers. # Makefile for multiplexer I2C chip drivers.
obj-$(CONFIG_I2C_MUX_PCA9541) += pca9541.o
obj-$(CONFIG_I2C_MUX_PCA954x) += pca954x.o obj-$(CONFIG_I2C_MUX_PCA954x) += pca954x.o
ifeq ($(CONFIG_I2C_DEBUG_BUS),y) ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG
EXTRA_CFLAGS += -DDEBUG
endif
This diff is collapsed.
...@@ -181,7 +181,7 @@ static int pca954x_deselect_mux(struct i2c_adapter *adap, ...@@ -181,7 +181,7 @@ static int pca954x_deselect_mux(struct i2c_adapter *adap,
/* /*
* I2C init/probing/exit functions * I2C init/probing/exit functions
*/ */
static int __devinit pca954x_probe(struct i2c_client *client, static int pca954x_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
...@@ -255,7 +255,7 @@ static int __devinit pca954x_probe(struct i2c_client *client, ...@@ -255,7 +255,7 @@ static int __devinit pca954x_probe(struct i2c_client *client,
return ret; return ret;
} }
static int __devexit pca954x_remove(struct i2c_client *client) static int pca954x_remove(struct i2c_client *client)
{ {
struct pca954x *data = i2c_get_clientdata(client); struct pca954x *data = i2c_get_clientdata(client);
const struct chip_desc *chip = &chips[data->type]; const struct chip_desc *chip = &chips[data->type];
...@@ -279,7 +279,7 @@ static struct i2c_driver pca954x_driver = { ...@@ -279,7 +279,7 @@ static struct i2c_driver pca954x_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = pca954x_probe, .probe = pca954x_probe,
.remove = __devexit_p(pca954x_remove), .remove = pca954x_remove,
.id_table = pca954x_id, .id_table = pca954x_id,
}; };
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h> #include <linux/i2c-algo-bit.h>
#include <asm/io.h> #include <asm/io.h>
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include <linux/agp_backend.h> #include <linux/agp_backend.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h> #include <linux/i2c-algo-bit.h>
#include <video/vga.h> #include <video/vga.h>
......
...@@ -32,7 +32,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. ...@@ -32,7 +32,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h> #include <linux/i2c-algo-bit.h>
#include <asm/io.h> #include <asm/io.h>
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#define __SAVAGEFB_H__ #define __SAVAGEFB_H__
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/i2c-algo-bit.h> #include <linux/i2c-algo-bit.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <video/vga.h> #include <video/vga.h>
......
...@@ -384,11 +384,15 @@ static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data) ...@@ -384,11 +384,15 @@ static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data)
dev_set_drvdata(&dev->dev, data); dev_set_drvdata(&dev->dev, data);
} }
static inline int i2c_parent_is_i2c_adapter(const struct i2c_adapter *adapter) static inline struct i2c_adapter *
i2c_parent_is_i2c_adapter(const struct i2c_adapter *adapter)
{ {
return adapter->dev.parent != NULL struct device *parent = adapter->dev.parent;
&& adapter->dev.parent->bus == &i2c_bus_type
&& adapter->dev.parent->type == &i2c_adapter_type; if (parent != NULL && parent->type == &i2c_adapter_type)
return to_i2c_adapter(parent);
else
return NULL;
} }
/* Adapter locking functions, exported for shared pin cases */ /* Adapter locking functions, exported for shared pin cases */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment