Skip to content

Commit

Permalink
i2c: Check for ACPI resource conflicts
Browse files Browse the repository at this point in the history
Check for ACPI resource conflicts in i2c bus drivers. I've included
all recent SMBus master drivers for PC hardware.

I've voluntarily left out:
* Drivers that don't run on PCs: they can't conflict with ACPI.
* Bit-banged bus device drivers: it's very unlikely that ACPI would
  deal with such buses.

Signed-off-by: Jean Delvare <jdelvare@suse.de>
  • Loading branch information
Jean Delvare authored and Jean Delvare committed Jul 14, 2008
1 parent 2373c18 commit 54fb4a0
Show file tree
Hide file tree
Showing 13 changed files with 67 additions and 0 deletions.
6 changes: 6 additions & 0 deletions drivers/i2c/busses/i2c-ali1535.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#include <linux/ioport.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <asm/io.h>


Expand Down Expand Up @@ -159,6 +160,11 @@ static int ali1535_setup(struct pci_dev *dev)
goto exit;
}

retval = acpi_check_region(ali1535_smba, ALI1535_SMB_IOSIZE,
ali1535_driver.name);
if (retval)
goto exit;

if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE,
ali1535_driver.name)) {
dev_err(&dev->dev, "ALI1535_smb region 0x%x already in use!\n",
Expand Down
5 changes: 5 additions & 0 deletions drivers/i2c/busses/i2c-ali1563.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/i2c.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/acpi.h>

#define ALI1563_MAX_TIMEOUT 500
#define ALI1563_SMBBA 0x80
Expand Down Expand Up @@ -356,6 +357,10 @@ static int __devinit ali1563_setup(struct pci_dev * dev)
}
}

if (acpi_check_region(ali1563_smba, ALI1563_SMB_IOSIZE,
ali1563_pci_driver.name))
goto Err;

if (!request_region(ali1563_smba, ALI1563_SMB_IOSIZE,
ali1563_pci_driver.name)) {
dev_err(&dev->dev, "Could not allocate I/O space at 0x%04x\n",
Expand Down
5 changes: 5 additions & 0 deletions drivers/i2c/busses/i2c-ali15x3.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <asm/io.h>

/* ALI15X3 SMBus address offsets */
Expand Down Expand Up @@ -166,6 +167,10 @@ static int ali15x3_setup(struct pci_dev *ALI15X3_dev)
if(force_addr)
ali15x3_smba = force_addr & ~(ALI15X3_SMB_IOSIZE - 1);

if (acpi_check_region(ali15x3_smba, ALI15X3_SMB_IOSIZE,
ali15x3_driver.name))
return -EBUSY;

if (!request_region(ali15x3_smba, ALI15X3_SMB_IOSIZE,
ali15x3_driver.name)) {
dev_err(&ALI15X3_dev->dev,
Expand Down
6 changes: 6 additions & 0 deletions drivers/i2c/busses/i2c-amd756.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include <linux/ioport.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <asm/io.h>

/* AMD756 SMBus address offsets */
Expand Down Expand Up @@ -368,6 +369,11 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
amd756_ioport += SMB_ADDR_OFFSET;
}

error = acpi_check_region(amd756_ioport, SMB_IOSIZE,
amd756_driver.name);
if (error)
return error;

if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) {
dev_err(&pdev->dev, "SMB region 0x%x already in use!\n",
amd756_ioport);
Expand Down
5 changes: 5 additions & 0 deletions drivers/i2c/busses/i2c-amd8111.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/acpi.h>
#include <asm/io.h>

MODULE_LICENSE("GPL");
Expand Down Expand Up @@ -374,6 +375,10 @@ static int __devinit amd8111_probe(struct pci_dev *dev,
smbus->base = pci_resource_start(dev, 0);
smbus->size = pci_resource_len(dev, 0);

error = acpi_check_resource_conflict(&dev->resource[0]);
if (error)
goto out_kfree;

if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) {
error = -EBUSY;
goto out_kfree;
Expand Down
5 changes: 5 additions & 0 deletions drivers/i2c/busses/i2c-i801.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/acpi.h>
#include <asm/io.h>

/* I801 SMBus address offsets */
Expand Down Expand Up @@ -624,6 +625,10 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
goto exit;
}

err = acpi_check_resource_conflict(&dev->resource[SMBBAR]);
if (err)
goto exit;

err = pci_request_region(dev, SMBBAR, i801_driver.name);
if (err) {
dev_err(&dev->dev, "Failed to request SMBus region "
Expand Down
3 changes: 3 additions & 0 deletions drivers/i2c/busses/i2c-isch.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/acpi.h>

/* SCH SMBus address offsets */
#define SMBHSTCNT (0 + sch_smba)
Expand Down Expand Up @@ -279,6 +280,8 @@ static int __devinit sch_probe(struct pci_dev *dev,
dev_err(&dev->dev, "SMBus base address uninitialized!\n");
return -ENODEV;
}
if (acpi_check_region(sch_smba, SMBIOSIZE, sch_driver.name))
return -EBUSY;
if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) {
dev_err(&dev->dev, "SMBus region 0x%x already in use!\n",
sch_smba);
Expand Down
6 changes: 6 additions & 0 deletions drivers/i2c/busses/i2c-nforce2.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/dmi.h>
#include <linux/acpi.h>
#include <asm/io.h>

MODULE_LICENSE("GPL");
Expand Down Expand Up @@ -343,6 +344,11 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
smbus->size = 64;
}

error = acpi_check_region(smbus->base, smbus->size,
nforce2_driver.name);
if (error)
return -1;

if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) {
dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n",
smbus->base, smbus->base+smbus->size-1, name);
Expand Down
4 changes: 4 additions & 0 deletions drivers/i2c/busses/i2c-piix4.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/dmi.h>
#include <linux/acpi.h>
#include <asm/io.h>


Expand Down Expand Up @@ -168,6 +169,9 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
}
}

if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
return -EBUSY;

if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
piix4_smba);
Expand Down
6 changes: 6 additions & 0 deletions drivers/i2c/busses/i2c-sis5595.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/acpi.h>
#include <asm/io.h>

