diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-piix4.c')
| -rw-r--r-- | drivers/i2c/busses/i2c-piix4.c | 46 | 
1 files changed, 32 insertions, 14 deletions
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index a028617b8f1..a6f54ba27e2 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -22,7 +22,7 @@  	Intel PIIX4, 440MX  	Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100  	ATI IXP200, IXP300, IXP400, SB600, SB700/SP5100, SB800 -	AMD Hudson-2, CZ +	AMD Hudson-2, ML, CZ  	SMSC Victory66     Note: we assume there can only be one device, with one or more @@ -38,7 +38,6 @@  #include <linux/ioport.h>  #include <linux/i2c.h>  #include <linux/slab.h> -#include <linux/init.h>  #include <linux/dmi.h>  #include <linux/acpi.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");  		} else {  			dev_err(&PIIX4_dev->dev, -				"Host SMBus controller not enabled!\n"); +				"SMBus Host Controller not enabled!\n");  			release_region(piix4_smba, SMBIOSIZE);  			return -ENODEV;  		}  	}  	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) -		dev_dbg(&PIIX4_dev->dev, "Using Interrupt SMI# for SMBus.\n"); +		dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus\n");  	else  		dev_err(&PIIX4_dev->dev, "Illegal Interrupt configuration "  			"(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 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 */  	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 */ -	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")) {  		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);  	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, -			"Host SMBus controller not enabled!\n"); +			"SMBus Host Controller not enabled!\n");  		return -ENODEV;  	} -	piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;  	if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))  		return -ENODEV; @@ -277,7 +294,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,  	/* Aux SMBus does not support IRQ information */  	if (aux) {  		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;  	} @@ -292,9 +310,9 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,  	release_region(piix4_smba + i2ccfg_offset, 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 -		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,  		 "SMBus Host Controller at 0x%x, revision %d\n", @@ -522,7 +540,7 @@ static const struct i2c_algorithm smbus_algorithm = {  	.functionality	= piix4_func,  }; -static DEFINE_PCI_DEVICE_TABLE(piix4_ids) = { +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) },  	{ PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3) },  | 
