i2c-stub: Allow user to disable some commands
[safe/jmp/linux-2.6] / drivers / i2c / busses / i2c-sis630.c
index c4cc5ed..68cff7a 100644 (file)
@@ -1,7 +1,4 @@
 /*
-    i2c-sis630.c - Part of lm_sensors, Linux kernel modules for hardware
-              monitoring
-
     Copyright (c) 2002,2003 Alexander Malysh <amalysh@web.de>
 
     This program is free software; you can redistribute it and/or modify
@@ -55,6 +52,7 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
+#include <linux/acpi.h>
 #include <asm/io.h>
 
 /* SIS630 SMBus registers */
@@ -175,7 +173,7 @@ static int sis630_transaction_wait(struct i2c_adapter *adap, int size)
        } while (!(temp & 0x0e) && (timeout++ < MAX_TIMEOUT));
 
        /* If the SMBus is still busy, we give up */
-       if (timeout >= MAX_TIMEOUT) {
+       if (timeout > MAX_TIMEOUT) {
                dev_dbg(&adap->dev, "SMBus Timeout!\n");
                result = -ETIMEDOUT;
        }
@@ -356,7 +354,8 @@ static s32 sis630_access(struct i2c_adapter *adap, u16 addr,
                        size = SIS630_BLOCK_DATA;
                        return sis630_block_data(adap, data, read_write);
                default:
-                       printk("Unsupported SMBus operation\n");
+                       dev_warn(&adap->dev, "Unsupported transaction %d\n",
+                                size);
                        return -EOPNOTSUPP;
        }
 
@@ -378,8 +377,6 @@ static s32 sis630_access(struct i2c_adapter *adap, u16 addr,
                case SIS630_WORD_DATA:
                        data->word = sis630_read(SMB_BYTE) + (sis630_read(SMB_BYTE + 1) << 8);
                        break;
-               default:
-                       return -EOPNOTSUPP;
        }
 
        return 0;
@@ -392,7 +389,7 @@ static u32 sis630_func(struct i2c_adapter *adapter)
                I2C_FUNC_SMBUS_BLOCK_DATA;
 }
 
-static int sis630_setup(struct pci_dev *sis630_dev)
+static int __devinit sis630_setup(struct pci_dev *sis630_dev)
 {
        unsigned char b;
        struct pci_dev *dummy = NULL;
@@ -438,6 +435,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)) {
@@ -462,8 +464,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 
 static struct i2c_adapter sis630_adapter = {
        .owner          = THIS_MODULE,
-       .id             = I2C_HW_SMBUS_SIS630,
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .algo           = &smbus_algorithm,
 };
 
@@ -485,8 +486,8 @@ static int __devinit sis630_probe(struct pci_dev *dev, const struct pci_device_i
        /* set up the sysfs linkage to our parent device */
        sis630_adapter.dev.parent = &dev->dev;
 
-       sprintf(sis630_adapter.name, "SMBus SIS630 adapter at %04x",
-               acpi_base + SMB_STS);
+       snprintf(sis630_adapter.name, sizeof(sis630_adapter.name),
+                "SMBus SIS630 adapter at %04x", acpi_base + SMB_STS);
 
        return i2c_add_adapter(&sis630_adapter);
 }