static int blacklist[] = {
Expand Down Expand Up @@ -174,6 +175,11 @@ static int sis5595_setup(struct pci_dev *SIS5595_dev)

/* NB: We grab just the two SMBus registers here, but this may still
* interfere with ACPI :-( */
retval = acpi_check_region(sis5595_base + SMB_INDEX, 2,
sis5595_driver.name);
if (retval)
return retval;

if (!request_region(sis5595_base + SMB_INDEX, 2,
sis5595_driver.name)) {
dev_err(&SIS5595_dev->dev, "SMBus registers 0x%04x-0x%04x already in use!\n",
Expand Down
6 changes: 6 additions & 0 deletions drivers/i2c/busses/i2c-sis630.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/acpi.h>
#include <asm/io.h>

/* SIS630 SMBus registers */
Expand Down Expand Up @@ -437,6 +438,11 @@ static int sis630_setup(struct pci_dev *sis630_dev)

dev_dbg(&sis630_dev->dev, "ACPI base at 0x%04x\n", acpi_base);

retval = acpi_check_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION,
sis630_driver.name);
if (retval)
goto exit;

/* Everything is happy, let's grab the memory and set things up. */
if (!request_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION,
sis630_driver.name)) {
Expand Down
5 changes: 5 additions & 0 deletions drivers/i2c/busses/i2c-sis96x.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <linux/ioport.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <asm/io.h>

/* base address register in PCI config space */
Expand Down Expand Up @@ -281,6 +282,10 @@ static int __devinit sis96x_probe(struct pci_dev *dev,
dev_info(&dev->dev, "SiS96x SMBus base address: 0x%04x\n",
sis96x_smbus_base);

retval = acpi_check_resource_conflict(&dev->resource[SIS96x_BAR]);
if (retval)
return retval;

/* Everything is happy, let's grab the memory and set things up. */
if (!request_region(sis96x_smbus_base, SMB_IOSIZE,
sis96x_driver.name)) {
Expand Down
5 changes: 5 additions & 0 deletions drivers/i2c/busses/i2c-viapro.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include <linux/ioport.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <asm/io.h>

static struct pci_dev *vt596_pdev;
Expand Down Expand Up @@ -356,6 +357,10 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
}

found:
error = acpi_check_region(vt596_smba, 8, vt596_driver.name);
if (error)
return error;

if (!request_region(vt596_smba, 8, vt596_driver.name)) {
dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n",
vt596_smba);
Expand Down

0 comments on commit 54fb4a0

Please sign in to comment.