diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-piix4.c')
| -rw-r--r-- | drivers/i2c/busses/i2c-piix4.c | 340 |
1 files changed, 239 insertions, 101 deletions
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 90946a8b9a75..ac3bb550303f 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl> and Philip Edelbrock <phil@netroedge.com> - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ /* @@ -19,6 +11,7 @@ Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100 ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800 AMD Hudson-2, ML, CZ + Hygon CZ SMSC Victory66 Note: we assume there can only be one device, with one or more @@ -36,25 +29,14 @@ #include <linux/stddef.h> #include <linux/ioport.h> #include <linux/i2c.h> +#include <linux/i2c-smbus.h> #include <linux/slab.h> #include <linux/dmi.h> #include <linux/acpi.h> #include <linux/io.h> +#include <linux/platform_data/x86/amd-fch.h> - -/* PIIX4 SMBus address offsets */ -#define SMBHSTSTS (0 + piix4_smba) -#define SMBHSLVSTS (1 + piix4_smba) -#define SMBHSTCNT (2 + piix4_smba) -#define SMBHSTCMD (3 + piix4_smba) -#define SMBHSTADD (4 + piix4_smba) -#define SMBHSTDAT0 (5 + piix4_smba) -#define SMBHSTDAT1 (6 + piix4_smba) -#define SMBBLKDAT (7 + piix4_smba) -#define SMBSLVCNT (8 + piix4_smba) -#define SMBSHDWCMD (9 + piix4_smba) -#define SMBSLVEVT (0xA + piix4_smba) -#define SMBSLVDAT (0xC + piix4_smba) +#include "i2c-piix4.h" /* count for request_region */ #define SMBIOSIZE 9 @@ -76,13 +58,14 @@ #define PIIX4_BYTE 0x04 #define PIIX4_BYTE_DATA 0x08 #define PIIX4_WORD_DATA 0x0C -#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 +#define SB800_PIIX4_SMB_MAP_SIZE 2 #define KERNCZ_IMC_IDX 0x3e #define KERNCZ_IMC_DATA 0x3f @@ -98,11 +81,14 @@ #define SB800_PIIX4_PORT_IDX_MASK 0x06 #define SB800_PIIX4_PORT_IDX_SHIFT 1 -/* On kerncz, SmBus0Sel is at bit 20:19 of PMx00 DecodeEn */ -#define SB800_PIIX4_PORT_IDX_KERNCZ 0x02 -#define SB800_PIIX4_PORT_IDX_MASK_KERNCZ 0x18 +/* SmBus0Sel is at bit 20:19 of PMx00 DecodeEn */ +#define SB800_PIIX4_PORT_IDX_KERNCZ (FCH_PM_DECODEEN + 0x02) +#define SB800_PIIX4_PORT_IDX_MASK_KERNCZ (FCH_PM_DECODEEN_SMBUS0SEL >> 16) #define SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ 3 +#define SB800_PIIX4_FCH_PM_SIZE 8 +#define SB800_ASF_ACPI_PATH "\\_SB.ASFC" + /* insmod parameters */ /* If force is set to anything different from 0, we forcibly enable the @@ -147,7 +133,7 @@ static const struct dmi_system_id piix4_dmi_ibm[] = { .ident = "IBM", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, }, - { }, + { } }; /* @@ -168,8 +154,74 @@ struct i2c_piix4_adapdata { bool sb800_main; bool notify_imc; u8 port; /* Port number, shifted */ + struct sb800_mmio_cfg mmio_cfg; }; +int piix4_sb800_region_request(struct device *dev, struct sb800_mmio_cfg *mmio_cfg) +{ + if (mmio_cfg->use_mmio) { + void __iomem *addr; + + if (!request_mem_region_muxed(FCH_PM_BASE, + SB800_PIIX4_FCH_PM_SIZE, + "sb800_piix4_smb")) { + dev_err(dev, + "SMBus base address memory region 0x%x already in use.\n", + FCH_PM_BASE); + return -EBUSY; + } + + addr = ioremap(FCH_PM_BASE, + SB800_PIIX4_FCH_PM_SIZE); + if (!addr) { + release_mem_region(FCH_PM_BASE, + SB800_PIIX4_FCH_PM_SIZE); + dev_err(dev, "SMBus base address mapping failed.\n"); + return -ENOMEM; + } + + mmio_cfg->addr = addr; + + return 0; + } + + if (!request_muxed_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE, + "sb800_piix4_smb")) { + dev_err(dev, + "SMBus base address index region 0x%x already in use.\n", + SB800_PIIX4_SMB_IDX); + return -EBUSY; + } + + return 0; +} +EXPORT_SYMBOL_NS_GPL(piix4_sb800_region_request, "PIIX4_SMBUS"); + +void piix4_sb800_region_release(struct device *dev, struct sb800_mmio_cfg *mmio_cfg) +{ + if (mmio_cfg->use_mmio) { + iounmap(mmio_cfg->addr); + release_mem_region(FCH_PM_BASE, + SB800_PIIX4_FCH_PM_SIZE); + return; + } + + release_region(SB800_PIIX4_SMB_IDX, SB800_PIIX4_SMB_MAP_SIZE); +} +EXPORT_SYMBOL_NS_GPL(piix4_sb800_region_release, "PIIX4_SMBUS"); + +static bool piix4_sb800_use_mmio(struct pci_dev *PIIX4_dev) +{ + /* + * cd6h/cd7h port I/O accesses can be disabled on AMD processors + * w/ SMBus PCI revision ID 0x51 or greater. MMIO is supported on + * the same processors and is the recommended access method. + */ + return (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD && + PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS && + PIIX4_dev->revision >= 0x51); +} + static int piix4_setup(struct pci_dev *PIIX4_dev, const struct pci_device_id *id) { @@ -269,12 +321,61 @@ static int piix4_setup(struct pci_dev *PIIX4_dev, return piix4_smba; } +static int piix4_setup_sb800_smba(struct pci_dev *PIIX4_dev, + u8 smb_en, + u8 aux, + u8 *smb_en_status, + unsigned short *piix4_smba) +{ + struct sb800_mmio_cfg mmio_cfg; + u8 smba_en_lo; + u8 smba_en_hi; + int retval; + + mmio_cfg.use_mmio = piix4_sb800_use_mmio(PIIX4_dev); + retval = piix4_sb800_region_request(&PIIX4_dev->dev, &mmio_cfg); + if (retval) + return retval; + + if (mmio_cfg.use_mmio) { + smba_en_lo = ioread8(mmio_cfg.addr); + smba_en_hi = ioread8(mmio_cfg.addr + 1); + } else { + 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); + } + + piix4_sb800_region_release(&PIIX4_dev->dev, &mmio_cfg); + + if (!smb_en) { + *smb_en_status = smba_en_lo & 0x10; + *piix4_smba = smba_en_hi << 8; + if (aux) + *piix4_smba |= 0x20; + } else { + *smb_en_status = smba_en_lo & 0x01; + *piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; + } + + if (!*smb_en_status) { + dev_err(&PIIX4_dev->dev, + "SMBus Host Controller not enabled!\n"); + return -ENODEV; + } + + return 0; +} + static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, const struct pci_device_id *id, u8 aux) { unsigned short piix4_smba; - u8 smba_en_lo, smba_en_hi, smb_en, smb_en_status, port_sel; + u8 smb_en, smb_en_status, port_sel; u8 i2ccfg, i2ccfg_offset = 0x10; + struct sb800_mmio_cfg mmio_cfg; + int retval; /* SB800 and later SMBus does not support forcing address */ if (force || force_addr) { @@ -289,40 +390,18 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, PIIX4_dev->revision >= 0x41) || (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD && PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS && - PIIX4_dev->revision >= 0x49)) + PIIX4_dev->revision >= 0x49) || + (PIIX4_dev->vendor == PCI_VENDOR_ID_HYGON && + PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS)) smb_en = 0x00; else smb_en = (aux) ? 0x28 : 0x2c; - if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2, "sb800_piix4_smb")) { - dev_err(&PIIX4_dev->dev, - "SMB base address index region 0x%x already in use.\n", - SB800_PIIX4_SMB_IDX); - return -EBUSY; - } - - 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); - - release_region(SB800_PIIX4_SMB_IDX, 2); - - if (!smb_en) { - smb_en_status = smba_en_lo & 0x10; - piix4_smba = smba_en_hi << 8; - if (aux) - piix4_smba |= 0x20; - } else { - smb_en_status = smba_en_lo & 0x01; - piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; - } + retval = piix4_setup_sb800_smba(PIIX4_dev, smb_en, aux, &smb_en_status, + &piix4_smba); - if (!smb_en_status) { - dev_err(&PIIX4_dev->dev, - "SMBus Host Controller not enabled!\n"); - return -ENODEV; - } + if (retval) + return retval; if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) return -ENODEV; @@ -361,25 +440,25 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, piix4_smba, i2ccfg >> 4); /* Find which register is used for port selection */ - if (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD) { - switch (PIIX4_dev->device) { - case PCI_DEVICE_ID_AMD_KERNCZ_SMBUS: + if (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD || + PIIX4_dev->vendor == PCI_VENDOR_ID_HYGON) { + if (PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS || + (PIIX4_dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS && + PIIX4_dev->revision >= 0x1F)) { piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_KERNCZ; piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK_KERNCZ; piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ; - break; - case PCI_DEVICE_ID_AMD_HUDSON2_SMBUS: - default: + } else { piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_ALT; piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK; piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT; - break; } } else { - if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2, - "sb800_piix4_smb")) { + mmio_cfg.use_mmio = piix4_sb800_use_mmio(PIIX4_dev); + retval = piix4_sb800_region_request(&PIIX4_dev->dev, &mmio_cfg); + if (retval) { release_region(piix4_smba, SMBIOSIZE); - return -EBUSY; + return retval; } outb_p(SB800_PIIX4_PORT_IDX_SEL, SB800_PIIX4_SMB_IDX); @@ -389,7 +468,7 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, SB800_PIIX4_PORT_IDX; piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK; piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT; - release_region(SB800_PIIX4_SMB_IDX, 2); + piix4_sb800_region_release(&PIIX4_dev->dev, &mmio_cfg); } dev_info(&PIIX4_dev->dev, @@ -439,10 +518,8 @@ static int piix4_setup_aux(struct pci_dev *PIIX4_dev, return piix4_smba; } -static int piix4_transaction(struct i2c_adapter *piix4_adapter) +int piix4_transaction(struct i2c_adapter *piix4_adapter, unsigned short piix4_smba) { - struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter); - unsigned short piix4_smba = adapdata->smba; int temp; int result = 0; int timeout = 0; @@ -493,7 +570,7 @@ static int piix4_transaction(struct i2c_adapter *piix4_adapter) result = -EIO; dev_dbg(&piix4_adapter->dev, "Bus collision! SMBus may be " "locked until next hard reset. (sorry!)\n"); - /* Clock stops and slave is stuck in mid-transmission */ + /* Clock stops and target is stuck in mid-transmission */ } if (temp & 0x04) { @@ -514,6 +591,7 @@ static int piix4_transaction(struct i2c_adapter *piix4_adapter) inb_p(SMBHSTDAT1)); return result; } +EXPORT_SYMBOL_NS_GPL(piix4_transaction, "PIIX4_SMBUS"); /* Return negative errno on error. */ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, @@ -578,7 +656,7 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr, outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT); - status = piix4_transaction(adap); + status = piix4_transaction(adap, piix4_smba); if (status) return status; @@ -667,6 +745,30 @@ static void piix4_imc_wakeup(void) release_region(KERNCZ_IMC_IDX, 2); } +int piix4_sb800_port_sel(u8 port, struct sb800_mmio_cfg *mmio_cfg) +{ + u8 smba_en_lo, val; + + if (mmio_cfg->use_mmio) { + smba_en_lo = ioread8(mmio_cfg->addr + piix4_port_sel_sb800); + val = (smba_en_lo & ~piix4_port_mask_sb800) | port; + if (smba_en_lo != val) + iowrite8(val, mmio_cfg->addr + piix4_port_sel_sb800); + + return (smba_en_lo & piix4_port_mask_sb800); + } + + outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX); + smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); + + val = (smba_en_lo & ~piix4_port_mask_sb800) | port; + if (smba_en_lo != val) + outb_p(val, SB800_PIIX4_SMB_IDX + 1); + + return (smba_en_lo & piix4_port_mask_sb800); +} +EXPORT_SYMBOL_NS_GPL(piix4_sb800_port_sel, "PIIX4_SMBUS"); + /* * Handles access to multiple SMBus ports on the SB800. * The port is selected by bits 2:1 of the smb_en register (0x2c). @@ -683,12 +785,12 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, unsigned short piix4_smba = adapdata->smba; int retries = MAX_TIMEOUT; int smbslvcnt; - u8 smba_en_lo; - u8 port; + u8 prev_port; int retval; - if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2, "sb800_piix4_smb")) - return -EBUSY; + retval = piix4_sb800_region_request(&adap->dev, &adapdata->mmio_cfg); + if (retval) + return retval; /* Request the SMBUS semaphore, avoid conflicts with the IMC */ smbslvcnt = inb_p(SMBSLVCNT); @@ -743,18 +845,12 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, } } - outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX); - smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1); - - port = adapdata->port; - if ((smba_en_lo & piix4_port_mask_sb800) != port) - outb_p((smba_en_lo & ~piix4_port_mask_sb800) | port, - SB800_PIIX4_SMB_IDX + 1); + prev_port = piix4_sb800_port_sel(adapdata->port, &adapdata->mmio_cfg); retval = piix4_access(adap, addr, flags, read_write, command, size, data); - outb_p(smba_en_lo, SB800_PIIX4_SMB_IDX + 1); + piix4_sb800_port_sel(prev_port, &adapdata->mmio_cfg); /* Release the semaphore */ outb_p(smbslvcnt | 0x20, SMBSLVCNT); @@ -763,7 +859,7 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, piix4_imc_wakeup(); release: - release_region(SB800_PIIX4_SMB_IDX, 2); + piix4_sb800_region_release(&adap->dev, &adapdata->mmio_cfg); return retval; } @@ -794,6 +890,7 @@ static const struct pci_device_id piix4_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4) }, { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, @@ -811,10 +908,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; @@ -827,7 +926,7 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, } adap->owner = THIS_MODULE; - adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + adap->class = I2C_CLASS_HWMON; adap->algo = sb800_main ? &piix4_smbus_algorithm_sb800 : &smbus_algorithm; @@ -838,6 +937,7 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, return -ENOMEM; } + adapdata->mmio_cfg.use_mmio = piix4_sb800_use_mmio(dev); adapdata->smba = smba; adapdata->sb800_main = sb800_main; adapdata->port = port << piix4_port_shift_sb800; @@ -846,6 +946,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); @@ -859,6 +965,14 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, return retval; } + /* + * The AUX bus can not be probed as on some platforms it reports all + * devices present and all reads return "0". + * This would allow the ee1004 to be probed incorrectly. + */ + if (port == 0) + i2c_register_spd_write_enable(adap); + *padap = adap; return 0; } @@ -870,8 +984,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) @@ -900,15 +1025,20 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) { int retval; bool is_sb800 = false; + bool is_asf = false; + acpi_status status; + acpi_handle handle; 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 || + dev->vendor == PCI_VENDOR_ID_HYGON) { bool notify_imc = false; is_sb800 = true; - if (dev->vendor == PCI_VENDOR_ID_AMD && + if ((dev->vendor == PCI_VENDOR_ID_AMD || + dev->vendor == PCI_VENDOR_ID_HYGON) && dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) { u8 imc; @@ -940,10 +1070,11 @@ 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; + piix4_adapter_count = 1; } /* Check for auxiliary SMBus on some AMD chipsets */ @@ -959,15 +1090,22 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) } } + status = acpi_get_handle(NULL, (acpi_string)SB800_ASF_ACPI_PATH, &handle); + if (ACPI_SUCCESS(status)) + is_asf = true; + if (dev->vendor == PCI_VENDOR_ID_AMD && - dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) { - retval = piix4_setup_sb800(dev, id, 1); + (dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS || + dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS)) { + /* Do not setup AUX port if ASF is enabled */ + if (!is_asf) + retval = piix4_setup_sb800(dev, id, 1); } 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); } @@ -990,7 +1128,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]) { @@ -1014,7 +1152,7 @@ static struct pci_driver piix4_driver = { module_pci_driver(piix4_driver); -MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and " - "Philip Edelbrock <phil@netroedge.com>"); +MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); +MODULE_AUTHOR("Philip Edelbrock <phil@netroedge.com>"); MODULE_DESCRIPTION("PIIX4 SMBus driver"); MODULE_LICENSE("GPL"); |
