Merge branch 'i2c/for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
[linux-2.6-block.git] / drivers / i2c / busses / i2c-piix4.c
index cba325eb852fed527fe4c73d72fb718113db5097..30ded6422e7b2cc460a4ca3c9a66962c14d12e4b 100644 (file)
@@ -72,7 +72,8 @@
 #define PIIX4_BLOCK_DATA       0x14
 
 /* Multi-port constants */
-#define PIIX4_MAX_ADAPTERS 4
+#define PIIX4_MAX_ADAPTERS     4
+#define HUDSON2_MAIN_PORTS     2 /* HUDSON2, KERNCZ reserves ports 3, 4 */
 
 /* SB800 constants */
 #define SB800_PIIX4_SMB_IDX            0xcd6
@@ -806,10 +807,12 @@ MODULE_DEVICE_TABLE (pci, piix4_ids);
 
 static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS];
 static struct i2c_adapter *piix4_aux_adapter;
+static int piix4_adapter_count;
 
 static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
                             bool sb800_main, u8 port, bool notify_imc,
-                            const char *name, struct i2c_adapter **padap)
+                            u8 hw_port_nr, const char *name,
+                            struct i2c_adapter **padap)
 {
        struct i2c_adapter *adap;
        struct i2c_piix4_adapdata *adapdata;
@@ -841,6 +844,12 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
        /* set up the sysfs linkage to our parent device */
        adap->dev.parent = &dev->dev;
 
+       if (has_acpi_companion(&dev->dev)) {
+               acpi_preset_companion(&adap->dev,
+                                     ACPI_COMPANION(&dev->dev),
+                                     hw_port_nr);
+       }
+
        snprintf(adap->name, sizeof(adap->name),
                "SMBus PIIX4 adapter%s at %04x", name, smba);
 
@@ -865,8 +874,19 @@ static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba,
        int port;
        int retval;
 
-       for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) {
+       if (dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS ||
+           (dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS &&
+            dev->revision >= 0x1F)) {
+               piix4_adapter_count = HUDSON2_MAIN_PORTS;
+       } else {
+               piix4_adapter_count = PIIX4_MAX_ADAPTERS;
+       }
+
+       for (port = 0; port < piix4_adapter_count; port++) {
+               u8 hw_port_nr = port == 0 ? 0 : port + 1;
+
                retval = piix4_add_adapter(dev, smba, true, port, notify_imc,
+                                          hw_port_nr,
                                           piix4_main_port_names_sb800[port],
                                           &piix4_main_adapters[port]);
                if (retval < 0)
@@ -937,8 +957,8 @@ 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, false, 0, false, "",
-                                          &piix4_main_adapters[0]);
+               retval = piix4_add_adapter(dev, retval, false, 0, false, 0,
+                                          "", &piix4_main_adapters[0]);
                if (retval < 0)
                        return retval;
        }
@@ -964,7 +984,7 @@ 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, false, 0, false,
+               piix4_add_adapter(dev, retval, false, 0, false, 1,
                                  is_sb800 ? piix4_aux_port_name_sb800 : "",
                                  &piix4_aux_adapter);
        }
@@ -987,7 +1007,7 @@ static void piix4_adap_remove(struct i2c_adapter *adap)
 
 static void piix4_remove(struct pci_dev *dev)
 {
-       int port = PIIX4_MAX_ADAPTERS;
+       int port = piix4_adapter_count;
 
        while (--port >= 0) {
                if (piix4_main_adapters[port]) {