|
@@ -22,7 +22,7 @@
|
|
Intel PIIX4, 440MX
|
|
Intel PIIX4, 440MX
|
|
Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
|
|
Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
|
|
ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800
|
|
ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800
|
|
- AMD Hudson-2, CZ
|
|
|
|
|
|
+ AMD Hudson-2, ML, CZ
|
|
SMSC Victory66
|
|
SMSC Victory66
|
|
|
|
|
|
Note: we assume there can only be one device, with one or more
|
|
Note: we assume there can only be one device, with one or more
|
|
@@ -38,7 +38,6 @@
|
|
#include <linux/ioport.h>
|
|
#include <linux/ioport.h>
|
|
#include <linux/i2c.h>
|
|
#include <linux/i2c.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/slab.h>
|
|
-#include <linux/init.h>
|
|
|
|
#include <linux/dmi.h>
|
|
#include <linux/dmi.h>
|
|
#include <linux/acpi.h>
|
|
#include <linux/acpi.h>
|
|
#include <linux/io.h>
|
|
#include <linux/io.h>
|
|
@@ -208,16 +207,16 @@ static int piix4_setup(struct pci_dev *PIIX4_dev,
|
|
"WARNING: SMBus interface has been FORCEFULLY ENABLED!\n");
|
|
"WARNING: SMBus interface has been FORCEFULLY ENABLED!\n");
|
|
} else {
|
|
} else {
|
|
dev_err(&PIIX4_dev->dev,
|
|
dev_err(&PIIX4_dev->dev,
|
|
- "Host SMBus controller not enabled!\n");
|
|
|
|
|
|
+ "SMBus Host Controller not enabled!\n");
|
|
release_region(piix4_smba, SMBIOSIZE);
|
|
release_region(piix4_smba, SMBIOSIZE);
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (((temp & 0x0E) == 8) || ((temp & 0x0E) == 2))
|
|
if (((temp & 0x0E) == 8) || ((temp & 0x0E) == 2))
|
|
- dev_dbg(&PIIX4_dev->dev, "Using Interrupt 9 for SMBus.\n");
|
|
|
|
|
|
+ dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus\n");
|
|
else if ((temp & 0x0E) == 0)
|
|
else if ((temp & 0x0E) == 0)
|
|
- dev_dbg(&PIIX4_dev->dev, "Using Interrupt SMI# for SMBus.\n");
|
|
|
|
|
|
+ dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus\n");
|
|
else
|
|
else
|
|
dev_err(&PIIX4_dev->dev, "Illegal Interrupt configuration "
|
|
dev_err(&PIIX4_dev->dev, "Illegal Interrupt configuration "
|
|
"(or code out of date)!\n");
|
|
"(or code out of date)!\n");
|
|
@@ -235,7 +234,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
|
|
{
|
|
{
|
|
unsigned short piix4_smba;
|
|
unsigned short piix4_smba;
|
|
unsigned short smba_idx = 0xcd6;
|
|
unsigned short smba_idx = 0xcd6;
|
|
- u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en;
|
|
|
|
|
|
+ u8 smba_en_lo, smba_en_hi, smb_en, smb_en_status;
|
|
|
|
+ u8 i2ccfg, i2ccfg_offset = 0x10;
|
|
|
|
|
|
/* SB800 and later SMBus does not support forcing address */
|
|
/* SB800 and later SMBus does not support forcing address */
|
|
if (force || force_addr) {
|
|
if (force || force_addr) {
|
|
@@ -245,7 +245,15 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
|
|
}
|
|
}
|
|
|
|
|
|
/* Determine the address of the SMBus areas */
|
|
/* Determine the address of the SMBus areas */
|
|
- smb_en = (aux) ? 0x28 : 0x2c;
|
|
|
|
|
|
+ if ((PIIX4_dev->vendor == PCI_VENDOR_ID_AMD &&
|
|
|
|
+ PIIX4_dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS &&
|
|
|
|
+ PIIX4_dev->revision >= 0x41) ||
|
|
|
|
+ (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD &&
|
|
|
|
+ PIIX4_dev->device == 0x790b &&
|
|
|
|
+ PIIX4_dev->revision >= 0x49))
|
|
|
|
+ smb_en = 0x00;
|
|
|
|
+ else
|
|
|
|
+ smb_en = (aux) ? 0x28 : 0x2c;
|
|
|
|
|
|
if (!request_region(smba_idx, 2, "smba_idx")) {
|
|
if (!request_region(smba_idx, 2, "smba_idx")) {
|
|
dev_err(&PIIX4_dev->dev, "SMBus base address index region "
|
|
dev_err(&PIIX4_dev->dev, "SMBus base address index region "
|
|
@@ -258,13 +266,22 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
|
|
smba_en_hi = inb_p(smba_idx + 1);
|
|
smba_en_hi = inb_p(smba_idx + 1);
|
|
release_region(smba_idx, 2);
|
|
release_region(smba_idx, 2);
|
|
|
|
|
|
- if ((smba_en_lo & 1) == 0) {
|
|
|
|
|
|
+ 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,
|
|
dev_err(&PIIX4_dev->dev,
|
|
- "Host SMBus controller not enabled!\n");
|
|
|
|
|
|
+ "SMBus Host Controller not enabled!\n");
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
}
|
|
}
|
|
|
|
|
|
- piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
|
|
|
|
if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
|
|
if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
|
|
|
|
@@ -277,7 +294,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
|
|
/* Aux SMBus does not support IRQ information */
|
|
/* Aux SMBus does not support IRQ information */
|
|
if (aux) {
|
|
if (aux) {
|
|
dev_info(&PIIX4_dev->dev,
|
|
dev_info(&PIIX4_dev->dev,
|
|
- "SMBus Host Controller at 0x%x\n", piix4_smba);
|
|
|
|
|
|
+ "Auxiliary SMBus Host Controller at 0x%x\n",
|
|
|
|
+ piix4_smba);
|
|
return piix4_smba;
|
|
return piix4_smba;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -292,9 +310,9 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
|
|
release_region(piix4_smba + i2ccfg_offset, 1);
|
|
release_region(piix4_smba + i2ccfg_offset, 1);
|
|
|
|
|
|
if (i2ccfg & 1)
|
|
if (i2ccfg & 1)
|
|
- dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus.\n");
|
|
|
|
|
|
+ dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus\n");
|
|
else
|
|
else
|
|
- dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus.\n");
|
|
|
|
|
|
+ dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus\n");
|
|
|
|
|
|
dev_info(&PIIX4_dev->dev,
|
|
dev_info(&PIIX4_dev->dev,
|
|
"SMBus Host Controller at 0x%x, revision %d\n",
|
|
"SMBus Host Controller at 0x%x, revision %d\n",
|