* [PATCH v4 1/3] i2c-piix4: Convert piix4_main_adapter to array
2015-11-15 11:33 [PATCH v4 0/3] Support multiplexed main SMBus interface on SB800 Christian Fetzer
@ 2015-11-15 11:33 ` Christian Fetzer
2015-11-15 11:33 ` [PATCH v4 2/3] i2c-piix4: Add support for multiplexed main adapter in SB800 Christian Fetzer
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Christian Fetzer @ 2015-11-15 11:33 UTC (permalink / raw)
To: linux-i2c
Cc: jarkko.nikula, andriy.shevchenko, mika.westerberg, wsa,
galandilias, fetzer.ch
The SB800 chipset supports a multiplexed main SMBus controller with
four ports. Therefore the static variable piix4_main_adapter is
converted into a piix4_main_adapters array that can hold one
i2c_adapter for each multiplexed port.
The auxiliary adapter remains unchanged since it represents the second
(not multiplexed) SMBus controller on the SB800 chipset.
Signed-off-by: Christian Fetzer <fetzer.ch@gmail.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/i2c/busses/i2c-piix4.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 630bce6..9c32eb1 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -75,6 +75,9 @@
#define PIIX4_WORD_DATA 0x0C
#define PIIX4_BLOCK_DATA 0x14
+/* Multi-port constants */
+#define PIIX4_MAX_ADAPTERS 4
+
/* insmod parameters */
/* If force is set to anything different from 0, we forcibly enable the
@@ -561,7 +564,7 @@ static const struct pci_device_id piix4_ids[] = {
MODULE_DEVICE_TABLE (pci, piix4_ids);
-static struct i2c_adapter *piix4_main_adapter;
+static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS];
static struct i2c_adapter *piix4_aux_adapter;
static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
@@ -629,7 +632,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
return retval;
/* Try to register main SMBus adapter, give up if we can't */
- retval = piix4_add_adapter(dev, retval, &piix4_main_adapter);
+ retval = piix4_add_adapter(dev, retval, &piix4_main_adapters[0]);
if (retval < 0)
return retval;
@@ -674,9 +677,13 @@ static void piix4_adap_remove(struct i2c_adapter *adap)
static void piix4_remove(struct pci_dev *dev)
{
- if (piix4_main_adapter) {
- piix4_adap_remove(piix4_main_adapter);
- piix4_main_adapter = NULL;
+ int port = PIIX4_MAX_ADAPTERS;
+
+ while (--port >= 0) {
+ if (piix4_main_adapters[port]) {
+ piix4_adap_remove(piix4_main_adapters[port]);
+ piix4_main_adapters[port] = NULL;
+ }
}
if (piix4_aux_adapter) {
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v4 2/3] i2c-piix4: Add support for multiplexed main adapter in SB800
2015-11-15 11:33 [PATCH v4 0/3] Support multiplexed main SMBus interface on SB800 Christian Fetzer
2015-11-15 11:33 ` [PATCH v4 1/3] i2c-piix4: Convert piix4_main_adapter to array Christian Fetzer
@ 2015-11-15 11:33 ` Christian Fetzer
2015-11-16 9:29 ` Andy Shevchenko
2015-11-16 12:31 ` Mika Westerberg
2015-11-15 11:33 ` [PATCH v4 3/3] i2c-piix4: Add adapter port name support for SB800 chipset Christian Fetzer
2015-11-16 9:26 ` [PATCH v4 0/3] Support multiplexed main SMBus interface on SB800 Andy Shevchenko
3 siblings, 2 replies; 7+ messages in thread
From: Christian Fetzer @ 2015-11-15 11:33 UTC (permalink / raw)
To: linux-i2c
Cc: jarkko.nikula, andriy.shevchenko, mika.westerberg, wsa,
galandilias, fetzer.ch, Thomas Brandon, Eddi De Pieri
The SB800 chipset supports a multiplexed main SMBus controller with
four ports. The multiplexed ports share the same SMBus address and
register set. The port is selected by bits 2:1 of the smb_en register
(0x2C).
Only one port can be active at any point in time therefore a mutex is
needed in order to synchronize access.
Additionally, the commit avoids requesting and releasing the SMBus base
address index region on every multiplexed transfer by moving the
request_region call into piix4_probe.
Tested on HP ProLiant MicroServer G7 N54L (where this patch adds
support to access sensor data from the w83795adg).
Cc: Thomas Brandon <tbrandonau@gmail.com>
Cc: Eddi De Pieri <eddi@depieri.net>
Signed-off-by: Christian Fetzer <fetzer.ch@gmail.com>
---
drivers/i2c/busses/i2c-piix4.c | 165 +++++++++++++++++++++++++++++++++++------
1 file changed, 143 insertions(+), 22 deletions(-)
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 9c32eb1..780f2b9 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -23,6 +23,9 @@
Note: we assume there can only be one device, with one or more
SMBus interfaces.
+ The device can register multiple i2c_adapters (up to PIIX4_MAX_ADAPTERS).
+ For devices supporting multiple ports the i2c_adapter should provide
+ an i2c_algorithm to access them.
*/
#include <linux/module.h>
@@ -37,6 +40,7 @@
#include <linux/dmi.h>
#include <linux/acpi.h>
#include <linux/io.h>
+#include <linux/mutex.h>
/* PIIX4 SMBus address offsets */
@@ -78,6 +82,9 @@
/* Multi-port constants */
#define PIIX4_MAX_ADAPTERS 4
+/* SB800 constants */
+#define SB800_PIIX4_SMB_IDX 0xcd6
+
/* insmod parameters */
/* If force is set to anything different from 0, we forcibly enable the
@@ -127,6 +134,11 @@ static const struct dmi_system_id piix4_dmi_ibm[] = {
struct i2c_piix4_adapdata {
unsigned short smba;
+
+ /* SB800 */
+ bool sb800_main;
+ unsigned short port;
+ struct mutex *mutex;
};
static int piix4_setup(struct pci_dev *PIIX4_dev,
@@ -232,7 +244,6 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
const struct pci_device_id *id, u8 aux)
{
unsigned short piix4_smba;
- unsigned short smba_idx = 0xcd6;
u8 smba_en_lo, smba_en_hi, smb_en, smb_en_status;
u8 i2ccfg, i2ccfg_offset = 0x10;
@@ -254,16 +265,10 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
else
smb_en = (aux) ? 0x28 : 0x2c;
- if (!request_region(smba_idx, 2, "smba_idx")) {
- dev_err(&PIIX4_dev->dev, "SMBus base address index region "
- "0x%x already in use!\n", smba_idx);
- return -EBUSY;
- }
- outb_p(smb_en, smba_idx);
- smba_en_lo = inb_p(smba_idx + 1);
- outb_p(smb_en + 1, smba_idx);
- smba_en_hi = inb_p(smba_idx + 1);
- release_region(smba_idx, 2);
+ outb_p(smb_en, SB800_PIIX4_SMB_IDX);
+ smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
+ outb_p(smb_en + 1, SB800_PIIX4_SMB_IDX);
+ smba_en_hi = inb_p(SB800_PIIX4_SMB_IDX + 1);
if (!smb_en) {
smb_en_status = smba_en_lo & 0x10;
@@ -527,6 +532,43 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
return 0;
}
+/*
+ * Handles access to multiple SMBus ports on the SB800.
+ * The port is selected by bits 2:1 of the smb_en register (0x2C).
+ * Returns negative errno on error.
+ *
+ * Note: The selected port must be returned to the initial selection to avoid
+ * problems on certain systems.
+ */
+static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
+ unsigned short flags, char read_write,
+ u8 command, int size, union i2c_smbus_data *data)
+{
+ struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(adap);
+ u8 smba_en_lo, smb_en = 0x2c;
+ u8 port;
+ int retval;
+
+ mutex_lock(adapdata->mutex);
+
+ outb_p(smb_en, SB800_PIIX4_SMB_IDX);
+ smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
+
+ port = adapdata->port;
+ if ((smba_en_lo & 6) != (port << 1))
+ outb_p((smba_en_lo & ~6) | (port << 1),
+ SB800_PIIX4_SMB_IDX + 1);
+
+ retval = piix4_access(adap, addr, flags, read_write,
+ command, size, data);
+
+ outb_p(smba_en_lo, SB800_PIIX4_SMB_IDX + 1);
+
+ mutex_unlock(adapdata->mutex);
+
+ return retval;
+}
+
static u32 piix4_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
@@ -539,6 +581,11 @@ static const struct i2c_algorithm smbus_algorithm = {
.functionality = piix4_func,
};
+static const struct i2c_algorithm piix4_smbus_algorithm_sb800 = {
+ .smbus_xfer = piix4_access_sb800,
+ .functionality = piix4_func,
+};
+
static const struct pci_device_id piix4_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) },
@@ -614,6 +661,53 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
return 0;
}
+static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba)
+{
+ struct mutex *mutex;
+ struct i2c_piix4_adapdata *adapdata;
+ int port;
+ int retval;
+
+ mutex = kzalloc(sizeof(*mutex), GFP_KERNEL);
+ if (mutex == NULL)
+ return -ENOMEM;
+
+ mutex_init(mutex);
+
+ for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) {
+ retval = piix4_add_adapter(dev, smba,
+ &piix4_main_adapters[port]);
+ if (retval < 0)
+ goto error;
+
+ piix4_main_adapters[port]->algo = &piix4_smbus_algorithm_sb800;
+
+ adapdata = i2c_get_adapdata(piix4_main_adapters[port]);
+ adapdata->sb800_main = true;
+ adapdata->port = port;
+ adapdata->mutex = mutex;
+ }
+
+ return retval;
+
+error:
+ dev_err(&dev->dev,
+ "Error setting up SB800 adapters. Unregistering!\n");
+ while (--port >= 0) {
+ adapdata = i2c_get_adapdata(piix4_main_adapters[port]);
+ if (adapdata->smba) {
+ i2c_del_adapter(piix4_main_adapters[port]);
+ kfree(adapdata);
+ kfree(piix4_main_adapters[port]);
+ piix4_main_adapters[port] = NULL;
+ }
+ }
+
+ kfree(mutex);
+
+ return retval;
+}
+
static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
int retval;
@@ -621,20 +715,41 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
if ((dev->vendor == PCI_VENDOR_ID_ATI &&
dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
dev->revision >= 0x40) ||
- dev->vendor == PCI_VENDOR_ID_AMD)
+ dev->vendor == PCI_VENDOR_ID_AMD) {
+ if (!request_region(SB800_PIIX4_SMB_IDX, 2, "smba_idx")) {
+ dev_err(&dev->dev,
+ "SMBus base address index region 0x%x already in use!\n",
+ SB800_PIIX4_SMB_IDX);
+ return -EBUSY;
+ }
+
/* base address location etc changed in SB800 */
retval = piix4_setup_sb800(dev, id, 0);
- else
- retval = piix4_setup(dev, id);
+ if (retval < 0) {
+ release_region(SB800_PIIX4_SMB_IDX, 2);
+ return retval;
+ }
- /* If no main SMBus found, give up */
- if (retval < 0)
- return retval;
+ /*
+ * Try to register multiplexed main SMBus adapter,
+ * give up if we can't
+ */
+ retval = piix4_add_adapters_sb800(dev, retval);
+ if (retval < 0) {
+ release_region(SB800_PIIX4_SMB_IDX, 2);
+ return retval;
+ }
+ } else {
+ retval = piix4_setup(dev, id);
+ if (retval < 0)
+ return retval;
- /* Try to register main SMBus adapter, give up if we can't */
- retval = piix4_add_adapter(dev, retval, &piix4_main_adapters[0]);
- if (retval < 0)
- return retval;
+ /* Try to register main SMBus adapter, give up if we can't */
+ retval = piix4_add_adapter(dev, retval,
+ &piix4_main_adapters[0]);
+ if (retval < 0)
+ return retval;
+ }
/* Check for auxiliary SMBus on some AMD chipsets */
retval = -ENODEV;
@@ -669,7 +784,13 @@ static void piix4_adap_remove(struct i2c_adapter *adap)
if (adapdata->smba) {
i2c_del_adapter(adap);
- release_region(adapdata->smba, SMBIOSIZE);
+ if (adapdata->port == 0) {
+ release_region(adapdata->smba, SMBIOSIZE);
+ if (adapdata->sb800_main) {
+ kfree(adapdata->mutex);
+ release_region(SB800_PIIX4_SMB_IDX, 2);
+ }
+ }
kfree(adapdata);
kfree(adap);
}
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v4 2/3] i2c-piix4: Add support for multiplexed main adapter in SB800
2015-11-15 11:33 ` [PATCH v4 2/3] i2c-piix4: Add support for multiplexed main adapter in SB800 Christian Fetzer
@ 2015-11-16 9:29 ` Andy Shevchenko
2015-11-16 12:31 ` Mika Westerberg
1 sibling, 0 replies; 7+ messages in thread
From: Andy Shevchenko @ 2015-11-16 9:29 UTC (permalink / raw)
To: Christian Fetzer, linux-i2c
Cc: jarkko.nikula, mika.westerberg, wsa, galandilias, Thomas Brandon,
Eddi De Pieri
On Sun, 2015-11-15 at 12:33 +0100, Christian Fetzer wrote:
> The SB800 chipset supports a multiplexed main SMBus controller with
> four ports. The multiplexed ports share the same SMBus address and
> register set. The port is selected by bits 2:1 of the smb_en register
> (0x2C).
>
> Only one port can be active at any point in time therefore a mutex is
> needed in order to synchronize access.
>
> Additionally, the commit avoids requesting and releasing the SMBus
> base
> address index region on every multiplexed transfer by moving the
> request_region call into piix4_probe.
>
> Tested on HP ProLiant MicroServer G7 N54L (where this patch adds
> support to access sensor data from the w83795adg).
One nitpick below.
>
> +/*
> + * Handles access to multiple SMBus ports on the SB800.
>
> + * The port is selected by bits 2:1 of the smb_en register (0x2C).
(1)
> + * Returns negative errno on error.
> + *
> + * Note: The selected port must be returned to the initial selection
> to avoid
> + * problems on certain systems.
> + */
> +static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
> + unsigned short flags, char read_write,
> + u8 command, int size, union i2c_smbus_data *data)
> +{
> + struct i2c_piix4_adapdata *adapdata =
> i2c_get_adapdata(adap);
> + u8 smba_en_lo, smb_en = 0x2c;
> + u8 port;
> + int retval;
> +
> + mutex_lock(adapdata->mutex);
> +
> + outb_p(smb_en, SB800_PIIX4_SMB_IDX);
> + smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
> +
> + port = adapdata->port;
> + if ((smba_en_lo & 6) != (port << 1))
I think it would be nice to have a definition for magic number along
with (1).
/* The port is selected by bits 2:1 of the smb_en register (0x2C) */
#define SB800_PIIX4_PORT_IDX_MASK 0x06
> + outb_p((smba_en_lo & ~6) | (port << 1),
> + SB800_PIIX4_SMB_IDX + 1);
> +
> + retval = piix4_access(adap, addr, flags, read_write,
> + command, size, data);
> +
> + outb_p(smba_en_lo, SB800_PIIX4_SMB_IDX + 1);
> +
> + mutex_unlock(adapdata->mutex);
> +
> + return retval;
> +}
> +
> static u32 piix4_func(struct i2c_adapter *adapter)
> {
> return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
> @@ -539,6 +581,11 @@ static const struct i2c_algorithm
> smbus_algorithm = {
> .functionality = piix4_func,
> };
>
> +static const struct i2c_algorithm piix4_smbus_algorithm_sb800 = {
> + .smbus_xfer = piix4_access_sb800,
> + .functionality = piix4_func,
> +};
> +
> static const struct pci_device_id piix4_ids[] = {
> { PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_INTEL_82371AB_3) },
> { PCI_DEVICE(PCI_VENDOR_ID_INTEL,
> PCI_DEVICE_ID_INTEL_82443MX_3) },
> @@ -614,6 +661,53 @@ static int piix4_add_adapter(struct pci_dev
> *dev, unsigned short smba,
> return 0;
> }
>
> +static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned
> short smba)
> +{
> + struct mutex *mutex;
> + struct i2c_piix4_adapdata *adapdata;
> + int port;
> + int retval;
> +
> + mutex = kzalloc(sizeof(*mutex), GFP_KERNEL);
> + if (mutex == NULL)
> + return -ENOMEM;
> +
> + mutex_init(mutex);
> +
> + for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) {
> + retval = piix4_add_adapter(dev, smba,
> + &piix4_main_adapters[port
> ]);
> + if (retval < 0)
> + goto error;
> +
> + piix4_main_adapters[port]->algo =
> &piix4_smbus_algorithm_sb800;
> +
> + adapdata =
> i2c_get_adapdata(piix4_main_adapters[port]);
> + adapdata->sb800_main = true;
> + adapdata->port = port;
> + adapdata->mutex = mutex;
> + }
> +
> + return retval;
> +
> +error:
> + dev_err(&dev->dev,
> + "Error setting up SB800 adapters.
> Unregistering!\n");
> + while (--port >= 0) {
> + adapdata =
> i2c_get_adapdata(piix4_main_adapters[port]);
> + if (adapdata->smba) {
> + i2c_del_adapter(piix4_main_adapters[port]);
> + kfree(adapdata);
> + kfree(piix4_main_adapters[port]);
> + piix4_main_adapters[port] = NULL;
> + }
> + }
> +
> + kfree(mutex);
> +
> + return retval;
> +}
> +
> static int piix4_probe(struct pci_dev *dev, const struct
> pci_device_id *id)
> {
> int retval;
> @@ -621,20 +715,41 @@ static int piix4_probe(struct pci_dev *dev,
> const struct pci_device_id *id)
> if ((dev->vendor == PCI_VENDOR_ID_ATI &&
> dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
> dev->revision >= 0x40) ||
> - dev->vendor == PCI_VENDOR_ID_AMD)
> + dev->vendor == PCI_VENDOR_ID_AMD) {
> + if (!request_region(SB800_PIIX4_SMB_IDX, 2,
> "smba_idx")) {
> + dev_err(&dev->dev,
> + "SMBus base address index region 0x%x
> already in use!\n",
> + SB800_PIIX4_SMB_IDX);
> + return -EBUSY;
> + }
> +
> /* base address location etc changed in SB800 */
> retval = piix4_setup_sb800(dev, id, 0);
> - else
> - retval = piix4_setup(dev, id);
> + if (retval < 0) {
> + release_region(SB800_PIIX4_SMB_IDX, 2);
> + return retval;
> + }
>
> - /* If no main SMBus found, give up */
> - if (retval < 0)
> - return retval;
> + /*
> + * Try to register multiplexed main SMBus adapter,
> + * give up if we can't
> + */
> + retval = piix4_add_adapters_sb800(dev, retval);
> + if (retval < 0) {
> + release_region(SB800_PIIX4_SMB_IDX, 2);
> + return retval;
> + }
> + } else {
> + retval = piix4_setup(dev, id);
> + if (retval < 0)
> + return retval;
>
> - /* Try to register main SMBus adapter, give up if we can't
> */
> - retval = piix4_add_adapter(dev, retval,
> &piix4_main_adapters[0]);
> - if (retval < 0)
> - return retval;
> + /* Try to register main SMBus adapter, give up if we
> can't */
> + retval = piix4_add_adapter(dev, retval,
> + &piix4_main_adapters[0]);
> + if (retval < 0)
> + return retval;
> + }
>
> /* Check for auxiliary SMBus on some AMD chipsets */
> retval = -ENODEV;
> @@ -669,7 +784,13 @@ static void piix4_adap_remove(struct i2c_adapter
> *adap)
>
> if (adapdata->smba) {
> i2c_del_adapter(adap);
> - release_region(adapdata->smba, SMBIOSIZE);
> + if (adapdata->port == 0) {
> + release_region(adapdata->smba, SMBIOSIZE);
> + if (adapdata->sb800_main) {
> + kfree(adapdata->mutex);
> + release_region(SB800_PIIX4_SMB_IDX,
> 2);
> + }
> + }
> kfree(adapdata);
> kfree(adap);
> }
--
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH v4 2/3] i2c-piix4: Add support for multiplexed main adapter in SB800
2015-11-15 11:33 ` [PATCH v4 2/3] i2c-piix4: Add support for multiplexed main adapter in SB800 Christian Fetzer
2015-11-16 9:29 ` Andy Shevchenko
@ 2015-11-16 12:31 ` Mika Westerberg
1 sibling, 0 replies; 7+ messages in thread
From: Mika Westerberg @ 2015-11-16 12:31 UTC (permalink / raw)
To: Christian Fetzer
Cc: linux-i2c, jarkko.nikula, andriy.shevchenko, wsa, galandilias,
Thomas Brandon, Eddi De Pieri
On Sun, Nov 15, 2015 at 12:33:03PM +0100, Christian Fetzer wrote:
> The SB800 chipset supports a multiplexed main SMBus controller with
> four ports. The multiplexed ports share the same SMBus address and
> register set. The port is selected by bits 2:1 of the smb_en register
> (0x2C).
>
> Only one port can be active at any point in time therefore a mutex is
> needed in order to synchronize access.
>
> Additionally, the commit avoids requesting and releasing the SMBus base
> address index region on every multiplexed transfer by moving the
> request_region call into piix4_probe.
>
> Tested on HP ProLiant MicroServer G7 N54L (where this patch adds
> support to access sensor data from the w83795adg).
>
> Cc: Thomas Brandon <tbrandonau@gmail.com>
> Cc: Eddi De Pieri <eddi@depieri.net>
> Signed-off-by: Christian Fetzer <fetzer.ch@gmail.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v4 3/3] i2c-piix4: Add adapter port name support for SB800 chipset
2015-11-15 11:33 [PATCH v4 0/3] Support multiplexed main SMBus interface on SB800 Christian Fetzer
2015-11-15 11:33 ` [PATCH v4 1/3] i2c-piix4: Convert piix4_main_adapter to array Christian Fetzer
2015-11-15 11:33 ` [PATCH v4 2/3] i2c-piix4: Add support for multiplexed main adapter in SB800 Christian Fetzer
@ 2015-11-15 11:33 ` Christian Fetzer
2015-11-16 9:26 ` [PATCH v4 0/3] Support multiplexed main SMBus interface on SB800 Andy Shevchenko
3 siblings, 0 replies; 7+ messages in thread
From: Christian Fetzer @ 2015-11-15 11:33 UTC (permalink / raw)
To: linux-i2c
Cc: jarkko.nikula, andriy.shevchenko, mika.westerberg, wsa,
galandilias, fetzer.ch
This patch adds support for port names for the SB800 chipset.
Since the chipset supports a multiplexed main SMBus controller, adding
the channel name to the adapter name is necessary to differentiate the
ports better (for example in sensors output).
Signed-off-by: Christian Fetzer <fetzer.ch@gmail.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/i2c/busses/i2c-piix4.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 780f2b9..cd2b098 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -132,6 +132,12 @@ static const struct dmi_system_id piix4_dmi_ibm[] = {
{ },
};
+/* SB800 globals */
+static const char *piix4_main_port_names_sb800[PIIX4_MAX_ADAPTERS] = {
+ "SDA0", "SDA2", "SDA3", "SDA4"
+};
+static const char *piix4_aux_port_name_sb800 = "SDA1";
+
struct i2c_piix4_adapdata {
unsigned short smba;
@@ -615,7 +621,7 @@ static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS];
static struct i2c_adapter *piix4_aux_adapter;
static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
- struct i2c_adapter **padap)
+ const char *name, struct i2c_adapter **padap)
{
struct i2c_adapter *adap;
struct i2c_piix4_adapdata *adapdata;
@@ -644,7 +650,7 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
adap->dev.parent = &dev->dev;
snprintf(adap->name, sizeof(adap->name),
- "SMBus PIIX4 adapter at %04x", smba);
+ "SMBus PIIX4 adapter %s at %04x", name, smba);
i2c_set_adapdata(adap, adapdata);
@@ -676,6 +682,7 @@ static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba)
for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) {
retval = piix4_add_adapter(dev, smba,
+ piix4_main_port_names_sb800[port],
&piix4_main_adapters[port]);
if (retval < 0)
goto error;
@@ -745,7 +752,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
return retval;
/* Try to register main SMBus adapter, give up if we can't */
- retval = piix4_add_adapter(dev, retval,
+ retval = piix4_add_adapter(dev, retval, "main",
&piix4_main_adapters[0]);
if (retval < 0)
return retval;
@@ -772,7 +779,8 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
if (retval > 0) {
/* Try to add the aux adapter if it exists,
* piix4_add_adapter will clean up if this fails */
- piix4_add_adapter(dev, retval, &piix4_aux_adapter);
+ piix4_add_adapter(dev, retval, piix4_aux_port_name_sb800,
+ &piix4_aux_adapter);
}
return 0;
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v4 0/3] Support multiplexed main SMBus interface on SB800
2015-11-15 11:33 [PATCH v4 0/3] Support multiplexed main SMBus interface on SB800 Christian Fetzer
` (2 preceding siblings ...)
2015-11-15 11:33 ` [PATCH v4 3/3] i2c-piix4: Add adapter port name support for SB800 chipset Christian Fetzer
@ 2015-11-16 9:26 ` Andy Shevchenko
3 siblings, 0 replies; 7+ messages in thread
From: Andy Shevchenko @ 2015-11-16 9:26 UTC (permalink / raw)
To: Christian Fetzer, linux-i2c
Cc: jarkko.nikula, mika.westerberg, wsa, galandilias
On Sun, 2015-11-15 at 12:33 +0100, Christian Fetzer wrote:
> This is an attempt to upstream the patches created by Thomas Brandon
> and
> Eddi De Pieri to support the multiplexed main SMBus interface on the
> SB800
> chipset. (https://www.mail-archive.com/linux-i2c@vger.kernel.org/msg0
> 6757.html)
>
> I have mainly rebased the latest patch version and tested the driver
> on a
> HP ProLiant MicroServer G7 N54L (where this patch allows to access
> sensor data
> from a w83795adg).
>
> The patched driver is running stable on the machine, given that
> ic2_piix4 is
> loaded before jc42 and w83795. If jc42 is loaded before i2c_piix4
> calling
> sensors triggers some errors:
> ERROR: Can't get value of subfeature temp1_min_alarm: Can't read
>
> While the kernel log shows:
> i2c i2c-1: Transaction (pre): CNT=0c, CMD=05, ADD=31, DAT0=03,
> DAT1=c0
> i2c i2c-1: Error: no response!
> i2c i2c-1: Transaction (post): CNT=0c, CMD=05, ADD=31, DAT0=ff,
> DAT1=ff
> Unfortunately I don't know how to tackle this specific issue.
>
> Please review and let me know required changes in order to get this
> upstream
> finally.
One nitpick in one patch, though it looks okay for me:
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
>
> Eddi, Thomas, it would be great if you could verify the changes on
> your
> machines.
>
> Regards,
> Christian
>
> v4:
> - Incorporated changes requested by Andy
> - added mutex to struct i2c_piix4_adapdata
> - added flag for releasing SMBus index region to struct
> i2c_piix4_adapdata
> - this flag now indicates that the adapter is a sb800 main
> adapter
> - together with the port number it simplifies the adapter
> releasing and the first patch in v3 is no more needed
> - unfortunately patch 3 and 4 in v3 had to be combined as
> only
> the patch introducing multiplexing adds a separate
> add_adapters_sb800
> method that can be used to set the flag.
> - fixed releasing the SMBus index region in case setting up the
> adapter fails
>
> v3:
> - Incorporated changes requested by Mika and Andy
> - main adapter name set to 'main'
> - defined constant idx address
> - block comment style, joined string literals, reworked for loops
> into while loops
>
> v2:
> - Incorporated changes requested by Mika
> - remove adapter in reverse order
> - ERROR label
> - request base address index region only once
>
> Christian Fetzer (3):
> i2c-piix4: Convert piix4_main_adapter to array
> i2c-piix4: Add support for multiplexed main adapter in SB800
> i2c-piix4: Add adapter port name support for SB800 chipset
>
> drivers/i2c/busses/i2c-piix4.c | 194
> +++++++++++++++++++++++++++++++++++------
> 1 file changed, 165 insertions(+), 29 deletions(-)
>
--
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy
^ permalink raw reply [flat|nested] 7+ messages in thread