From eee543e8248150e8fb833943c71f40c7b1724600 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 5 Oct 2012 22:23:51 +0200 Subject: i2c-mux: Add support for device auto-detection Let I2C bus segments behind multiplexers have a class. This allows for device auto-detection on these segments. As long as parent segments don't share the same class, it should be fine. I implemented support in drivers i2c-mux-gpio and i2c-mux-pca954x. I left i2c-mux-pca9541 and i2c-mux-pinctrl alone for the moment as I don't know if this feature makes sense for the use cases of these drivers. Signed-off-by: Jean Delvare Cc: Peter Korsgaard Cc: David Daney Cc: Michael Lawnick Cc: Rodolfo Giometti --- drivers/i2c/i2c-mux.c | 22 ++++++++++++++++++++++ drivers/i2c/muxes/i2c-mux-gpio.c | 4 +++- drivers/i2c/muxes/i2c-mux-pca9541.c | 2 +- drivers/i2c/muxes/i2c-mux-pca954x.c | 10 ++++++---- drivers/i2c/muxes/i2c-mux-pinctrl.c | 2 +- 5 files changed, 33 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c index 1038c381aea5..d94e0ce78277 100644 --- a/drivers/i2c/i2c-mux.c +++ b/drivers/i2c/i2c-mux.c @@ -88,9 +88,23 @@ static u32 i2c_mux_functionality(struct i2c_adapter *adap) return parent->algo->functionality(parent); } +/* Return all parent classes, merged */ +static unsigned int i2c_mux_parent_classes(struct i2c_adapter *parent) +{ + unsigned int class = 0; + + do { + class |= parent->class; + parent = i2c_parent_is_i2c_adapter(parent); + } while (parent); + + return class; +} + struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent, struct device *mux_dev, void *mux_priv, u32 force_nr, u32 chan_id, + unsigned int class, int (*select) (struct i2c_adapter *, void *, u32), int (*deselect) (struct i2c_adapter *, @@ -127,6 +141,14 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent, priv->adap.algo_data = priv; priv->adap.dev.parent = &parent->dev; + /* Sanity check on class */ + if (i2c_mux_parent_classes(parent) & class) + dev_err(&parent->dev, + "Segment %d behind mux can't share classes with ancestors\n", + chan_id); + else + priv->adap.class = class; + /* * Try to populate the mux adapter's of_node, expands to * nothing if !CONFIG_OF. diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c index 68b1f8ec3436..56889e00c76e 100644 --- a/drivers/i2c/muxes/i2c-mux-gpio.c +++ b/drivers/i2c/muxes/i2c-mux-gpio.c @@ -104,8 +104,10 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev) for (i = 0; i < pdata->n_values; i++) { u32 nr = pdata->base_nr ? (pdata->base_nr + i) : 0; + unsigned int class = pdata->classes ? pdata->classes[i] : 0; - mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr, i, + mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr, + i, class, i2c_mux_gpio_select, deselect); if (!mux->adap[i]) { ret = -ENODEV; diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c index f8f72f39e0b5..f3b8f9a6a89b 100644 --- a/drivers/i2c/muxes/i2c-mux-pca9541.c +++ b/drivers/i2c/muxes/i2c-mux-pca9541.c @@ -354,7 +354,7 @@ static int pca9541_probe(struct i2c_client *client, if (pdata) force = pdata->modes[0].adap_id; data->mux_adap = i2c_add_mux_adapter(adap, &client->dev, client, - force, 0, + force, 0, 0, pca9541_select_chan, pca9541_release_chan); diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c index f2dfe0d8fcce..8e4387235b69 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c @@ -186,7 +186,7 @@ static int pca954x_probe(struct i2c_client *client, { struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent); struct pca954x_platform_data *pdata = client->dev.platform_data; - int num, force; + int num, force, class; struct pca954x *data; int ret = -ENODEV; @@ -216,18 +216,20 @@ static int pca954x_probe(struct i2c_client *client, /* Now create an adapter for each channel */ for (num = 0; num < chips[data->type].nchans; num++) { force = 0; /* dynamic adap number */ + class = 0; /* no class by default */ if (pdata) { - if (num < pdata->num_modes) + if (num < pdata->num_modes) { /* force static number */ force = pdata->modes[num].adap_id; - else + class = pdata->modes[num].class; + } else /* discard unconfigured channels */ break; } data->virt_adaps[num] = i2c_add_mux_adapter(adap, &client->dev, client, - force, num, pca954x_select_chan, + force, num, class, pca954x_select_chan, (pdata && pdata->modes[num].deselect_on_exit) ? pca954x_deselect_mux : NULL); diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c index 46a669763476..5f097f309b9f 100644 --- a/drivers/i2c/muxes/i2c-mux-pinctrl.c +++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c @@ -221,7 +221,7 @@ static int __devinit i2c_mux_pinctrl_probe(struct platform_device *pdev) (mux->pdata->base_bus_num + i) : 0; mux->busses[i] = i2c_add_mux_adapter(mux->parent, &pdev->dev, - mux, bus, i, + mux, bus, i, 0, i2c_mux_pinctrl_select, deselect); if (!mux->busses[i]) { -- cgit v1.2.3-58-ga151 From 71b578452ec6b2e8a470e3dae89055cd1068a9f0 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 5 Oct 2012 22:23:52 +0200 Subject: i2c-smbus: Convert kzalloc to devm_kzalloc Converting kzalloc to devm_kzalloc simplifies the code and ensures that the result, alert, is freed after the irq allocated by the subsequent devm_request_irq. This in turn ensures that when an interrupt can be triggered, the alert structure is still available. The problem of a free after a devm_request_irq was found using the following semantic match (http://coccinelle.lip6.fr/) // @r exists@ expression e1,e2,x,a,b,c,d; identifier free; position p1,p2; @@ devm_request_irq@p1(e1,e2,...,x) ... when any when != e2 = a when != x = b if (...) { ... when != e2 = c when != x = d free@p2(...,x,...); ... return ...; } // Signed-off-by: Julia Lawall Signed-off-by: Jean Delvare --- drivers/i2c/i2c-smbus.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c index df3e0bf31eb3..92cdd2323b03 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c @@ -142,7 +142,8 @@ static int smbalert_probe(struct i2c_client *ara, struct i2c_adapter *adapter = ara->adapter; int res; - alert = kzalloc(sizeof(struct i2c_smbus_alert), GFP_KERNEL); + alert = devm_kzalloc(&ara->dev, sizeof(struct i2c_smbus_alert), + GFP_KERNEL); if (!alert) return -ENOMEM; @@ -154,10 +155,8 @@ static int smbalert_probe(struct i2c_client *ara, if (setup->irq > 0) { res = devm_request_irq(&ara->dev, setup->irq, smbalert_irq, 0, "smbus_alert", alert); - if (res) { - kfree(alert); + if (res) return res; - } } i2c_set_clientdata(ara, alert); @@ -167,14 +166,12 @@ static int smbalert_probe(struct i2c_client *ara, return 0; } -/* IRQ resource is managed so it is freed automatically */ +/* IRQ and memory resources are managed so they are freed automatically */ static int smbalert_remove(struct i2c_client *ara) { struct i2c_smbus_alert *alert = i2c_get_clientdata(ara); cancel_work_sync(&alert->alert); - - kfree(alert); return 0; } -- cgit v1.2.3-58-ga151 From 230da094352869ac36bca524a294deb7bb3dd876 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Fri, 5 Oct 2012 22:23:52 +0200 Subject: i2c: Convert struct i2c_msg initialization to C99 format Convert the struct i2c_msg initialization to C99 format. This makes maintaining and editing the code simpler. Also helps once other fields like transferred are added in future. Signed-off-by: Shubhrajyoti D Signed-off-by: Jean Delvare --- drivers/i2c/i2c-core.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 2421d95130d4..a7edf987a339 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1989,12 +1989,22 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr, unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3]; unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2]; int num = read_write == I2C_SMBUS_READ ? 2 : 1; - struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 }, - { addr, flags | I2C_M_RD, 0, msgbuf1 } - }; int i; u8 partial_pec = 0; int status; + struct i2c_msg msg[2] = { + { + .addr = addr, + .flags = flags, + .len = 1, + .buf = msgbuf0, + }, { + .addr = addr, + .flags = flags | I2C_M_RD, + .len = 0, + .buf = msgbuf1, + }, + }; msgbuf0[0] = command; switch (size) { -- cgit v1.2.3-58-ga151 From 3ddb59d4bcaeca8109ac5eb8ad17368e940ac05e Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Fri, 5 Oct 2012 22:23:52 +0200 Subject: i2c: Make I2C available on UML Remove the global dependency of the I2C subsystem on HAS_IOMEM and move the dependency to the i2c/busses submenu, with an exception for i2c-stub. The generic I2C part does not need to have HAS_IOMEM set and thus now becomes available in UML, so the I2C subsystem can now be used, e.g. by the i2c-stub driver, for development of I2C device drivers. [JD: Some adjustments.] [Heiko Carstens: Keep I2C disabled on S390.] Signed-off-by: Peter Huewe Signed-off-by: Jean Delvare --- drivers/i2c/Kconfig | 17 ++++++++++++++++- drivers/i2c/busses/Kconfig | 14 +------------- 2 files changed, 17 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 5a3bb3d738d8..2f8c76becc6b 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -4,7 +4,7 @@ menuconfig I2C tristate "I2C support" - depends on HAS_IOMEM + depends on !S390 select RT_MUTEXES ---help--- I2C (pronounce: I-squared-C) is a slow serial bus protocol used in @@ -49,6 +49,7 @@ config I2C_CHARDEV config I2C_MUX tristate "I2C bus multiplexing support" + depends on HAS_IOMEM help Say Y here if you want the I2C core to support the ability to handle multiplexed I2C bus topologies, by presenting each @@ -86,6 +87,19 @@ config I2C_SMBUS source drivers/i2c/algos/Kconfig source drivers/i2c/busses/Kconfig +config I2C_STUB + tristate "I2C/SMBus Test Stub" + depends on EXPERIMENTAL && m + default 'n' + help + This module may be useful to developers of SMBus client drivers, + especially for certain kinds of sensor chips. + + If you do build this module, be sure to read the notes and warnings + in . + + If you don't know what to do here, definitely say N. + config I2C_DEBUG_CORE bool "I2C Core debugging messages" help @@ -103,6 +117,7 @@ config I2C_DEBUG_ALGO config I2C_DEBUG_BUS bool "I2C Bus debugging messages" + depends on HAS_IOMEM help Say Y here if you want the I2C bus drivers to produce a bunch of debug messages to the system log. Select this if you are having diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 42d9fdd63de0..8eed054e3293 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -3,6 +3,7 @@ # menu "I2C Hardware Bus support" + depends on HAS_IOMEM comment "PC SMBus host controller drivers" depends on PCI @@ -849,19 +850,6 @@ config I2C_SIBYTE help Supports the SiByte SOC on-chip I2C interfaces (2 channels). -config I2C_STUB - tristate "I2C/SMBus Test Stub" - depends on EXPERIMENTAL && m - default 'n' - help - This module may be useful to developers of SMBus client drivers, - especially for certain kinds of sensor chips. - - If you do build this module, be sure to read the notes and warnings - in . - - If you don't know what to do here, definitely say N. - config SCx200_I2C tristate "NatSemi SCx200 I2C using GPIO pins (DEPRECATED)" depends on SCx200_GPIO -- cgit v1.2.3-58-ga151 From 401e72b55d29f1a08d3dfd7a6a6c2087203b6524 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 5 Oct 2012 22:23:52 +0200 Subject: i2c/scx200_*: Replace printks with pr_s Replace printks with pr_s, add pr_fmt()s to replace NAMEs Signed-off-by: Jim Cromie Reviewed-by: Joe Perches Signed-off-by: Jean Delvare --- drivers/i2c/busses/scx200_acb.c | 24 +++++++++++------------- drivers/i2c/busses/scx200_i2c.c | 15 +++++++-------- 2 files changed, 18 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 2eacb7784d56..08aab57337dd 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -23,6 +23,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -37,8 +39,6 @@ #include -#define NAME "scx200_acb" - MODULE_AUTHOR("Christer Weinigel "); MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver"); MODULE_ALIAS("platform:cs5535-smb"); @@ -398,7 +398,7 @@ static __devinit int scx200_acb_probe(struct scx200_acb_iface *iface) outb(0x70, ACBCTL2); if (inb(ACBCTL2) != 0x70) { - pr_debug(NAME ": ACBCTL2 readback failed\n"); + pr_debug("ACBCTL2 readback failed\n"); return -ENXIO; } @@ -406,8 +406,7 @@ static __devinit int scx200_acb_probe(struct scx200_acb_iface *iface) val = inb(ACBCTL1); if (val) { - pr_debug(NAME ": disabled, but ACBCTL1=0x%02x\n", - val); + pr_debug("disabled, but ACBCTL1=0x%02x\n", val); return -ENXIO; } @@ -417,8 +416,8 @@ static __devinit int scx200_acb_probe(struct scx200_acb_iface *iface) val = inb(ACBCTL1); if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) { - pr_debug(NAME ": enabled, but NMINTE won't be set, " - "ACBCTL1=0x%02x\n", val); + pr_debug("enabled, but NMINTE won't be set, ACBCTL1=0x%02x\n", + val); return -ENXIO; } @@ -433,7 +432,7 @@ static __devinit struct scx200_acb_iface *scx200_create_iface(const char *text, iface = kzalloc(sizeof(*iface), GFP_KERNEL); if (!iface) { - printk(KERN_ERR NAME ": can't allocate memory\n"); + pr_err("can't allocate memory\n"); return NULL; } @@ -459,14 +458,14 @@ static int __devinit scx200_acb_create(struct scx200_acb_iface *iface) rc = scx200_acb_probe(iface); if (rc) { - printk(KERN_WARNING NAME ": probe failed\n"); + pr_warn("probe failed\n"); return rc; } scx200_acb_reset(iface); if (i2c_add_adapter(adapter) < 0) { - printk(KERN_ERR NAME ": failed to register\n"); + pr_err("failed to register\n"); return -ENODEV; } @@ -493,8 +492,7 @@ static struct scx200_acb_iface * __devinit scx200_create_dev(const char *text, return NULL; if (!request_region(base, 8, iface->adapter.name)) { - printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n", - base, base + 8 - 1); + pr_err("can't allocate io 0x%lx-0x%lx\n", base, base + 8 - 1); goto errout_free; } @@ -583,7 +581,7 @@ static __init void scx200_scan_isa(void) static int __init scx200_acb_init(void) { - pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n"); + pr_debug("NatSemi SCx200 ACCESS.bus Driver\n"); /* First scan for ISA-based devices */ scx200_scan_isa(); /* XXX: should we care about errors? */ diff --git a/drivers/i2c/busses/scx200_i2c.c b/drivers/i2c/busses/scx200_i2c.c index 7ee0d502ceab..ae1258b95d60 100644 --- a/drivers/i2c/busses/scx200_i2c.c +++ b/drivers/i2c/busses/scx200_i2c.c @@ -21,6 +21,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -31,8 +33,6 @@ #include -#define NAME "scx200_i2c" - MODULE_AUTHOR("Christer Weinigel "); MODULE_DESCRIPTION("NatSemi SCx200 I2C Driver"); MODULE_LICENSE("GPL"); @@ -88,17 +88,17 @@ static struct i2c_adapter scx200_i2c_ops = { static int scx200_i2c_init(void) { - pr_debug(NAME ": NatSemi SCx200 I2C Driver\n"); + pr_debug("NatSemi SCx200 I2C Driver\n"); if (!scx200_gpio_present()) { - printk(KERN_ERR NAME ": no SCx200 gpio pins available\n"); + pr_err("no SCx200 gpio pins available\n"); return -ENODEV; } - pr_debug(NAME ": SCL=GPIO%02u, SDA=GPIO%02u\n", scl, sda); + pr_debug("SCL=GPIO%02u, SDA=GPIO%02u\n", scl, sda); if (scl == -1 || sda == -1 || scl == sda) { - printk(KERN_ERR NAME ": scl and sda must be specified\n"); + pr_err("scl and sda must be specified\n"); return -EINVAL; } @@ -107,8 +107,7 @@ static int scx200_i2c_init(void) scx200_gpio_configure(sda, ~2, 5); if (i2c_bit_add_bus(&scx200_i2c_ops) < 0) { - printk(KERN_ERR NAME ": adapter %s registration failed\n", - scx200_i2c_ops.name); + pr_err("adapter %s registration failed\n", scx200_i2c_ops.name); return -ENODEV; } -- cgit v1.2.3-58-ga151 From bccd780f867c82571181f6ca03e243beba697607 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 5 Oct 2012 22:23:53 +0200 Subject: i2c-designware: i2c_dw_xfer_msg can be static i2c_dw_xfer_msg is only called internally so it can be static. It original was, before the driver split. No idea why it was changed at that time. Signed-off-by: Jean Delvare Acked-by: Dirk Brandewie --- drivers/i2c/busses/i2c-designware-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 7b8ebbefb581..cbba7db9ad59 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -370,7 +370,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) * messages into the tx buffer. Even if the size of i2c_msg data is * longer than the size of the tx buffer, it handles everything. */ -void +static void i2c_dw_xfer_msg(struct dw_i2c_dev *dev) { struct i2c_msg *msgs = dev->msgs; -- cgit v1.2.3-58-ga151 From 7fe442a1a50f8b4fe49f685f21b08dd8f070f429 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 5 Oct 2012 22:23:53 +0200 Subject: i2c-parport: i2c_parport_irq can be static i2c_parport_irq is only called internally so it can be static. Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-parport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 24565687ac9b..81d887869620 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c @@ -151,7 +151,7 @@ static const struct i2c_algo_bit_data parport_algo_data = { /* ----- I2c and parallel port call-back functions and structures --------- */ -void i2c_parport_irq(void *data) +static void i2c_parport_irq(void *data) { struct i2c_par *adapter = data; struct i2c_client *ara = adapter->ara; -- cgit v1.2.3-58-ga151 From 01d56a6aa1c3a506426c8f3ff87c8d698023f336 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 5 Oct 2012 22:23:53 +0200 Subject: i2c-viapro: Add VIA VX900 device ID The SMBus controller in the VIA VX900 appears to be compatible with the VIA VX855, so just add the device ID. This closes kernel bug #43096. Signed-off-by: Jean Delvare --- Documentation/i2c/busses/i2c-viapro | 6 +++++- drivers/i2c/busses/Kconfig | 3 ++- drivers/i2c/busses/i2c-viapro.c | 3 +++ include/linux/pci_ids.h | 1 + 4 files changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/Documentation/i2c/busses/i2c-viapro b/Documentation/i2c/busses/i2c-viapro index 2e758b0e9456..b88f91ae580e 100644 --- a/Documentation/i2c/busses/i2c-viapro +++ b/Documentation/i2c/busses/i2c-viapro @@ -20,7 +20,10 @@ Supported adapters: Datasheet: available on http://linux.via.com.tw * VIA Technologies, Inc. VX855/VX875 - Datasheet: Availability unknown + Datasheet: available on http://linux.via.com.tw + + * VIA Technologies, Inc. VX900 + Datasheet: available on http://linux.via.com.tw Authors: Kyösti Mälkki , @@ -57,6 +60,7 @@ Your lspci -n listing must show one of these : device 1106:8324 (CX700) device 1106:8353 (VX800/VX820) device 1106:8409 (VX855/VX875) + device 1106:8410 (VX900) If none of these show up, you should look in the BIOS for settings like enable ACPI / SMBus or even USB. diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 8eed054e3293..7f69f500daf2 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -225,7 +225,7 @@ config I2C_VIA will be called i2c-via. config I2C_VIAPRO - tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx" + tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx/VX900" depends on PCI help If you say yes to this option, support will be included for the VIA @@ -241,6 +241,7 @@ config I2C_VIAPRO CX700 VX800/VX820 VX855/VX875 + VX900 This driver can also be built as a module. If so, the module will be called i2c-viapro. diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 333011c83d52..271c9a2b0fd7 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -401,6 +401,7 @@ found: case PCI_DEVICE_ID_VIA_CX700: case PCI_DEVICE_ID_VIA_VX800: case PCI_DEVICE_ID_VIA_VX855: + case PCI_DEVICE_ID_VIA_VX900: case PCI_DEVICE_ID_VIA_8251: case PCI_DEVICE_ID_VIA_8237: case PCI_DEVICE_ID_VIA_8237A: @@ -470,6 +471,8 @@ static DEFINE_PCI_DEVICE_TABLE(vt596_ids) = { .driver_data = SMBBA3 }, { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855), .driver_data = SMBBA3 }, + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX900), + .driver_data = SMBBA3 }, { 0, } }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 33880f6f4e51..9d36b829533a 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1427,6 +1427,7 @@ #define PCI_DEVICE_ID_VIA_CX700_IDE 0x0581 #define PCI_DEVICE_ID_VIA_VX800 0x8353 #define PCI_DEVICE_ID_VIA_VX855 0x8409 +#define PCI_DEVICE_ID_VIA_VX900 0x8410 #define PCI_DEVICE_ID_VIA_8371_1 0x8391 #define PCI_DEVICE_ID_VIA_82C598_1 0x8598 #define PCI_DEVICE_ID_VIA_838X_1 0xB188 -- cgit v1.2.3-58-ga151 From 3ad7ea18ae8c7ddda46b7276e0bda73e707ea9c1 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 5 Oct 2012 22:23:53 +0200 Subject: i2c-i801: Support SMBus multiplexing on Asus Z8 series Add support for SMBus multiplexing on Asus Z8 motherboard series. On these boards, the memory slots are behind a GPIO-controlled I2C multiplexer. Models with 6 or 12 memory slots have 2 segments behind the multiplexer, while models with 18 memory slots have 3 such segments. On these boards, only the memory slots are behind the multiplexer, so it is possible to keep the autodetection mechanism. The code is generic enough so it could work on other boards as long as the multiplexer is controlled by GPIO pins. For other forms of multiplexing (for example using an I2C device) additional code will be needed. Thanks to Asus for providing a board to develop and test this feature, as well as all the technical information required. At the moment, the GPIO driver must be loaded before the i2c-i801 driver, but I hope to solve this soon, using deferred probing on the i2c-mux-gpio side. Signed-off-by: Jean Delvare --- drivers/i2c/busses/Kconfig | 1 + drivers/i2c/busses/i2c-i801.c | 214 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 214 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 7f69f500daf2..ff01c389e2da 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -81,6 +81,7 @@ config I2C_I801 tristate "Intel 82801 (ICH/PCH)" depends on PCI select CHECK_SIGNATURE if X86 && DMI + select GPIOLIB if I2C_MUX help If you say yes to this option, support will be included for the Intel 801 family of mainboard I2C interfaces. Specifically, the following diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 33e9b0c09af2..bb1d7291cf21 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -80,6 +80,13 @@ #include #include #include +#include + +#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE +#include +#include +#include +#endif /* I801 SMBus address offsets */ #define SMBHSTSTS(p) (0 + (p)->smba) @@ -158,6 +165,15 @@ #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22 +struct i801_mux_config { + char *gpio_chip; + unsigned values[3]; + int n_values; + unsigned classes[3]; + unsigned gpios[2]; /* Relative to gpio_chip->base */ + int n_gpios; +}; + struct i801_priv { struct i2c_adapter adapter; unsigned long smba; @@ -175,6 +191,12 @@ struct i801_priv { int count; int len; u8 *data; + +#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE + const struct i801_mux_config *mux_drvdata; + unsigned mux_priv[2]; + struct platform_device *mux_pdev; +#endif }; static struct pci_driver i801_driver; @@ -900,6 +922,193 @@ static void __init input_apanel_init(void) {} static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) {} #endif /* CONFIG_X86 && CONFIG_DMI */ +#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE +static struct i801_mux_config i801_mux_config_asus_z8_d12 = { + .gpio_chip = "gpio_ich", + .values = { 0x02, 0x03 }, + .n_values = 2, + .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD }, + .gpios = { 52, 53 }, + .n_gpios = 2, +}; + +static struct i801_mux_config i801_mux_config_asus_z8_d18 = { + .gpio_chip = "gpio_ich", + .values = { 0x02, 0x03, 0x01 }, + .n_values = 3, + .classes = { I2C_CLASS_SPD, I2C_CLASS_SPD, I2C_CLASS_SPD }, + .gpios = { 52, 53 }, + .n_gpios = 2, +}; + +static struct dmi_system_id __devinitdata mux_dmi_table[] = { + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8NA-D6(C)"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)E-D12(X)"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8NH-D12"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8PH-D12/IFB"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8NR-D12"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)H-D12"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8PG-D18"), + }, + .driver_data = &i801_mux_config_asus_z8_d18, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8PE-D18"), + }, + .driver_data = &i801_mux_config_asus_z8_d18, + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "Z8PS-D12"), + }, + .driver_data = &i801_mux_config_asus_z8_d12, + }, + { } +}; + +static int __devinit match_gpio_chip_by_label(struct gpio_chip *chip, + void *data) +{ + return !strcmp(chip->label, data); +} + +/* Setup multiplexing if needed */ +static int __devinit i801_add_mux(struct i801_priv *priv) +{ + struct device *dev = &priv->adapter.dev; + const struct i801_mux_config *mux_config; + struct gpio_chip *gpio; + struct i2c_mux_gpio_platform_data gpio_data; + int i, err; + + if (!priv->mux_drvdata) + return 0; + mux_config = priv->mux_drvdata; + + /* Find GPIO chip */ + gpio = gpiochip_find(mux_config->gpio_chip, match_gpio_chip_by_label); + if (gpio) { + dev_info(dev, + "GPIO chip %s found, SMBus multiplexing enabled\n", + mux_config->gpio_chip); + } else { + dev_err(dev, + "GPIO chip %s not found, SMBus multiplexing disabled\n", + mux_config->gpio_chip); + return -ENODEV; + } + + /* Find absolute GPIO pin numbers */ + if (ARRAY_SIZE(priv->mux_priv) < mux_config->n_gpios) { + dev_err(dev, "i801_priv.mux_priv too small (%zu, need %d)\n", + ARRAY_SIZE(priv->mux_priv), mux_config->n_gpios); + return -ENODEV; + } + for (i = 0; i < mux_config->n_gpios; i++) + priv->mux_priv[i] = gpio->base + mux_config->gpios[i]; + + /* Prepare the platform data */ + memset(&gpio_data, 0, sizeof(struct i2c_mux_gpio_platform_data)); + gpio_data.parent = priv->adapter.nr; + gpio_data.values = mux_config->values; + gpio_data.n_values = mux_config->n_values; + gpio_data.classes = mux_config->classes; + gpio_data.gpios = priv->mux_priv; + gpio_data.n_gpios = mux_config->n_gpios; + gpio_data.idle = I2C_MUX_GPIO_NO_IDLE; + + /* Register the mux device */ + priv->mux_pdev = platform_device_register_data(dev, "i2c-mux-gpio", + priv->mux_priv[0], &gpio_data, + sizeof(struct i2c_mux_gpio_platform_data)); + if (IS_ERR(priv->mux_pdev)) { + err = PTR_ERR(priv->mux_pdev); + priv->mux_pdev = NULL; + dev_err(dev, "Failed to register i2c-mux-gpio device\n"); + return err; + } + + return 0; +} + +static void __devexit i801_del_mux(struct i801_priv *priv) +{ + if (priv->mux_pdev) + platform_device_unregister(priv->mux_pdev); +} + +static unsigned int __devinit i801_get_adapter_class(struct i801_priv *priv) +{ + const struct dmi_system_id *id; + const struct i801_mux_config *mux_config; + unsigned int class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + int i; + + id = dmi_first_match(mux_dmi_table); + if (id) { + /* Remove from branch classes from trunk */ + mux_config = id->driver_data; + for (i = 0; i < mux_config->n_values; i++) + class &= ~mux_config->classes[i]; + + /* Remember for later */ + priv->mux_drvdata = mux_config; + } + + return class; +} +#else +static inline int i801_add_mux(struct i801_priv *priv) { return 0; } +static inline void i801_del_mux(struct i801_priv *priv) { } + +static inline unsigned int i801_get_adapter_class(struct i801_priv *priv) +{ + return I2C_CLASS_HWMON | I2C_CLASS_SPD; +} +#endif + static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) { @@ -913,7 +1122,7 @@ static int __devinit i801_probe(struct pci_dev *dev, i2c_set_adapdata(&priv->adapter, priv); priv->adapter.owner = THIS_MODULE; - priv->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + priv->adapter.class = i801_get_adapter_class(priv); priv->adapter.algo = &smbus_algorithm; priv->pci_dev = dev; @@ -1033,6 +1242,8 @@ static int __devinit i801_probe(struct pci_dev *dev, } i801_probe_optional_slaves(priv); + /* We ignore errors - multiplexing is optional */ + i801_add_mux(priv); pci_set_drvdata(dev, priv); @@ -1052,6 +1263,7 @@ static void __devexit i801_remove(struct pci_dev *dev) { struct i801_priv *priv = pci_get_drvdata(dev); + i801_del_mux(priv); i2c_del_adapter(&priv->adapter); pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); -- cgit v1.2.3-58-ga151 From 2614a8594152cad49047ed02255a3d9fbbbea8dd Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 5 Oct 2012 22:23:53 +0200 Subject: i2c-mux-gpio: Use devm_kzalloc instead of kzalloc Use the devm_kzalloc managed function to stripdown the error and remove code. Signed-off-by: Maxime Ripard Acked-by: Peter Korsgaard Signed-off-by: Jean Delvare --- drivers/i2c/muxes/i2c-mux-gpio.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c index 56889e00c76e..7c23bb51bd33 100644 --- a/drivers/i2c/muxes/i2c-mux-gpio.c +++ b/drivers/i2c/muxes/i2c-mux-gpio.c @@ -71,7 +71,7 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev) return -ENODEV; } - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL); if (!mux) { ret = -ENOMEM; goto alloc_failed; @@ -79,11 +79,12 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev) mux->parent = parent; mux->data = *pdata; - mux->adap = kzalloc(sizeof(struct i2c_adapter *) * pdata->n_values, - GFP_KERNEL); + mux->adap = devm_kzalloc(&pdev->dev, + sizeof(*mux->adap) * pdata->n_values, + GFP_KERNEL); if (!mux->adap) { ret = -ENOMEM; - goto alloc_failed2; + goto alloc_failed; } if (pdata->idle != I2C_MUX_GPIO_NO_IDLE) { @@ -130,9 +131,6 @@ add_adapter_failed: err_request_gpio: for (; i > 0; i--) gpio_free(pdata->gpios[i - 1]); - kfree(mux->adap); -alloc_failed2: - kfree(mux); alloc_failed: i2c_put_adapter(parent); @@ -152,8 +150,6 @@ static int __devexit i2c_mux_gpio_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); i2c_put_adapter(mux->parent); - kfree(mux->adap); - kfree(mux); return 0; } -- cgit v1.2.3-58-ga151 From e7ee51405835cac72e7b6e0ff26dba608cf186cc Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 5 Oct 2012 22:23:54 +0200 Subject: i2c-mux-gpio: Add support for dynamically allocated GPIO pins The code instantiating an i2c-mux-gpio platform device doesn't necessarily know in advance the GPIO pin numbers it wants to use. If pins are on a GPIO device which gets its base GPIO number assigned dynamically at run-time, the values can't be hard-coded. In that case, let the caller tell i2c-mux-gpio the name of the GPIO chip and the (relative) GPIO pin numbers to use. At probe time, the i2c-mux-gpio driver will look for the chip and apply the proper offset to turn relative GPIO pin numbers to absolute GPIO pin numbers. The same could be (and was so far) done on the caller's end, however doing it in i2c-mux-gpio has two benefits: * It avoids duplicating the code on every caller's side (about 30 lines of code.) * It allows for deferred probing for the muxed part of the I2C bus only. If finding the GPIO chip is the caller's responsibility, then deferred probing (if the GPIO chip isn't there yet) will not only affect the mux and the I2C bus segments behind it, but also the I2C bus trunk. Signed-off-by: Jean Delvare Cc: Peter Korsgaard --- drivers/i2c/muxes/i2c-mux-gpio.c | 38 ++++++++++++++++++++++++++++++++------ include/linux/i2c-mux-gpio.h | 3 +++ 2 files changed, 35 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c index 7c23bb51bd33..566a6757a33d 100644 --- a/drivers/i2c/muxes/i2c-mux-gpio.c +++ b/drivers/i2c/muxes/i2c-mux-gpio.c @@ -21,6 +21,7 @@ struct gpiomux { struct i2c_adapter *parent; struct i2c_adapter **adap; /* child busses */ struct i2c_mux_gpio_platform_data data; + unsigned gpio_base; }; static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val) @@ -28,7 +29,8 @@ static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val) int i; for (i = 0; i < mux->data.n_gpios; i++) - gpio_set_value(mux->data.gpios[i], val & (1 << i)); + gpio_set_value(mux->gpio_base + mux->data.gpios[i], + val & (1 << i)); } static int i2c_mux_gpio_select(struct i2c_adapter *adap, void *data, u32 chan) @@ -49,13 +51,19 @@ static int i2c_mux_gpio_deselect(struct i2c_adapter *adap, void *data, u32 chan) return 0; } +static int __devinit match_gpio_chip_by_label(struct gpio_chip *chip, + void *data) +{ + return !strcmp(chip->label, data); +} + static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev) { struct gpiomux *mux; struct i2c_mux_gpio_platform_data *pdata; struct i2c_adapter *parent; int (*deselect) (struct i2c_adapter *, void *, u32); - unsigned initial_state; + unsigned initial_state, gpio_base; int i, ret; pdata = pdev->dev.platform_data; @@ -64,6 +72,23 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev) return -ENODEV; } + /* + * If a GPIO chip name is provided, the GPIO pin numbers provided are + * relative to its base GPIO number. Otherwise they are absolute. + */ + if (pdata->gpio_chip) { + struct gpio_chip *gpio; + + gpio = gpiochip_find(pdata->gpio_chip, + match_gpio_chip_by_label); + if (!gpio) + return -EPROBE_DEFER; + + gpio_base = gpio->base; + } else { + gpio_base = 0; + } + parent = i2c_get_adapter(pdata->parent); if (!parent) { dev_err(&pdev->dev, "Parent adapter (%d) not found\n", @@ -79,6 +104,7 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev) mux->parent = parent; mux->data = *pdata; + mux->gpio_base = gpio_base; mux->adap = devm_kzalloc(&pdev->dev, sizeof(*mux->adap) * pdata->n_values, GFP_KERNEL); @@ -96,10 +122,10 @@ static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev) } for (i = 0; i < pdata->n_gpios; i++) { - ret = gpio_request(pdata->gpios[i], "i2c-mux-gpio"); + ret = gpio_request(gpio_base + pdata->gpios[i], "i2c-mux-gpio"); if (ret) goto err_request_gpio; - gpio_direction_output(pdata->gpios[i], + gpio_direction_output(gpio_base + pdata->gpios[i], initial_state & (1 << i)); } @@ -130,7 +156,7 @@ add_adapter_failed: i = pdata->n_gpios; err_request_gpio: for (; i > 0; i--) - gpio_free(pdata->gpios[i - 1]); + gpio_free(gpio_base + pdata->gpios[i - 1]); alloc_failed: i2c_put_adapter(parent); @@ -146,7 +172,7 @@ static int __devexit i2c_mux_gpio_remove(struct platform_device *pdev) i2c_del_mux_adapter(mux->adap[i]); for (i = 0; i < mux->data.n_gpios; i++) - gpio_free(mux->data.gpios[i]); + gpio_free(mux->gpio_base + mux->data.gpios[i]); platform_set_drvdata(pdev, NULL); i2c_put_adapter(mux->parent); diff --git a/include/linux/i2c-mux-gpio.h b/include/linux/i2c-mux-gpio.h index 4ea1cc7392bd..4406108201fe 100644 --- a/include/linux/i2c-mux-gpio.h +++ b/include/linux/i2c-mux-gpio.h @@ -22,6 +22,8 @@ * position * @n_values: Number of multiplexer positions (busses to instantiate) * @classes: Optional I2C auto-detection classes + * @gpio_chip: Optional GPIO chip name; if set, GPIO pin numbers are given + * relative to the base GPIO number of that chip * @gpios: Array of GPIO numbers used to control MUX * @n_gpios: Number of GPIOs used to control MUX * @idle: Bitmask to write to MUX when idle or GPIO_I2CMUX_NO_IDLE if not used @@ -32,6 +34,7 @@ struct i2c_mux_gpio_platform_data { const unsigned *values; int n_values; const unsigned *classes; + char *gpio_chip; const unsigned *gpios; int n_gpios; unsigned idle; -- cgit v1.2.3-58-ga151 From f82b86267a7a7cc2fc9779fa2957467c242395d8 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 5 Oct 2012 22:23:54 +0200 Subject: i2c-i801: Let i2c-mux-gpio find the GPIO chip Now that i2c-mux-gpio is able to find the GPIO chip by itself, we can delegate this task. The great thing here is that i2c-mux-gpio can defer device probing until the gpio chip is available, so we no longer depend on the module loading order. Signed-off-by: Jean Delvare --- drivers/i2c/busses/i2c-i801.c | 37 ++++--------------------------------- 1 file changed, 4 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index bb1d7291cf21..37793156bd93 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -194,7 +194,6 @@ struct i801_priv { #if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE const struct i801_mux_config *mux_drvdata; - unsigned mux_priv[2]; struct platform_device *mux_pdev; #endif }; @@ -1008,60 +1007,32 @@ static struct dmi_system_id __devinitdata mux_dmi_table[] = { { } }; -static int __devinit match_gpio_chip_by_label(struct gpio_chip *chip, - void *data) -{ - return !strcmp(chip->label, data); -} - /* Setup multiplexing if needed */ static int __devinit i801_add_mux(struct i801_priv *priv) { struct device *dev = &priv->adapter.dev; const struct i801_mux_config *mux_config; - struct gpio_chip *gpio; struct i2c_mux_gpio_platform_data gpio_data; - int i, err; + int err; if (!priv->mux_drvdata) return 0; mux_config = priv->mux_drvdata; - /* Find GPIO chip */ - gpio = gpiochip_find(mux_config->gpio_chip, match_gpio_chip_by_label); - if (gpio) { - dev_info(dev, - "GPIO chip %s found, SMBus multiplexing enabled\n", - mux_config->gpio_chip); - } else { - dev_err(dev, - "GPIO chip %s not found, SMBus multiplexing disabled\n", - mux_config->gpio_chip); - return -ENODEV; - } - - /* Find absolute GPIO pin numbers */ - if (ARRAY_SIZE(priv->mux_priv) < mux_config->n_gpios) { - dev_err(dev, "i801_priv.mux_priv too small (%zu, need %d)\n", - ARRAY_SIZE(priv->mux_priv), mux_config->n_gpios); - return -ENODEV; - } - for (i = 0; i < mux_config->n_gpios; i++) - priv->mux_priv[i] = gpio->base + mux_config->gpios[i]; - /* Prepare the platform data */ memset(&gpio_data, 0, sizeof(struct i2c_mux_gpio_platform_data)); gpio_data.parent = priv->adapter.nr; gpio_data.values = mux_config->values; gpio_data.n_values = mux_config->n_values; gpio_data.classes = mux_config->classes; - gpio_data.gpios = priv->mux_priv; + gpio_data.gpio_chip = mux_config->gpio_chip; + gpio_data.gpios = mux_config->gpios; gpio_data.n_gpios = mux_config->n_gpios; gpio_data.idle = I2C_MUX_GPIO_NO_IDLE; /* Register the mux device */ priv->mux_pdev = platform_device_register_data(dev, "i2c-mux-gpio", - priv->mux_priv[0], &gpio_data, + PLATFORM_DEVID_AUTO, &gpio_data, sizeof(struct i2c_mux_gpio_platform_data)); if (IS_ERR(priv->mux_pdev)) { err = PTR_ERR(priv->mux_pdev); -- cgit v1.2.3-58-ga151 From c415b303a704e5c5f766fc0404093910c36cc4ab Mon Sep 17 00:00:00 2001 From: Daniel J Blueman Date: Fri, 5 Oct 2012 22:23:55 +0200 Subject: i2c-piix4: Fix build failure Fix build failure in Intel PIIX4 I2C driver. Signed-off-by: Daniel J Blueman Signed-off-by: Jean Delvare Cc: stable@vger.kernel.org [v3.6] --- drivers/i2c/busses/i2c-piix4.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index ef511df2c965..8bbd6ece7c41 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3-58-ga151