Merge branch 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 15 Jul 2008 18:16:05 +0000 (11:16 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 15 Jul 2008 18:16:05 +0000 (11:16 -0700)
* 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6: (56 commits)
  i2c: Add detection capability to new-style drivers
  i2c: Call client_unregister for new-style devices too
  i2c: Clean up old chip drivers
  i2c-ibm_iic: Register child nodes
  i2c: New-style EEPROM driver using device IDs
  i2c: Export the i2c_bus_type symbol
  i2c-au1550: Fix PM support
  i2c-dev: Delete empty detach_client callback
  i2c: Drop stray references to lm_sensors
  i2c: Check for ACPI resource conflicts
  i2c-ocores: basic PM support
  i2c-sibyte: SWARM I2C board initialization
  i2c-i801: Fix handling of error conditions
  i2c-i801: Rename local variable temp to status
  i2c-i801: Properly report bus arbitration loss
  i2c-i801: Remove verbose debugging messages
  i2c-algo-pcf: Drop unused struct members
  i2c-algo-pcf: Multi-master lost-arbitration improvement
  i2c: Deprecate the legacy gpio drivers
  i2c-pxa: Initialize early
  ...

72 files changed:
Documentation/feature-removal-schedule.txt
Documentation/i2c/busses/i2c-i810 [deleted file]
Documentation/i2c/busses/i2c-prosavage [deleted file]
Documentation/i2c/busses/i2c-savage4 [deleted file]
Documentation/i2c/fault-codes [new file with mode: 0644]
Documentation/i2c/smbus-protocol
Documentation/i2c/writing-clients
MAINTAINERS
arch/mips/sibyte/swarm/Makefile
arch/mips/sibyte/swarm/swarm-i2c.c [new file with mode: 0644]
drivers/i2c/algos/i2c-algo-bit.c
drivers/i2c/algos/i2c-algo-pca.c
drivers/i2c/algos/i2c-algo-pcf.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-ali1535.c
drivers/i2c/busses/i2c-ali1563.c
drivers/i2c/busses/i2c-ali15x3.c
drivers/i2c/busses/i2c-amd756-s4882.c
drivers/i2c/busses/i2c-amd756.c
drivers/i2c/busses/i2c-amd8111.c
drivers/i2c/busses/i2c-au1550.c
drivers/i2c/busses/i2c-cpm.c [new file with mode: 0644]
drivers/i2c/busses/i2c-davinci.c
drivers/i2c/busses/i2c-elektor.c
drivers/i2c/busses/i2c-gpio.c
drivers/i2c/busses/i2c-hydra.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-i810.c [deleted file]
drivers/i2c/busses/i2c-ibm_iic.c
drivers/i2c/busses/i2c-iop3xx.c
drivers/i2c/busses/i2c-isch.c [new file with mode: 0644]
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-nforce2-s4985.c [new file with mode: 0644]
drivers/i2c/busses/i2c-nforce2.c
drivers/i2c/busses/i2c-ocores.c
drivers/i2c/busses/i2c-pasemi.c
drivers/i2c/busses/i2c-pca-platform.c
drivers/i2c/busses/i2c-piix4.c
drivers/i2c/busses/i2c-pmcmsp.c
drivers/i2c/busses/i2c-prosavage.c [deleted file]
drivers/i2c/busses/i2c-pxa.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/busses/i2c-savage4.c [deleted file]
drivers/i2c/busses/i2c-sibyte.c
drivers/i2c/busses/i2c-sis5595.c
drivers/i2c/busses/i2c-sis630.c
drivers/i2c/busses/i2c-sis96x.c
drivers/i2c/busses/i2c-stub.c
drivers/i2c/busses/i2c-taos-evm.c
drivers/i2c/busses/i2c-via.c
drivers/i2c/busses/i2c-viapro.c
drivers/i2c/busses/i2c-voodoo3.c
drivers/i2c/busses/scx200_acb.c
drivers/i2c/chips/Kconfig
drivers/i2c/chips/Makefile
drivers/i2c/chips/at24.c [new file with mode: 0644]
drivers/i2c/chips/eeprom.c
drivers/i2c/chips/max6875.c
drivers/i2c/chips/pca9539.c
drivers/i2c/chips/pcf8574.c
drivers/i2c/chips/pcf8591.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-dev.c
drivers/video/fb_ddc.c
drivers/video/intelfb/intelfb_i2c.c
drivers/video/matrox/i2c-matroxfb.c
include/linux/i2c-algo-pcf.h
include/linux/i2c-id.h
include/linux/i2c.h
include/linux/i2c/at24.h [new file with mode: 0644]

index 46ece3f..65a1482 100644 (file)
@@ -222,13 +222,6 @@ Who:       Thomas Gleixner <tglx@linutronix.de>
 
 ---------------------------
 
-What:  i2c-i810, i2c-prosavage and i2c-savage4
-When:  May 2008
-Why:   These drivers are superseded by i810fb, intelfb and savagefb.
-Who:   Jean Delvare <khali@linux-fr.org>
-
----------------------------
-
 What (Why):
        - include/linux/netfilter_ipv4/ipt_TOS.h ipt_tos.h header files
          (superseded by xt_TOS/xt_tos target & match)
diff --git a/Documentation/i2c/busses/i2c-i810 b/Documentation/i2c/busses/i2c-i810
deleted file mode 100644 (file)
index 778210e..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-Kernel driver i2c-i810
-
-Supported adapters:
-  * Intel 82810, 82810-DC100, 82810E, and 82815 (GMCH)
-  * Intel 82845G (GMCH)
-
-Authors: 
-       Frodo Looijaard <frodol@dds.nl>, 
-       Philip Edelbrock <phil@netroedge.com>,
-        Kyösti Mälkki <kmalkki@cc.hut.fi>,
-       Ralph Metzler <rjkm@thp.uni-koeln.de>,
-       Mark D. Studebaker <mdsxyz123@yahoo.com>
-
-Main contact: Mark Studebaker <mdsxyz123@yahoo.com>
-
-Description 
------------ 
-
-WARNING: If you have an '810' or '815' motherboard, your standard I2C
-temperature sensors are most likely on the 801's I2C bus. You want the
-i2c-i801 driver for those, not this driver.
-
-Now for the i2c-i810...
-
-The GMCH chip contains two I2C interfaces.
-
-The first interface is used for DDC (Data Display Channel) which is a
-serial channel through the VGA monitor connector to a DDC-compliant
-monitor. This interface is defined by the Video Electronics Standards
-Association (VESA). The standards are available for purchase at
-http://www.vesa.org .
-
-The second interface is a general-purpose I2C bus. It may be connected to a
-TV-out chip such as the BT869 or possibly to a digital flat-panel display.
-
-Features
--------- 
-
-Both busses use the i2c-algo-bit driver for 'bit banging'
-and support for specific transactions is provided by i2c-algo-bit.
-
-Issues
-------
-
-If you enable bus testing in i2c-algo-bit (insmod i2c-algo-bit bit_test=1),
-the test may fail; if so, the i2c-i810 driver won't be inserted. However,
-we think this has been fixed.
diff --git a/Documentation/i2c/busses/i2c-prosavage b/Documentation/i2c/busses/i2c-prosavage
deleted file mode 100644 (file)
index 7036879..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-Kernel driver i2c-prosavage
-
-Supported adapters:
-       
-       S3/VIA KM266/VT8375 aka ProSavage8 
-       S3/VIA KM133/VT8365 aka Savage4 
-
-Author: Henk Vergonet <henk@god.dyndns.org>
-
-Description
------------
-
-The Savage4 chips contain two I2C interfaces (aka a I2C 'master' or
-'host'). 
-
-The first interface is used for DDC (Data Display Channel) which is a
-serial channel through the VGA monitor connector to a DDC-compliant
-monitor. This interface is defined by the Video Electronics Standards
-Association (VESA). The standards are available for purchase at
-http://www.vesa.org . The second interface is a general-purpose I2C bus.
-
-Usefull for gaining access to the TV Encoder chips.
-
diff --git a/Documentation/i2c/busses/i2c-savage4 b/Documentation/i2c/busses/i2c-savage4
deleted file mode 100644 (file)
index 6ecceab..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-Kernel driver i2c-savage4
-
-Supported adapters:
-  * Savage4
-  * Savage2000
-
-Authors: 
-       Alexander Wold <awold@bigfoot.com>,
-       Mark D. Studebaker <mdsxyz123@yahoo.com> 
-
-Description
------------
-
-The Savage4 chips contain two I2C interfaces (aka a I2C 'master'
-or 'host'). 
-
-The first interface is used for DDC (Data Display Channel) which is a
-serial channel through the VGA monitor connector to a DDC-compliant
-monitor. This interface is defined by the Video Electronics Standards
-Association (VESA). The standards are available for purchase at
-http://www.vesa.org . The DDC bus is not yet supported because its register
-is not directly memory-mapped.
-
-The second interface is a general-purpose I2C bus. This is the only
-interface supported by the driver at the moment.
-
diff --git a/Documentation/i2c/fault-codes b/Documentation/i2c/fault-codes
new file mode 100644 (file)
index 0000000..045765c
--- /dev/null
@@ -0,0 +1,127 @@
+This is a summary of the most important conventions for use of fault
+codes in the I2C/SMBus stack.
+
+
+A "Fault" is not always an "Error"
+----------------------------------
+Not all fault reports imply errors; "page faults" should be a familiar
+example.  Software often retries idempotent operations after transient
+faults.  There may be fancier recovery schemes that are appropriate in
+some cases, such as re-initializing (and maybe resetting).  After such
+recovery, triggered by a fault report, there is no error.
+
+In a similar way, sometimes a "fault" code just reports one defined
+result for an operation ... it doesn't indicate that anything is wrong
+at all, just that the outcome wasn't on the "golden path".
+
+In short, your I2C driver code may need to know these codes in order
+to respond correctly.  Other code may need to rely on YOUR code reporting
+the right fault code, so that it can (in turn) behave correctly.
+
+
+I2C and SMBus fault codes
+-------------------------
+These are returned as negative numbers from most calls, with zero or
+some positive number indicating a non-fault return.  The specific
+numbers associated with these symbols differ between architectures,
+though most Linux systems use <asm-generic/errno*.h> numbering.
+
+Note that the descriptions here are not exhaustive.  There are other
+codes that may be returned, and other cases where these codes should
+be returned.  However, drivers should not return other codes for these
+cases (unless the hardware doesn't provide unique fault reports).
+
+Also, codes returned by adapter probe methods follow rules which are
+specific to their host bus (such as PCI, or the platform bus).
+
+
+EAGAIN
+       Returned by I2C adapters when they lose arbitration in master
+       transmit mode:  some other master was transmitting different
+       data at the same time.
+
+       Also returned when trying to invoke an I2C operation in an
+       atomic context, when some task is already using that I2C bus
+       to execute some other operation.
+
+EBADMSG
+       Returned by SMBus logic when an invalid Packet Error Code byte
+       is received.  This code is a CRC covering all bytes in the
+       transaction, and is sent before the terminating STOP.  This
+       fault is only reported on read transactions; the SMBus slave
+       may have a way to report PEC mismatches on writes from the
+       host.  Note that even if PECs are in use, you should not rely
+       on these as the only way to detect incorrect data transfers.
+
+EBUSY
+       Returned by SMBus adapters when the bus was busy for longer
+       than allowed.  This usually indicates some device (maybe the
+       SMBus adapter) needs some fault recovery (such as resetting),
+       or that the reset was attempted but failed.
+
+EINVAL
+       This rather vague error means an invalid parameter has been
+       detected before any I/O operation was started.  Use a more
+       specific fault code when you can.
+
+       One example would be a driver trying an SMBus Block Write
+       with block size outside the range of 1-32 bytes.
+
+EIO
+       This rather vague error means something went wrong when
+       performing an I/O operation.  Use a more specific fault
+       code when you can.
+
+ENODEV
+       Returned by driver probe() methods.  This is a bit more
+       specific than ENXIO, implying the problem isn't with the
+       address, but with the device found there.  Driver probes
+       may verify the device returns *correct* responses, and
+       return this as appropriate.  (The driver core will warn
+       about probe faults other than ENXIO and ENODEV.)
+
+ENOMEM
+       Returned by any component that can't allocate memory when
+       it needs to do so.
+
+ENXIO
+       Returned by I2C adapters to indicate that the address phase
+       of a transfer didn't get an ACK.  While it might just mean
+       an I2C device was temporarily not responding, usually it
+       means there's nothing listening at that address.
+
+       Returned by driver probe() methods to indicate that they
+       found no device to bind to.  (ENODEV may also be used.)
+
+EOPNOTSUPP
+       Returned by an adapter when asked to perform an operation
+       that it doesn't, or can't, support.
+
+       For example, this would be returned when an adapter that
+       doesn't support SMBus block transfers is asked to execute
+       one.  In that case, the driver making that request should
+       have verified that functionality was supported before it
+       made that block transfer request.
+
+       Similarly, if an I2C adapter can't execute all legal I2C
+       messages, it should return this when asked to perform a
+       transaction it can't.  (These limitations can't be seen in
+       the adapter's functionality mask, since the assumption is
+       that if an adapter supports I2C it supports all of I2C.)
+
+EPROTO
+       Returned when slave does not conform to the relevant I2C
+       or SMBus (or chip-specific) protocol specifications.  One
+       case is when the length of an SMBus block data response
+       (from the SMBus slave) is outside the range 1-32 bytes.
+
+ETIMEDOUT
+       This is returned by drivers when an operation took too much
+       time, and was aborted before it completed.
+
+       SMBus adapters may return it when an operation took more
+       time than allowed by the SMBus specification; for example,
+       when a slave stretches clocks too far.  I2C has no such
+       timeouts, but it's normal for I2C adapters to impose some
+       arbitrary limits (much longer than SMBus!) too.
+
index 03f08fb..24bfb65 100644 (file)
@@ -42,8 +42,8 @@ Count (8 bits): A data byte containing the length of a block operation.
 [..]: Data sent by I2C device, as opposed to data sent by the host adapter.
 
 
-SMBus Quick Command:  i2c_smbus_write_quick()
-=============================================
+SMBus Quick Command
+===================
 
 This sends a single bit to the device, at the place of the Rd/Wr bit.
 
index d4cd412..6b61b3a 100644 (file)
@@ -44,6 +44,10 @@ static struct i2c_driver foo_driver = {
        .id_table       = foo_ids,
        .probe          = foo_probe,
        .remove         = foo_remove,
+       /* if device autodetection is needed: */
+       .class          = I2C_CLASS_SOMETHING,
+       .detect         = foo_detect,
+       .address_data   = &addr_data,
 
        /* else, driver uses "legacy" binding model: */
        .attach_adapter = foo_attach_adapter,
@@ -217,6 +221,31 @@ in the I2C bus driver. You may want to save the returned i2c_client
 reference for later use.
 
 
+Device Detection (Standard driver model)
+----------------------------------------
+
+Sometimes you do not know in advance which I2C devices are connected to
+a given I2C bus.  This is for example the case of hardware monitoring
+devices on a PC's SMBus.  In that case, you may want to let your driver
+detect supported devices automatically.  This is how the legacy model
+was working, and is now available as an extension to the standard
+driver model (so that we can finally get rid of the legacy model.)
+
+You simply have to define a detect callback which will attempt to
+identify supported devices (returning 0 for supported ones and -ENODEV
+for unsupported ones), a list of addresses to probe, and a device type
+(or class) so that only I2C buses which may have that type of device
+connected (and not otherwise enumerated) will be probed.  The i2c
+core will then call you back as needed and will instantiate a device
+for you for every successful detection.
+
+Note that this mechanism is purely optional and not suitable for all
+devices.  You need some reliable way to identify the supported devices
+(typically using device-specific, dedicated identification registers),
+otherwise misdetections are likely to occur and things can get wrong
+quickly.
+
+
 Device Deletion (Standard driver model)
 ---------------------------------------
 
@@ -569,7 +598,6 @@ SMBus communication
   in terms of it. Never use this function directly!
 
 
-  extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value);
   extern s32 i2c_smbus_read_byte(struct i2c_client * client);
   extern s32 i2c_smbus_write_byte(struct i2c_client * client, u8 value);
   extern s32 i2c_smbus_read_byte_data(struct i2c_client * client, u8 command);
@@ -578,30 +606,31 @@ SMBus communication
   extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command);
   extern s32 i2c_smbus_write_word_data(struct i2c_client * client,
                                        u8 command, u16 value);
+  extern s32 i2c_smbus_read_block_data(struct i2c_client * client,
+                                       u8 command, u8 *values);
   extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
                                         u8 command, u8 length,
                                         u8 *values);
   extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
                                            u8 command, u8 length, u8 *values);
-
-These ones were removed in Linux 2.6.10 because they had no users, but could
-be added back later if needed:
-
-  extern s32 i2c_smbus_read_block_data(struct i2c_client * client,
-                                       u8 command, u8 *values);
   extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
                                             u8 command, u8 length,
                                             u8 *values);
+
+These ones were removed from i2c-core because they had no users, but could
+be added back later if needed:
+
+  extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value);
   extern s32 i2c_smbus_process_call(struct i2c_client * client,
                                     u8 command, u16 value);
   extern s32 i2c_smbus_block_process_call(struct i2c_client *client,
                                           u8 command, u8 length,
                                           u8 *values)
 
-All these transactions return -1 on failure. The 'write' transactions 
-return 0 on success; the 'read' transactions return the read value, except 
-for read_block, which returns the number of values read. The block buffers 
-need not be longer than 32 bytes.
+All these transactions return a negative errno value on failure. The 'write'
+transactions return 0 on success; the 'read' transactions return the read
+value, except for block transactions, which return the number of values
+read. The block buffers need not be longer than 32 bytes.
 
 You can read the file `smbus-protocol' for more information about the
 actual SMBus protocol.
index 1528e58..6198fa3 100644 (file)
@@ -1686,6 +1686,13 @@ L:       linuxppc-embedded@ozlabs.org
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
+FREESCALE I2C CPM DRIVER
+P:     Jochen Friedrich
+M:     jochen@scram.de
+L:     linuxppc-dev@ozlabs.org
+L:     i2c@lm-sensors.org
+S:     Maintained
+
 FREESCALE SOC FS_ENET DRIVER
 P:     Pantelis Antoniou
 M:     pantelis.antoniou@gmail.com
index 1775755..255d692 100644 (file)
@@ -1,3 +1,4 @@
 obj-y                          := setup.o rtc_xicor1241.o rtc_m41t81.o
 
+obj-$(CONFIG_I2C_BOARDINFO)    += swarm-i2c.o
 obj-$(CONFIG_KGDB)             += dbg_io.o
diff --git a/arch/mips/sibyte/swarm/swarm-i2c.c b/arch/mips/sibyte/swarm/swarm-i2c.c
new file mode 100644 (file)
index 0000000..4282ac9
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *     arch/mips/sibyte/swarm/swarm-i2c.c
+ *
+ *     Broadcom BCM91250A (SWARM), etc. I2C platform setup.
+ *
+ *     Copyright (c) 2008  Maciej W. Rozycki
+ *
+ *     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.
+ */
+
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+
+static struct i2c_board_info swarm_i2c_info1[] __initdata = {
+       {
+               I2C_BOARD_INFO("m41t81", 0x68),
+       },
+};
+
+static int __init swarm_i2c_init(void)
+{
+       int err;
+
+       err = i2c_register_board_info(1, swarm_i2c_info1,
+                                     ARRAY_SIZE(swarm_i2c_info1));
+       if (err < 0)
+               printk(KERN_ERR
+                      "swarm-i2c: cannot register board I2C devices\n");
+       return err;
+}
+
+arch_initcall(swarm_i2c_init);
index 3581282..eb8f72c 100644 (file)
@@ -320,7 +320,7 @@ static int try_address(struct i2c_adapter *i2c_adap,
                       unsigned char addr, int retries)
 {
        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
-       int i, ret = -1;
+       int i, ret = 0;
 
        for (i = 0; i <= retries; i++) {
                ret = i2c_outb(i2c_adap, addr);
@@ -508,7 +508,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
                        addr ^= 1;
                ret = try_address(i2c_adap, addr, retries);
                if ((ret != 1) && !nak_ok)
-                       return -EREMOTEIO;
+                       return -ENXIO;
        }
 
        return 0;
index e954a20..d50b329 100644 (file)
@@ -182,7 +182,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
        }
        if (state != 0xf8) {
                dev_dbg(&i2c_adap->dev, "bus is not idle. status is %#04x\n", state);
-               return -EIO;
+               return -EAGAIN;
        }
 
        DEB1("{{{ XFER %d messages\n", num);
index 8907b01..1e328d1 100644 (file)
@@ -78,6 +78,36 @@ static void i2c_stop(struct i2c_algo_pcf_data *adap)
        set_pcf(adap, 1, I2C_PCF_STOP);
 }
 
+static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status)
+{
+       DEB2(printk(KERN_INFO
+               "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n",
+                *status));
+
+       /* Cleanup from LAB -- reset and enable ESO.
+        * This resets the PCF8584; since we've lost the bus, no
+        * further attempts should be made by callers to clean up
+        * (no i2c_stop() etc.)
+        */
+       set_pcf(adap, 1, I2C_PCF_PIN);
+       set_pcf(adap, 1, I2C_PCF_ESO);
+
+       /* We pause for a time period sufficient for any running
+        * I2C transaction to complete -- the arbitration logic won't
+        * work properly until the next START is seen.
+        * It is assumed the bus driver or client has set a proper value.
+        *
+        * REVISIT: should probably use msleep instead of mdelay if we
+        * know we can sleep.
+        */
+       if (adap->lab_mdelay)
+               mdelay(adap->lab_mdelay);
+
+       DEB2(printk(KERN_INFO
+               "i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n",
+               get_pcf(adap, 1)));
+}
+
 static int wait_for_bb(struct i2c_algo_pcf_data *adap) {
 
        int timeout = DEF_TIMEOUT;
@@ -109,23 +139,7 @@ static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) {
                *status = get_pcf(adap, 1);
        }
        if (*status & I2C_PCF_LAB) {
-               DEB2(printk(KERN_INFO 
-                       "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n",
-                        *status));
-               /* Cleanup from LAB-- reset and enable ESO.
-                * This resets the PCF8584; since we've lost the bus, no
-                * further attempts should be made by callers to clean up 
-                * (no i2c_stop() etc.)
-                */
-               set_pcf(adap, 1, I2C_PCF_PIN);
-               set_pcf(adap, 1, I2C_PCF_ESO);
-               /* TODO: we should pause for a time period sufficient for any
-                * running I2C transaction to complete-- the arbitration
-                * logic won't work properly until the next START is seen.
-                */
-               DEB2(printk(KERN_INFO 
-                       "i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n", 
-                       get_pcf(adap,1)));
+               handle_lab(adap, status);
                return(-EINTR);
        }
 #endif
index 48438cc..6ee997b 100644 (file)
@@ -4,6 +4,9 @@
 
 menu "I2C Hardware Bus support"
 
+comment "PC SMBus host controller drivers"
+       depends on PCI
+
 config I2C_ALI1535
        tristate "ALI 1535"
        depends on PCI
@@ -73,94 +76,6 @@ config I2C_AMD8111
          This driver can also be built as a module.  If so, the module
          will be called i2c-amd8111.
 
-config I2C_AT91
-       tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
-       depends on ARCH_AT91 && EXPERIMENTAL && BROKEN
-       help
-         This supports the use of the I2C interface on Atmel AT91
-         processors.
-
-         This driver is BROKEN because the controller which it uses
-         will easily trigger RX overrun and TX underrun errors.  Using
-         low I2C clock rates may partially work around those issues
-         on some systems.  Another serious problem is that there is no
-         documented way to issue repeated START conditions, as needed
-         to support combined I2C messages.  Use the i2c-gpio driver
-         unless your system can cope with those limitations.
-
-config I2C_AU1550
-       tristate "Au1550/Au1200 SMBus interface"
-       depends on SOC_AU1550 || SOC_AU1200
-       help
-         If you say yes to this option, support will be included for the
-         Au1550 and Au1200 SMBus interface.
-
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-au1550.
-
-config I2C_BLACKFIN_TWI
-       tristate "Blackfin TWI I2C support"
-       depends on BLACKFIN
-       help
-         This is the TWI I2C device driver for Blackfin BF522, BF525,
-         BF527, BF534, BF536, BF537 and BF54x. For other Blackfin processors,
-         please don't use this driver.
-
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-bfin-twi.
-
-config I2C_BLACKFIN_TWI_CLK_KHZ
-       int "Blackfin TWI I2C clock (kHz)"
-       depends on I2C_BLACKFIN_TWI
-       range 10 400
-       default 50
-       help
-         The unit of the TWI clock is kHz.
-
-config I2C_DAVINCI
-       tristate "DaVinci I2C driver"
-       depends on ARCH_DAVINCI
-       help
-         Support for TI DaVinci I2C controller driver.
-
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-davinci.
-
-         Please note that this driver might be needed to bring up other
-         devices such as DaVinci NIC.
-         For details please see http://www.ti.com/davinci
-
-config I2C_ELEKTOR
-       tristate "Elektor ISA card"
-       depends on ISA && BROKEN_ON_SMP
-       select I2C_ALGOPCF
-       help
-         This supports the PCF8584 ISA bus I2C adapter.  Say Y if you own
-         such an adapter.
-
-         This support is also available as a module.  If so, the module
-         will be called i2c-elektor.
-
-config I2C_GPIO
-       tristate "GPIO-based bitbanging I2C"
-       depends on GENERIC_GPIO
-       select I2C_ALGOBIT
-       help
-         This is a very simple bitbanging I2C driver utilizing the
-         arch-neutral GPIO API to control the SCL and SDA lines.
-
-config I2C_HYDRA
-       tristate "CHRP Apple Hydra Mac I/O I2C interface"
-       depends on PCI && PPC_CHRP && EXPERIMENTAL
-       select I2C_ALGOBIT
-       help
-         This supports the use of the I2C interface in the Apple Hydra Mac
-         I/O chip on some CHRP machines (e.g. the LongTrail).  Say Y if you
-         have such a machine.
-
-         This support is also available as a module.  If so, the module
-         will be called i2c-hydra.
-
 config I2C_I801
        tristate "Intel 82801 (ICH)"
        depends on PCI
@@ -186,41 +101,15 @@ config I2C_I801
          This driver can also be built as a module.  If so, the module
          will be called i2c-i801.
 
-config I2C_I810
-       tristate "Intel 810/815 (DEPRECATED)"
-       default n
+config I2C_ISCH
+       tristate "Intel SCH SMBus 1.0"
        depends on PCI
-       select I2C_ALGOBIT
-       help
-         If you say yes to this option, support will be included for the Intel
-         810/815 family of mainboard I2C interfaces.  Specifically, the
-         following versions of the chipset are supported:
-           i810AA
-           i810AB
-           i810E
-           i815
-           i845G
-
-         This driver is deprecated in favor of the i810fb and intelfb drivers.
-
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-i810.
-
-config I2C_PXA
-       tristate "Intel PXA2XX I2C adapter (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && ARCH_PXA
        help
-         If you have devices in the PXA I2C bus, say yes to this option.
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-pxa.
+         Say Y here if you want to use SMBus controller on the Intel SCH
+         based systems.
 
-config I2C_PXA_SLAVE
-       bool "Intel PXA2XX I2C Slave comms support"
-       depends on I2C_PXA
-       help
-         Support I2C slave mode communications on the PXA I2C bus.  This
-         is necessary for systems where the PXA may be a target on the
-         I2C bus.
+         This driver can also be built as a module. If so, the module
+         will be called i2c-isch.
 
 config I2C_PIIX4
        tristate "Intel PIIX4 and compatible (ATI/Serverworks/Broadcom/SMSC)"
@@ -247,39 +136,111 @@ config I2C_PIIX4
          This driver can also be built as a module.  If so, the module
          will be called i2c-piix4.
 
-config I2C_IBM_IIC
-       tristate "IBM PPC 4xx on-chip I2C interface"
-       depends on 4xx
+config I2C_NFORCE2
+       tristate "Nvidia nForce2, nForce3 and nForce4"
+       depends on PCI
        help
-         Say Y here if you want to use IIC peripheral found on
-         embedded IBM PPC 4xx based systems.
+         If you say yes to this option, support will be included for the Nvidia
+         nForce2, nForce3 and nForce4 families of mainboard I2C interfaces.
 
          This driver can also be built as a module.  If so, the module
-         will be called i2c-ibm_iic.
+         will be called i2c-nforce2.
 
-config I2C_IOP3XX
-       tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface"
-       depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX
+config I2C_NFORCE2_S4985
+       tristate "SMBus multiplexing on the Tyan S4985"
+       depends on I2C_NFORCE2 && EXPERIMENTAL
        help
-         Say Y here if you want to use the IIC bus controller on
-         the Intel IOPx3xx I/O Processors or IXP4xx Network Processors.
+         Enabling this option will add specific SMBus support for the Tyan
+         S4985 motherboard.  On this 4-CPU board, the SMBus is multiplexed
+         over 4 different channels, where the various memory module EEPROMs
+         live.  Saying yes here will give you access to these in addition
+         to the trunk.
 
          This driver can also be built as a module.  If so, the module
-         will be called i2c-iop3xx.
+         will be called i2c-nforce2-s4985.
 
-config I2C_IXP2000
-       tristate "IXP2000 GPIO-Based I2C Interface (DEPRECATED)"
-       depends on ARCH_IXP2000
+config I2C_SIS5595
+       tristate "SiS 5595"
+       depends on PCI
+       help
+         If you say yes to this option, support will be included for the
+         SiS5595 SMBus (a subset of I2C) interface.
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-sis5595.
+
+config I2C_SIS630
+       tristate "SiS 630/730"
+       depends on PCI
+       help
+         If you say yes to this option, support will be included for the
+         SiS630 and SiS730 SMBus (a subset of I2C) interface.
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-sis630.
+
+config I2C_SIS96X
+       tristate "SiS 96x"
+       depends on PCI
+       help
+         If you say yes to this option, support will be included for the SiS
+         96x SMBus (a subset of I2C) interfaces.  Specifically, the following
+         chipsets are supported:
+           645/961
+           645DX/961
+           645DX/962
+           648/961
+           650/961
+           735
+           745
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-sis96x.
+
+config I2C_VIA
+       tristate "VIA VT82C586B"
+       depends on PCI && EXPERIMENTAL
        select I2C_ALGOBIT
        help
-         Say Y here if you have an Intel IXP2000 (2400, 2800, 2850) based
-         system and are using GPIO lines for an I2C bus.
+         If you say yes to this option, support will be included for the VIA
+          82C586B I2C interface
 
-         This support is also available as a module. If so, the module
-         will be called i2c-ixp2000.
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-via.
 
-         This driver is deprecated and will be dropped soon. Use i2c-gpio
-         instead.
+config I2C_VIAPRO
+       tristate "VIA VT82C596/82C686/82xx and CX700"
+       depends on PCI
+       help
+         If you say yes to this option, support will be included for the VIA
+         VT82C596 and later SMBus interface.  Specifically, the following
+         chipsets are supported:
+           VT82C596A/B
+           VT82C686A/B
+           VT8231
+           VT8233/A
+           VT8235
+           VT8237R/A/S
+           VT8251
+           CX700
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-viapro.
+
+comment "Mac SMBus host controller drivers"
+       depends on PPC_CHRP || PPC_PMAC
+
+config I2C_HYDRA
+       tristate "CHRP Apple Hydra Mac I/O I2C interface"
+       depends on PCI && PPC_CHRP && EXPERIMENTAL
+       select I2C_ALGOBIT
+       help
+         This supports the use of the I2C interface in the Apple Hydra Mac
+         I/O chip on some CHRP machines (e.g. the LongTrail).  Say Y if you
+         have such a machine.
+
+         This support is also available as a module.  If so, the module
+         will be called i2c-hydra.
 
 config I2C_POWERMAC
        tristate "Powermac I2C interface"
@@ -293,95 +254,158 @@ config I2C_POWERMAC
          This support is also available as a module.  If so, the module
          will be called i2c-powermac.
 
-config I2C_MPC
-       tristate "MPC107/824x/85xx/52xx/86xx"
-       depends on PPC32
+comment "I2C system bus drivers (mostly embedded / system-on-chip)"
+
+config I2C_AT91
+       tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
+       depends on ARCH_AT91 && EXPERIMENTAL && BROKEN
        help
-         If you say yes to this option, support will be included for the
-         built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and
-         MPC85xx/MPC8641 family processors. The driver may also work on 52xx
-         family processors, though interrupts are known not to work.
+         This supports the use of the I2C interface on Atmel AT91
+         processors.
 
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-mpc.
+         This driver is BROKEN because the controller which it uses
+         will easily trigger RX overrun and TX underrun errors.  Using
+         low I2C clock rates may partially work around those issues
+         on some systems.  Another serious problem is that there is no
+         documented way to issue repeated START conditions, as needed
+         to support combined I2C messages.  Use the i2c-gpio driver
+         unless your system can cope with those limitations.
 
-config I2C_NFORCE2
-       tristate "Nvidia nForce2, nForce3 and nForce4"
-       depends on PCI
+config I2C_AU1550
+       tristate "Au1550/Au1200 SMBus interface"
+       depends on SOC_AU1550 || SOC_AU1200
        help
-         If you say yes to this option, support will be included for the Nvidia
-         nForce2, nForce3 and nForce4 families of mainboard I2C interfaces.
+         If you say yes to this option, support will be included for the
+         Au1550 and Au1200 SMBus interface.
 
          This driver can also be built as a module.  If so, the module
-         will be called i2c-nforce2.
+         will be called i2c-au1550.
 
-config I2C_OCORES
-       tristate "OpenCores I2C Controller"
-       depends on EXPERIMENTAL
+config I2C_BLACKFIN_TWI
+       tristate "Blackfin TWI I2C support"
+       depends on BLACKFIN
+       depends on !BF561 && !BF531 && !BF532 && !BF533
        help
-         If you say yes to this option, support will be included for the
-         OpenCores I2C controller. For details see
-         http://www.opencores.org/projects.cgi/web/i2c/overview
+         This is the I2C bus driver for Blackfin on-chip TWI interface.
 
          This driver can also be built as a module.  If so, the module
-         will be called i2c-ocores.
+         will be called i2c-bfin-twi.
 
-config I2C_OMAP
-       tristate "OMAP I2C adapter"
-       depends on ARCH_OMAP
-       default y if MACH_OMAP_H3 || MACH_OMAP_OSK
+config I2C_BLACKFIN_TWI_CLK_KHZ
+       int "Blackfin TWI I2C clock (kHz)"
+       depends on I2C_BLACKFIN_TWI
+       range 10 400
+       default 50
        help
-         If you say yes to this option, support will be included for the
-         I2C interface on the Texas Instruments OMAP1/2 family of processors.
-         Like OMAP1510/1610/1710/5912 and OMAP242x.
-         For details see http://www.ti.com/omap.
+         The unit of the TWI clock is kHz.
 
-config I2C_PARPORT
-       tristate "Parallel port adapter"
-       depends on PARPORT
+config I2C_CPM
+       tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)"
+       depends on (CPM1 || CPM2) && OF_I2C
+       help
+         This supports the use of the I2C interface on Freescale
+         processors with CPM1 or CPM2.
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-cpm.
+
+config I2C_DAVINCI
+       tristate "DaVinci I2C driver"
+       depends on ARCH_DAVINCI
+       help
+         Support for TI DaVinci I2C controller driver.
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-davinci.
+
+         Please note that this driver might be needed to bring up other
+         devices such as DaVinci NIC.
+         For details please see http://www.ti.com/davinci
+
+config I2C_GPIO
+       tristate "GPIO-based bitbanging I2C"
+       depends on GENERIC_GPIO
        select I2C_ALGOBIT
        help
-         This supports parallel port I2C adapters such as the ones made by
-         Philips or Velleman, Analog Devices evaluation boards, and more.
-         Basically any adapter using the parallel port as an I2C bus with
-         no extra chipset is supported by this driver, or could be.
+         This is a very simple bitbanging I2C driver utilizing the
+         arch-neutral GPIO API to control the SCL and SDA lines.
 
-         This driver is a replacement for (and was inspired by) an older
-         driver named i2c-philips-par.  The new driver supports more devices,
-         and makes it easier to add support for new devices.
+config I2C_IBM_IIC
+       tristate "IBM PPC 4xx on-chip I2C interface"
+       depends on 4xx
+       help
+         Say Y here if you want to use IIC peripheral found on
+         embedded IBM PPC 4xx based systems.
 
-         An adapter type parameter is now mandatory.  Please read the file
-         Documentation/i2c/busses/i2c-parport for details.
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-ibm_iic.
 
-         Another driver exists, named i2c-parport-light, which doesn't depend
-         on the parport driver.  This is meant for embedded systems. Don't say
-         Y here if you intend to say Y or M there.
+config I2C_IOP3XX
+       tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface"
+       depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX
+       help
+         Say Y here if you want to use the IIC bus controller on
+         the Intel IOPx3xx I/O Processors or IXP4xx Network Processors.
 
-         This support is also available as a module.  If so, the module
-         will be called i2c-parport.
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-iop3xx.
 
-config I2C_PARPORT_LIGHT
-       tristate "Parallel port adapter (light)"
+config I2C_IXP2000
+       tristate "IXP2000 GPIO-Based I2C Interface (DEPRECATED)"
+       depends on ARCH_IXP2000
        select I2C_ALGOBIT
        help
-         This supports parallel port I2C adapters such as the ones made by
-         Philips or Velleman, Analog Devices evaluation boards, and more.
-         Basically any adapter using the parallel port as an I2C bus with
-         no extra chipset is supported by this driver, or could be.
+         Say Y here if you have an Intel IXP2000 (2400, 2800, 2850) based
+         system and are using GPIO lines for an I2C bus.
 
-         This driver is a light version of i2c-parport.  It doesn't depend
-         on the parport driver, and uses direct I/O access instead.  This
-         might be preferred on embedded systems where wasting memory for
-         the clean but heavy parport handling is not an option.  The
-         drawback is a reduced portability and the impossibility to
-         daisy-chain other parallel port devices.
+         This support is also available as a module. If so, the module
+         will be called i2c-ixp2000.
 
-         Don't say Y here if you said Y or M to i2c-parport.  Saying M to
-         both is possible but both modules should not be loaded at the same
-         time.
+         This driver is deprecated and will be dropped soon. Use i2c-gpio
+         instead.
 
-         This support is also available as a module.  If so, the module
-         will be called i2c-parport-light.
+config I2C_MPC
+       tristate "MPC107/824x/85xx/52xx/86xx"
+       depends on PPC32
+       help
+         If you say yes to this option, support will be included for the
+         built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and
+         MPC85xx/MPC8641 family processors. The driver may also work on 52xx
+         family processors, though interrupts are known not to work.
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-mpc.
+
+config I2C_MV64XXX
+       tristate "Marvell mv64xxx I2C Controller"
+       depends on (MV64X60 || PLAT_ORION) && EXPERIMENTAL
+       help
+         If you say yes to this option, support will be included for the
+         built-in I2C interface on the Marvell 64xxx line of host bridges.
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-mv64xxx.
+
+config I2C_OCORES
+       tristate "OpenCores I2C Controller"
+       depends on EXPERIMENTAL
+       help
+         If you say yes to this option, support will be included for the
+         OpenCores I2C controller. For details see
+         http://www.opencores.org/projects.cgi/web/i2c/overview
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-ocores.
+
+config I2C_OMAP
+       tristate "OMAP I2C adapter"
+       depends on ARCH_OMAP
+       default y if MACH_OMAP_H3 || MACH_OMAP_OSK
+       help
+         If you say yes to this option, support will be included for the
+         I2C interface on the Texas Instruments OMAP1/2 family of processors.
+         Like OMAP1510/1610/1710/5912 and OMAP242x.
+         For details see http://www.ti.com/omap.
 
 config I2C_PASEMI
        tristate "PA Semi SMBus interface"
@@ -389,23 +413,31 @@ config I2C_PASEMI
        help
          Supports the PA Semi PWRficient on-chip SMBus interfaces.
 
-config I2C_PROSAVAGE
-       tristate "S3/VIA (Pro)Savage (DEPRECATED)"
-       default n
-       depends on PCI
-       select I2C_ALGOBIT
+config I2C_PNX
+       tristate "I2C bus support for Philips PNX targets"
+       depends on ARCH_PNX4008
        help
-         If you say yes to this option, support will be included for the
-         I2C bus and DDC bus of the S3VIA embedded Savage4 and ProSavage8
-         graphics processors.
-         chipsets supported:
-           S3/VIA KM266/VT8375 aka ProSavage8
-           S3/VIA KM133/VT8365 aka Savage4
+         This driver supports the Philips IP3204 I2C IP block master and/or
+         slave controller
 
-         This driver is deprecated in favor of the savagefb driver.
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-pnx.
 
-         This support is also available as a module.  If so, the module
-         will be called i2c-prosavage.
+config I2C_PXA
+       tristate "Intel PXA2XX I2C adapter (EXPERIMENTAL)"
+       depends on EXPERIMENTAL && ARCH_PXA
+       help
+         If you have devices in the PXA I2C bus, say yes to this option.
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-pxa.
+
+config I2C_PXA_SLAVE
+       bool "Intel PXA2XX I2C Slave comms support"
+       depends on I2C_PXA
+       help
+         Support I2C slave mode communications on the PXA I2C bus.  This
+         is necessary for systems where the PXA may be a target on the
+         I2C bus.
 
 config I2C_S3C2410
        tristate "S3C2410 I2C Driver"
@@ -414,25 +446,24 @@ config I2C_S3C2410
          Say Y here to include support for I2C controller in the
          Samsung S3C2410 based System-on-Chip devices.
 
-config I2C_SAVAGE4
-       tristate "S3 Savage 4 (DEPRECATED)"
-       default n
-       depends on PCI
-       select I2C_ALGOBIT
+config I2C_SH7760
+       tristate "Renesas SH7760 I2C Controller"
+       depends on CPU_SUBTYPE_SH7760
        help
-         If you say yes to this option, support will be included for the
-         S3 Savage 4 I2C interface.
-
-         This driver is deprecated in favor of the savagefb driver.
+         This driver supports the 2 I2C interfaces on the Renesas SH7760.
 
          This driver can also be built as a module.  If so, the module
-         will be called i2c-savage4.
+         will be called i2c-sh7760.
 
-config I2C_SIBYTE
-       tristate "SiByte SMBus interface"
-       depends on SIBYTE_SB1xxx_SOC
+config I2C_SH_MOBILE
+       tristate "SuperH Mobile I2C Controller"
+       depends on SUPERH
        help
-         Supports the SiByte SOC on-chip I2C interfaces (2 channels).
+         If you say yes to this option, support will be included for the
+         built-in I2C interface on the Renesas SH-Mobile processor.
+
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-sh_mobile.
 
 config I2C_SIMTEC
        tristate "Simtec Generic I2C interface"
@@ -446,86 +477,65 @@ config I2C_SIMTEC
          This driver can also be built as a module. If so, the module
          will be called i2c-simtec.
 
-config SCx200_I2C
-       tristate "NatSemi SCx200 I2C using GPIO pins (DEPRECATED)"
-       depends on SCx200_GPIO
+config I2C_VERSATILE
+       tristate "ARM Versatile/Realview I2C bus support"
+       depends on ARCH_VERSATILE || ARCH_REALVIEW
        select I2C_ALGOBIT
        help
-         Enable the use of two GPIO pins of a SCx200 processor as an I2C bus.
-
-         If you don't know what to do here, say N.
+         Say yes if you want to support the I2C serial bus on ARMs Versatile
+         range of platforms.
 
-         This support is also available as a module.  If so, the module
-         will be called scx200_i2c.
+         This driver can also be built as a module.  If so, the module
+         will be called i2c-versatile.
 
-         This driver is deprecated and will be dropped soon. Use i2c-gpio
-         (or scx200_acb) instead.
+comment "External I2C/SMBus adapter drivers"
 
-config SCx200_I2C_SCL
-       int "GPIO pin used for SCL"
-       depends on SCx200_I2C
-       default "12"
+config I2C_PARPORT
+       tristate "Parallel port adapter"
+       depends on PARPORT
+       select I2C_ALGOBIT
        help
-         Enter the GPIO pin number used for the SCL signal.  This value can
-         also be specified with a module parameter.
+         This supports parallel port I2C adapters such as the ones made by
+         Philips or Velleman, Analog Devices evaluation boards, and more.
+         Basically any adapter using the parallel port as an I2C bus with
+         no extra chipset is supported by this driver, or could be.
 
-config SCx200_I2C_SDA
-       int "GPIO pin used for SDA"
-       depends on SCx200_I2C
-       default "13"
-       help
-         Enter the GPIO pin number used for the SSA signal.  This value can
-         also be specified with a module parameter.
+         This driver is a replacement for (and was inspired by) an older
+         driver named i2c-philips-par.  The new driver supports more devices,
+         and makes it easier to add support for new devices.
 
-config SCx200_ACB
-       tristate "Geode ACCESS.bus support"
-       depends on X86_32 && PCI
-       help
-         Enable the use of the ACCESS.bus controllers on the Geode SCx200 and
-         SC1100 processors and the CS5535 and CS5536 Geode companion devices.
+         An adapter type parameter is now mandatory.  Please read the file
+         Documentation/i2c/busses/i2c-parport for details.
 
-         If you don't know what to do here, say N.
+         Another driver exists, named i2c-parport-light, which doesn't depend
+         on the parport driver.  This is meant for embedded systems. Don't say
+         Y here if you intend to say Y or M there.
 
          This support is also available as a module.  If so, the module
-         will be called scx200_acb.
-
-config I2C_SIS5595
-       tristate "SiS 5595"
-       depends on PCI
-       help
-         If you say yes to this option, support will be included for the
-         SiS5595 SMBus (a subset of I2C) interface.
-
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-sis5595.
+         will be called i2c-parport.
 
-config I2C_SIS630
-       tristate "SiS 630/730"
-       depends on PCI
+config I2C_PARPORT_LIGHT
+       tristate "Parallel port adapter (light)"
+       select I2C_ALGOBIT
        help
-         If you say yes to this option, support will be included for the
-         SiS630 and SiS730 SMBus (a subset of I2C) interface.
+         This supports parallel port I2C adapters such as the ones made by
+         Philips or Velleman, Analog Devices evaluation boards, and more.
+         Basically any adapter using the parallel port as an I2C bus with
+         no extra chipset is supported by this driver, or could be.
 
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-sis630.
+         This driver is a light version of i2c-parport.  It doesn't depend
+         on the parport driver, and uses direct I/O access instead.  This
+         might be preferred on embedded systems where wasting memory for
+         the clean but heavy parport handling is not an option.  The
+         drawback is a reduced portability and the impossibility to
+         daisy-chain other parallel port devices.
 
-config I2C_SIS96X
-       tristate "SiS 96x"
-       depends on PCI
-       help
-         If you say yes to this option, support will be included for the SiS
-         96x SMBus (a subset of I2C) interfaces.  Specifically, the following
-         chipsets are supported:
-           645/961
-           645DX/961
-           645DX/962
-           648/961
-           650/961
-           735
-           745
+         Don't say Y here if you said Y or M to i2c-parport.  Saying M to
+         both is possible but both modules should not be loaded at the same
+         time.
 
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-sis96x.
+         This support is also available as a module.  If so, the module
+         will be called i2c-parport-light.
 
 config I2C_TAOS_EVM
        tristate "TAOS evaluation module"
@@ -543,21 +553,8 @@ config I2C_TAOS_EVM
          This support is also available as a module.  If so, the module
          will be called i2c-taos-evm.
 
-config I2C_STUB
-       tristate "I2C/SMBus Test Stub"
-       depends on EXPERIMENTAL && m
-       default 'n'
-       help
-         This module may be useful to developers of SMBus client drivers,
-         especially for certain kinds of sensor chips.
-
-         If you do build this module, be sure to read the notes and warnings
-         in <file:Documentation/i2c/i2c-stub>.
-
-         If you don't know what to do here, definitely say N.
-
 config I2C_TINY_USB
-       tristate "I2C-Tiny-USB"
+       tristate "Tiny-USB adapter"
        depends on USB
        help
          If you say yes to this option, support will be included for the
@@ -567,16 +564,21 @@ config I2C_TINY_USB
          This driver can also be built as a module.  If so, the module
          will be called i2c-tiny-usb.
 
-config I2C_VERSATILE
-       tristate "ARM Versatile/Realview I2C bus support"
-       depends on ARCH_VERSATILE || ARCH_REALVIEW
+comment "Graphics adapter I2C/DDC channel drivers"
+       depends on PCI
+
+config I2C_VOODOO3
+       tristate "Voodoo 3"
+       depends on PCI
        select I2C_ALGOBIT
        help
-         Say yes if you want to support the I2C serial bus on ARMs Versatile
-         range of platforms.
+         If you say yes to this option, support will be included for the
+         Voodoo 3 I2C interface.
 
          This driver can also be built as a module.  If so, the module
-         will be called i2c-versatile.
+         will be called i2c-voodoo3.
+
+comment "Other I2C/SMBus bus drivers"
 
 config I2C_ACORN
        tristate "Acorn IOC/IOMD I2C bus support"
@@ -588,46 +590,16 @@ config I2C_ACORN
 
          If you don't know, say Y.
 
-config I2C_VIA
-       tristate "VIA 82C586B"
-       depends on PCI && EXPERIMENTAL
-       select I2C_ALGOBIT
-       help
-         If you say yes to this option, support will be included for the VIA
-          82C586B I2C interface
-
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-via.
-
-config I2C_VIAPRO
-       tristate "VIA VT82C596/82C686/82xx and CX700"
-       depends on PCI
-       help
-         If you say yes to this option, support will be included for the VIA
-         VT82C596 and later SMBus interface.  Specifically, the following
-         chipsets are supported:
-           VT82C596A/B
-           VT82C686A/B
-           VT8231
-           VT8233/A
-           VT8235
-           VT8237R/A/S
-           VT8251
-           CX700
-
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-viapro.
-
-config I2C_VOODOO3
-       tristate "Voodoo 3"
-       depends on PCI
-       select I2C_ALGOBIT
+config I2C_ELEKTOR
+       tristate "Elektor ISA card"
+       depends on ISA && BROKEN_ON_SMP
+       select I2C_ALGOPCF
        help
-         If you say yes to this option, support will be included for the
-         Voodoo 3 I2C interface.
+         This supports the PCF8584 ISA bus I2C adapter.  Say Y if you own
+         such an adapter.
 
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-voodoo3.
+         This support is also available as a module.  If so, the module
+         will be called i2c-elektor.
 
 config I2C_PCA_ISA
        tristate "PCA9564 on an ISA bus"
@@ -657,26 +629,6 @@ config I2C_PCA_PLATFORM
          This driver can also be built as a module.  If so, the module
          will be called i2c-pca-platform.
 
-config I2C_MV64XXX
-       tristate "Marvell mv64xxx I2C Controller"
-       depends on (MV64X60 || PLAT_ORION) && EXPERIMENTAL
-       help
-         If you say yes to this option, support will be included for the
-         built-in I2C interface on the Marvell 64xxx line of host bridges.
-
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-mv64xxx.
-
-config I2C_PNX
-       tristate "I2C bus support for Philips PNX targets"
-       depends on ARCH_PNX4008
-       help
-         This driver supports the Philips IP3204 I2C IP block master and/or
-         slave controller
-
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-pnx.
-
 config I2C_PMCMSP
        tristate "PMC MSP I2C TWI Controller"
        depends on PMC_MSP
@@ -686,23 +638,66 @@ config I2C_PMCMSP
          This driver can also be built as module. If so, the module
          will be called i2c-pmcmsp.
 
-config I2C_SH7760
-       tristate "Renesas SH7760 I2C Controller"
-       depends on CPU_SUBTYPE_SH7760
+config I2C_SIBYTE
+       tristate "SiByte SMBus interface"
+       depends on SIBYTE_SB1xxx_SOC
        help
-         This driver supports the 2 I2C interfaces on the Renesas SH7760.
+         Supports the SiByte SOC on-chip I2C interfaces (2 channels).
 
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-sh7760.
+config I2C_STUB
+       tristate "I2C/SMBus Test Stub"
+       depends on EXPERIMENTAL && m
+       default 'n'
+       help
+         This module may be useful to developers of SMBus client drivers,
+         especially for certain kinds of sensor chips.
 
-config I2C_SH_MOBILE
-       tristate "SuperH Mobile I2C Controller"
-       depends on SUPERH
+         If you do build this module, be sure to read the notes and warnings
+         in <file:Documentation/i2c/i2c-stub>.
+
+         If you don't know what to do here, definitely say N.
+
+config SCx200_I2C
+       tristate "NatSemi SCx200 I2C using GPIO pins (DEPRECATED)"
+       depends on SCx200_GPIO
+       select I2C_ALGOBIT
        help
-         If you say yes to this option, support will be included for the
-         built-in I2C interface on the Renesas SH-Mobile processor.
+         Enable the use of two GPIO pins of a SCx200 processor as an I2C bus.
 
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-sh_mobile.
+         If you don't know what to do here, say N.
+
+         This support is also available as a module.  If so, the module
+         will be called scx200_i2c.
+
+         This driver is deprecated and will be dropped soon. Use i2c-gpio
+         (or scx200_acb) instead.
+
+config SCx200_I2C_SCL
+       int "GPIO pin used for SCL"
+       depends on SCx200_I2C
+       default "12"
+       help
+         Enter the GPIO pin number used for the SCL signal.  This value can
+         also be specified with a module parameter.
+
+config SCx200_I2C_SDA
+       int "GPIO pin used for SDA"
+       depends on SCx200_I2C
+       default "13"
+       help
+         Enter the GPIO pin number used for the SSA signal.  This value can
+         also be specified with a module parameter.
+
+config SCx200_ACB
+       tristate "Geode ACCESS.bus support"
+       depends on X86_32 && PCI
+       help
+         Enable the use of the ACCESS.bus controllers on the Geode SCx200 and
+         SC1100 processors and the CS5535 and CS5536 Geode companion devices.
+
+         If you don't know what to do here, say N.
+
+         This support is also available as a module.  If so, the module
+         will be called scx200_acb.
 
 endmenu
index e8c882a..97dbfa2 100644 (file)
@@ -2,57 +2,68 @@
 # Makefile for the i2c bus drivers.
 #
 
+# PC SMBus host controller drivers
 obj-$(CONFIG_I2C_ALI1535)      += i2c-ali1535.o
 obj-$(CONFIG_I2C_ALI1563)      += i2c-ali1563.o
 obj-$(CONFIG_I2C_ALI15X3)      += i2c-ali15x3.o
 obj-$(CONFIG_I2C_AMD756)       += i2c-amd756.o
 obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o
 obj-$(CONFIG_I2C_AMD8111)      += i2c-amd8111.o
+obj-$(CONFIG_I2C_I801)         += i2c-i801.o
+obj-$(CONFIG_I2C_ISCH)         += i2c-isch.o
+obj-$(CONFIG_I2C_NFORCE2)      += i2c-nforce2.o
+obj-$(CONFIG_I2C_NFORCE2_S4985)        += i2c-nforce2-s4985.o
+obj-$(CONFIG_I2C_PIIX4)                += i2c-piix4.o
+obj-$(CONFIG_I2C_SIS5595)      += i2c-sis5595.o
+obj-$(CONFIG_I2C_SIS630)       += i2c-sis630.o
+obj-$(CONFIG_I2C_SIS96X)       += i2c-sis96x.o
+obj-$(CONFIG_I2C_VIA)          += i2c-via.o
+obj-$(CONFIG_I2C_VIAPRO)       += i2c-viapro.o
+
+# Mac SMBus host controller drivers
+obj-$(CONFIG_I2C_HYDRA)                += i2c-hydra.o
+obj-$(CONFIG_I2C_POWERMAC)     += i2c-powermac.o
+
+# Embebbed system I2C/SMBus host controller drivers
 obj-$(CONFIG_I2C_AT91)         += i2c-at91.o
 obj-$(CONFIG_I2C_AU1550)       += i2c-au1550.o
 obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
+obj-$(CONFIG_I2C_CPM)          += i2c-cpm.o
 obj-$(CONFIG_I2C_DAVINCI)      += i2c-davinci.o
-obj-$(CONFIG_I2C_ELEKTOR)      += i2c-elektor.o
 obj-$(CONFIG_I2C_GPIO)         += i2c-gpio.o
-obj-$(CONFIG_I2C_HYDRA)                += i2c-hydra.o
-obj-$(CONFIG_I2C_I801)         += i2c-i801.o
-obj-$(CONFIG_I2C_I810)         += i2c-i810.o
 obj-$(CONFIG_I2C_IBM_IIC)      += i2c-ibm_iic.o
 obj-$(CONFIG_I2C_IOP3XX)       += i2c-iop3xx.o
 obj-$(CONFIG_I2C_IXP2000)      += i2c-ixp2000.o
-obj-$(CONFIG_I2C_POWERMAC)     += i2c-powermac.o
 obj-$(CONFIG_I2C_MPC)          += i2c-mpc.o
 obj-$(CONFIG_I2C_MV64XXX)      += i2c-mv64xxx.o
-obj-$(CONFIG_I2C_NFORCE2)      += i2c-nforce2.o
 obj-$(CONFIG_I2C_OCORES)       += i2c-ocores.o
 obj-$(CONFIG_I2C_OMAP)         += i2c-omap.o
-obj-$(CONFIG_I2C_PARPORT)      += i2c-parport.o
-obj-$(CONFIG_I2C_PARPORT_LIGHT)        += i2c-parport-light.o
 obj-$(CONFIG_I2C_PASEMI)       += i2c-pasemi.o
-obj-$(CONFIG_I2C_PCA_ISA)      += i2c-pca-isa.o
-obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o
-obj-$(CONFIG_I2C_PIIX4)                += i2c-piix4.o
-obj-$(CONFIG_I2C_PMCMSP)       += i2c-pmcmsp.o
 obj-$(CONFIG_I2C_PNX)          += i2c-pnx.o
-obj-$(CONFIG_I2C_PROSAVAGE)    += i2c-prosavage.o
 obj-$(CONFIG_I2C_PXA)          += i2c-pxa.o
 obj-$(CONFIG_I2C_S3C2410)      += i2c-s3c2410.o
-obj-$(CONFIG_I2C_SAVAGE4)      += i2c-savage4.o
 obj-$(CONFIG_I2C_SH7760)       += i2c-sh7760.o
 obj-$(CONFIG_I2C_SH_MOBILE)    += i2c-sh_mobile.o
-obj-$(CONFIG_I2C_SIBYTE)       += i2c-sibyte.o
 obj-$(CONFIG_I2C_SIMTEC)       += i2c-simtec.o
-obj-$(CONFIG_I2C_SIS5595)      += i2c-sis5595.o
-obj-$(CONFIG_I2C_SIS630)       += i2c-sis630.o
-obj-$(CONFIG_I2C_SIS96X)       += i2c-sis96x.o
-obj-$(CONFIG_I2C_STUB)         += i2c-stub.o
+obj-$(CONFIG_I2C_VERSATILE)    += i2c-versatile.o
+
+# External I2C/SMBus adapter drivers
+obj-$(CONFIG_I2C_PARPORT)      += i2c-parport.o
+obj-$(CONFIG_I2C_PARPORT_LIGHT)        += i2c-parport-light.o
 obj-$(CONFIG_I2C_TAOS_EVM)     += i2c-taos-evm.o
 obj-$(CONFIG_I2C_TINY_USB)     += i2c-tiny-usb.o
-obj-$(CONFIG_I2C_VERSATILE)    += i2c-versatile.o
-obj-$(CONFIG_I2C_ACORN)                += i2c-acorn.o
-obj-$(CONFIG_I2C_VIA)          += i2c-via.o
-obj-$(CONFIG_I2C_VIAPRO)       += i2c-viapro.o
+
+# Graphics adapter I2C/DDC channel drivers
 obj-$(CONFIG_I2C_VOODOO3)      += i2c-voodoo3.o
+
+# Other I2C/SMBus bus drivers
+obj-$(CONFIG_I2C_ACORN)                += i2c-acorn.o
+obj-$(CONFIG_I2C_ELEKTOR)      += i2c-elektor.o
+obj-$(CONFIG_I2C_PCA_ISA)      += i2c-pca-isa.o
+obj-$(CONFIG_I2C_PCA_PLATFORM) += i2c-pca-platform.o
+obj-$(CONFIG_I2C_PMCMSP)       += i2c-pmcmsp.o
+obj-$(CONFIG_I2C_SIBYTE)       += i2c-sibyte.o
+obj-$(CONFIG_I2C_STUB)         += i2c-stub.o
 obj-$(CONFIG_SCx200_ACB)       += scx200_acb.o
 obj-$(CONFIG_SCx200_I2C)       += scx200_i2c.o
 
index f14372a..9cead9b 100644 (file)
@@ -1,6 +1,4 @@
 /*
-    i2c-ali1535.c - Part of lm_sensors, Linux kernel modules for hardware
-                    monitoring
     Copyright (c) 2000  Frodo Looijaard <frodol@dds.nl>, 
                         Philip Edelbrock <phil@netroedge.com>, 
                         Mark D. Studebaker <mdsxyz123@yahoo.com>,
@@ -61,6 +59,7 @@
 #include <linux/ioport.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
+#include <linux/acpi.h>
 #include <asm/io.h>
 
 
@@ -159,6 +158,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",
@@ -259,7 +263,7 @@ static int ali1535_transaction(struct i2c_adapter *adap)
                        dev_err(&adap->dev,
                                "SMBus reset failed! (0x%02x) - controller or "
                                "device on bus is probably hung\n", temp);
-                       return -1;
+                       return -EBUSY;
                }
        } else {
                /* check and clear done bit */
@@ -281,12 +285,12 @@ static int ali1535_transaction(struct i2c_adapter *adap)
 
        /* If the SMBus is still busy, we give up */
        if (timeout >= MAX_TIMEOUT) {
-               result = -1;
+               result = -ETIMEDOUT;
                dev_err(&adap->dev, "SMBus Timeout!\n");
        }
 
        if (temp & ALI1535_STS_FAIL) {
-               result = -1;
+               result = -EIO;
                dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
        }
 
@@ -295,7 +299,7 @@ static int ali1535_transaction(struct i2c_adapter *adap)
         * do a printk.  This means that bus collisions go unreported.
         */
        if (temp & ALI1535_STS_BUSERR) {
-               result = -1;
+               result = -ENXIO;
                dev_dbg(&adap->dev,
                        "Error: no response or bus collision ADD=%02x\n",
                        inb_p(SMBHSTADD));
@@ -303,13 +307,13 @@ static int ali1535_transaction(struct i2c_adapter *adap)
 
        /* haven't ever seen this */
        if (temp & ALI1535_STS_DEV) {
-               result = -1;
+               result = -EIO;
                dev_err(&adap->dev, "Error: device error\n");
        }
 
        /* check to see if the "command complete" indication is set */
        if (!(temp & ALI1535_STS_DONE)) {
-               result = -1;
+               result = -ETIMEDOUT;
                dev_err(&adap->dev, "Error: command never completed\n");
        }
 
@@ -332,7 +336,7 @@ static int ali1535_transaction(struct i2c_adapter *adap)
        return result;
 }
 
-/* Return -1 on error. */
+/* Return negative errno on error. */
 static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
                          unsigned short flags, char read_write, u8 command,
                          int size, union i2c_smbus_data *data)
@@ -357,10 +361,6 @@ static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
        outb_p(0xFF, SMBHSTSTS);
 
        switch (size) {
-       case I2C_SMBUS_PROC_CALL:
-               dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
-               result = -1;
-               goto EXIT;
        case I2C_SMBUS_QUICK:
                outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
                       SMBHSTADD);
@@ -418,13 +418,15 @@ static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
                                outb_p(data->block[i], SMBBLKDAT);
                }
                break;
+       default:
+               dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
+               result = -EOPNOTSUPP;
+               goto EXIT;
        }
 
-       if (ali1535_transaction(adap)) {
-               /* Error in transaction */
-               result = -1;
+       result = ali1535_transaction(adap);
+       if (result)
                goto EXIT;
-       }
 
        if ((read_write == I2C_SMBUS_WRITE) || (size == ALI1535_QUICK)) {
                result = 0;
@@ -475,7 +477,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 static struct i2c_adapter ali1535_adapter = {
        .owner          = THIS_MODULE,
        .id             = I2C_HW_SMBUS_ALI1535,
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .algo           = &smbus_algorithm,
 };
 
index 6b68074..fc3e5b0 100644 (file)
@@ -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
@@ -67,6 +68,7 @@ static int ali1563_transaction(struct i2c_adapter * a, int size)
 {
        u32 data;
        int timeout;
+       int status = -EIO;
 
        dev_dbg(&a->dev, "Transaction (pre): STS=%02x, CNTL1=%02x, "
                "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
@@ -103,13 +105,15 @@ static int ali1563_transaction(struct i2c_adapter * a, int size)
                /* Issue 'kill' to host controller */
                outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2);
                data = inb_p(SMB_HST_STS);
+               status = -ETIMEDOUT;
        }
 
        /* device error - no response, ignore the autodetection case */
-       if ((data & HST_STS_DEVERR) && (size != HST_CNTL2_QUICK)) {
-               dev_err(&a->dev, "Device error!\n");
+       if (data & HST_STS_DEVERR) {
+               if (size != HST_CNTL2_QUICK)
+                       dev_err(&a->dev, "Device error!\n");
+               status = -ENXIO;
        }
-
        /* bus collision */
        if (data & HST_STS_BUSERR) {
                dev_err(&a->dev, "Bus collision!\n");
@@ -122,13 +126,14 @@ static int ali1563_transaction(struct i2c_adapter * a, int size)
                outb_p(0x0,SMB_HST_CNTL2);
        }
 
-       return -1;
+       return status;
 }
 
 static int ali1563_block_start(struct i2c_adapter * a)
 {
        u32 data;
        int timeout;
+       int status = -EIO;
 
        dev_dbg(&a->dev, "Block (pre): STS=%02x, CNTL1=%02x, "
                "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
@@ -164,13 +169,20 @@ static int ali1563_block_start(struct i2c_adapter * a)
 
        if (timeout && !(data & HST_STS_BAD))
                return 0;
+
+       if (timeout == 0)
+               status = -ETIMEDOUT;
+
+       if (data & HST_STS_DEVERR)
+               status = -ENXIO;
+
        dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n",
-               timeout ? "Timeout " : "",
+               timeout ? "" : "Timeout ",
                data & HST_STS_FAIL ? "Transaction Failed " : "",
                data & HST_STS_BUSERR ? "No response or Bus Collision " : "",
                data & HST_STS_DEVERR ? "Device Error " : "",
                !(data & HST_STS_DONE) ? "Transaction Never Finished " : "");
-       return -1;
+       return status;
 }
 
 static int ali1563_block(struct i2c_adapter * a, union i2c_smbus_data * data, u8 rw)
@@ -235,10 +247,6 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr,
 
        /* Map the size to what the chip understands */
        switch (size) {
-       case I2C_SMBUS_PROC_CALL:
-               dev_err(&a->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
-               error = -EINVAL;
-               break;
        case I2C_SMBUS_QUICK:
                size = HST_CNTL2_QUICK;
                break;
@@ -254,6 +262,10 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr,
        case I2C_SMBUS_BLOCK_DATA:
                size = HST_CNTL2_BLOCK;
                break;
+       default:
+               dev_warn(&a->dev, "Unsupported transaction %d\n", size);
+               error = -EOPNOTSUPP;
+               goto Done;
        }
 
        outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD);
@@ -345,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",
@@ -371,7 +387,7 @@ static const struct i2c_algorithm ali1563_algorithm = {
 static struct i2c_adapter ali1563_adapter = {
        .owner  = THIS_MODULE,
        .id     = I2C_HW_SMBUS_ALI1563,
-       .class  = I2C_CLASS_HWMON,
+       .class  = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .algo   = &ali1563_algorithm,
 };
 
index 93bf87d..234fdde 100644 (file)
@@ -1,6 +1,4 @@
 /*
-    ali15x3.c - Part of lm_sensors, Linux kernel modules for hardware
-              monitoring
     Copyright (c) 1999  Frodo Looijaard <frodol@dds.nl> and
     Philip Edelbrock <phil@netroedge.com> and
     Mark D. Studebaker <mdsxyz123@yahoo.com>
@@ -68,6 +66,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 */
@@ -166,6 +165,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,
@@ -282,7 +285,7 @@ static int ali15x3_transaction(struct i2c_adapter *adap)
                        dev_err(&adap->dev, "SMBus reset failed! (0x%02x) - "
                                "controller or device on bus is probably hung\n",
                                temp);
-                       return -1;
+                       return -EBUSY;
                }
        } else {
                /* check and clear done bit */
@@ -304,12 +307,12 @@ static int ali15x3_transaction(struct i2c_adapter *adap)
 
        /* If the SMBus is still busy, we give up */
        if (timeout >= MAX_TIMEOUT) {
-               result = -1;
+               result = -ETIMEDOUT;
                dev_err(&adap->dev, "SMBus Timeout!\n");
        }
 
        if (temp & ALI15X3_STS_TERM) {
-               result = -1;
+               result = -EIO;
                dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
        }
 
@@ -320,7 +323,7 @@ static int ali15x3_transaction(struct i2c_adapter *adap)
          This means that bus collisions go unreported.
        */
        if (temp & ALI15X3_STS_COLL) {
-               result = -1;
+               result = -ENXIO;
                dev_dbg(&adap->dev,
                        "Error: no response or bus collision ADD=%02x\n",
                        inb_p(SMBHSTADD));
@@ -328,7 +331,7 @@ static int ali15x3_transaction(struct i2c_adapter *adap)
 
        /* haven't ever seen this */
        if (temp & ALI15X3_STS_DEV) {
-               result = -1;
+               result = -EIO;
                dev_err(&adap->dev, "Error: device error\n");
        }
        dev_dbg(&adap->dev, "Transaction (post): STS=%02x, CNT=%02x, CMD=%02x, "
@@ -338,7 +341,7 @@ static int ali15x3_transaction(struct i2c_adapter *adap)
        return result;
 }
 
-/* Return -1 on error. */
+/* Return negative errno on error. */
 static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr,
                   unsigned short flags, char read_write, u8 command,
                   int size, union i2c_smbus_data * data)
@@ -362,9 +365,6 @@ static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr,
        }
 
        switch (size) {
-       case I2C_SMBUS_PROC_CALL:
-               dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
-               return -1;
        case I2C_SMBUS_QUICK:
                outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
                       SMBHSTADD);
@@ -417,12 +417,16 @@ static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr,
                }
                size = ALI15X3_BLOCK_DATA;
                break;
+       default:
+               dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
+               return -EOPNOTSUPP;
        }
 
        outb_p(size, SMBHSTCNT);        /* output command */
 
-       if (ali15x3_transaction(adap))  /* Error in transaction */
-               return -1;
+       temp = ali15x3_transaction(adap);
+       if (temp)
+               return temp;
 
        if ((read_write == I2C_SMBUS_WRITE) || (size == ALI15X3_QUICK))
                return 0;
@@ -470,7 +474,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 static struct i2c_adapter ali15x3_adapter = {
        .owner          = THIS_MODULE,
        .id             = I2C_HW_SMBUS_ALI15X3,
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .algo           = &smbus_algorithm,
 };
 
index c38a0a1..2f150e3 100644 (file)
@@ -58,7 +58,7 @@ static s32 amd756_access_virt0(struct i2c_adapter * adap, u16 addr,
        /* We exclude the multiplexed addresses */
        if (addr == 0x4c || (addr & 0xfc) == 0x50 || (addr & 0xfc) == 0x30
         || addr == 0x18)
-               return -1;
+               return -ENXIO;
 
        mutex_lock(&amd756_lock);
 
@@ -86,7 +86,7 @@ static inline s32 amd756_access_channel(struct i2c_adapter * adap, u16 addr,
 
        /* We exclude the non-multiplexed addresses */
        if (addr != 0x4c && (addr & 0xfc) != 0x50 && (addr & 0xfc) != 0x30)
-               return -1;
+               return -ENXIO;
 
        mutex_lock(&amd756_lock);
 
index 43508d6..1ea3925 100644 (file)
@@ -1,7 +1,4 @@
 /*
-    amd756.c - Part of lm_sensors, Linux kernel modules for hardware
-              monitoring
-
     Copyright (c) 1999-2002 Merlin Hughes <merlin@merlin.org>
 
     Shamelessly ripped from i2c-piix4.c:
@@ -45,6 +42,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 */
@@ -151,17 +149,17 @@ static int amd756_transaction(struct i2c_adapter *adap)
        }
 
        if (temp & GS_PRERR_STS) {
-               result = -1;
+               result = -ENXIO;
                dev_dbg(&adap->dev, "SMBus Protocol error (no response)!\n");
        }
 
        if (temp & GS_COL_STS) {
-               result = -1;
+               result = -EIO;
                dev_warn(&adap->dev, "SMBus collision!\n");
        }
 
        if (temp & GS_TO_STS) {
-               result = -1;
+               result = -ETIMEDOUT;
                dev_dbg(&adap->dev, "SMBus protocol timeout!\n");
        }
 
@@ -189,22 +187,18 @@ static int amd756_transaction(struct i2c_adapter *adap)
        outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE);
        msleep(100);
        outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS);
-       return -1;
+       return -EIO;
 }
 
-/* Return -1 on error. */
+/* Return negative errno on error. */
 static s32 amd756_access(struct i2c_adapter * adap, u16 addr,
                  unsigned short flags, char read_write,
                  u8 command, int size, union i2c_smbus_data * data)
 {
        int i, len;
+       int status;
 
-       /** TODO: Should I supporte the 10-bit transfers? */
        switch (size) {
-       case I2C_SMBUS_PROC_CALL:
-               dev_dbg(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
-               /* TODO: Well... It is supported, I'm just not sure what to do here... */
-               return -1;
        case I2C_SMBUS_QUICK:
                outw_p(((addr & 0x7f) << 1) | (read_write & 0x01),
                       SMB_HOST_ADDRESS);
@@ -251,13 +245,17 @@ static s32 amd756_access(struct i2c_adapter * adap, u16 addr,
                }
                size = AMD756_BLOCK_DATA;
                break;
+       default:
+               dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
+               return -EOPNOTSUPP;
        }
 
        /* How about enabling interrupts... */
        outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE);
 
-       if (amd756_transaction(adap))   /* Error in transaction */
-               return -1;
+       status = amd756_transaction(adap);
+       if (status)
+               return status;
 
        if ((read_write == I2C_SMBUS_WRITE) || (size == AMD756_QUICK))
                return 0;
@@ -301,7 +299,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 struct i2c_adapter amd756_smbus = {
        .owner          = THIS_MODULE,
        .id             = I2C_HW_SMBUS_AMD756,
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .algo           = &smbus_algorithm,
 };
 
@@ -368,6 +366,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);
index 5d1a27e..3972208 100644 (file)
@@ -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");
@@ -77,7 +78,7 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus)
        if (!timeout) {
                dev_warn(&smbus->dev->dev,
                         "Timeout while waiting for IBF to clear\n");
-               return -1;
+               return -ETIMEDOUT;
        }
 
        return 0;
@@ -93,7 +94,7 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus)
        if (!timeout) {
                dev_warn(&smbus->dev->dev,
                         "Timeout while waiting for OBF to set\n");
-               return -1;
+               return -ETIMEDOUT;
        }
 
        return 0;
@@ -102,16 +103,21 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus)
 static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
                unsigned char *data)
 {
-       if (amd_ec_wait_write(smbus))
-               return -1;
+       int status;
+
+       status = amd_ec_wait_write(smbus);
+       if (status)
+               return status;
        outb(AMD_EC_CMD_RD, smbus->base + AMD_EC_CMD);
 
-       if (amd_ec_wait_write(smbus))
-               return -1;
+       status = amd_ec_wait_write(smbus);
+       if (status)
+               return status;
        outb(address, smbus->base + AMD_EC_DATA);
 
-       if (amd_ec_wait_read(smbus))
-               return -1;
+       status = amd_ec_wait_read(smbus);
+       if (status)
+               return status;
        *data = inb(smbus->base + AMD_EC_DATA);
 
        return 0;
@@ -120,16 +126,21 @@ static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
 static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address,
                unsigned char data)
 {
-       if (amd_ec_wait_write(smbus))
-               return -1;
+       int status;
+
+       status = amd_ec_wait_write(smbus);
+       if (status)
+               return status;
        outb(AMD_EC_CMD_WR, smbus->base + AMD_EC_CMD);
 
-       if (amd_ec_wait_write(smbus))
-               return -1;
+       status = amd_ec_wait_write(smbus);
+       if (status)
+               return status;
        outb(address, smbus->base + AMD_EC_DATA);
 
-       if (amd_ec_wait_write(smbus))
-               return -1;
+       status = amd_ec_wait_write(smbus);
+       if (status)
+               return status;
        outb(data, smbus->base + AMD_EC_DATA);
 
        return 0;
@@ -267,12 +278,17 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
 
                default:
                        dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
-                       return -1;
+                       return -EOPNOTSUPP;
        }
 
        amd_ec_write(smbus, AMD_SMB_ADDR, addr << 1);
        amd_ec_write(smbus, AMD_SMB_PRTCL, protocol);
 
+       /* FIXME this discards status from ec_read(); so temp[0] will
+        * hold stack garbage ... the rest of this routine will act
+        * nonsensically.  Ignored ec_write() status might explain
+        * some such failures...
+        */
        amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
 
        if (~temp[0] & AMD_SMB_STS_DONE) {
@@ -286,7 +302,7 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
        }
 
        if ((~temp[0] & AMD_SMB_STS_DONE) || (temp[0] & AMD_SMB_STS_STATUS))
-               return -1;
+               return -EIO;
 
        if (read_write == I2C_SMBUS_WRITE)
                return 0;
@@ -359,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;
@@ -368,7 +388,7 @@ static int __devinit amd8111_probe(struct pci_dev *dev,
        snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
                "SMBus2 AMD8111 adapter at %04x", smbus->base);
        smbus->adapter.id = I2C_HW_SMBUS_AMD8111;
-       smbus->adapter.class = I2C_CLASS_HWMON;
+       smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
        smbus->adapter.algo = &smbus_algorithm;
        smbus->adapter.algo_data = smbus;
 
index cae9dc8..66a04c2 100644 (file)
@@ -269,9 +269,13 @@ static int
 au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
 {
        struct i2c_au1550_data *adap = i2c_adap->algo_data;
+       volatile psc_smb_t *sp = (volatile psc_smb_t *)adap->psc_base;
        struct i2c_msg *p;
        int i, err = 0;
 
+       sp->psc_ctrl = PSC_CTRL_ENABLE;
+       au_sync();
+
        for (i = 0; !err && i < num; i++) {
                p = &msgs[i];
                err = do_address(adap, p->addr, p->flags & I2C_M_RD,
@@ -288,6 +292,10 @@ au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
        */
        if (err == 0)
                err = num;
+
+       sp->psc_ctrl = PSC_CTRL_SUSPEND;
+       au_sync();
+
        return err;
 }
 
@@ -302,6 +310,61 @@ static const struct i2c_algorithm au1550_algo = {
        .functionality  = au1550_func,
 };
 
+static void i2c_au1550_setup(struct i2c_au1550_data *priv)
+{
+       volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base;
+       u32 stat;
+
+       sp->psc_ctrl = PSC_CTRL_DISABLE;
+       au_sync();
+       sp->psc_sel = PSC_SEL_PS_SMBUSMODE;
+       sp->psc_smbcfg = 0;
+       au_sync();
+       sp->psc_ctrl = PSC_CTRL_ENABLE;
+       au_sync();
+       do {
+               stat = sp->psc_smbstat;
+               au_sync();
+       } while ((stat & PSC_SMBSTAT_SR) == 0);
+
+       sp->psc_smbcfg = (PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 |
+                               PSC_SMBCFG_DD_DISABLE);
+
+       /* Divide by 8 to get a 6.25 MHz clock.  The later protocol
+        * timings are based on this clock.
+        */
+       sp->psc_smbcfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8);
+       sp->psc_smbmsk = PSC_SMBMSK_ALLMASK;
+       au_sync();
+
+       /* Set the protocol timer values.  See Table 71 in the
+        * Au1550 Data Book for standard timing values.
+        */
+       sp->psc_smbtmr = PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(15) | \
+               PSC_SMBTMR_SET_PU(15) | PSC_SMBTMR_SET_SH(15) | \
+               PSC_SMBTMR_SET_SU(15) | PSC_SMBTMR_SET_CL(15) | \
+               PSC_SMBTMR_SET_CH(15);
+       au_sync();
+
+       sp->psc_smbcfg |= PSC_SMBCFG_DE_ENABLE;
+       do {
+               stat = sp->psc_smbstat;
+               au_sync();
+       } while ((stat & PSC_SMBSTAT_SR) == 0);
+
+       sp->psc_ctrl = PSC_CTRL_SUSPEND;
+       au_sync();
+}
+
+static void i2c_au1550_disable(struct i2c_au1550_data *priv)
+{
+       volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base;
+
+       sp->psc_smbcfg = 0;
+       sp->psc_ctrl = PSC_CTRL_DISABLE;
+       au_sync();
+}
+
 /*
  * registering functions to load algorithms at runtime
  * Prior to calling us, the 50MHz clock frequency and routing
@@ -311,9 +374,7 @@ static int __devinit
 i2c_au1550_probe(struct platform_device *pdev)
 {
        struct i2c_au1550_data *priv;
-       volatile psc_smb_t *sp;
        struct resource *r;
-       u32 stat;
        int ret;
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -348,43 +409,7 @@ i2c_au1550_probe(struct platform_device *pdev)
 
        /* Now, set up the PSC for SMBus PIO mode.
        */
-       sp = (volatile psc_smb_t *)priv->psc_base;
-       sp->psc_ctrl = PSC_CTRL_DISABLE;
-       au_sync();
-       sp->psc_sel = PSC_SEL_PS_SMBUSMODE;
-       sp->psc_smbcfg = 0;
-       au_sync();
-       sp->psc_ctrl = PSC_CTRL_ENABLE;
-       au_sync();
-       do {
-               stat = sp->psc_smbstat;
-               au_sync();
-       } while ((stat & PSC_SMBSTAT_SR) == 0);
-
-       sp->psc_smbcfg = (PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 |
-                               PSC_SMBCFG_DD_DISABLE);
-
-       /* Divide by 8 to get a 6.25 MHz clock.  The later protocol
-        * timings are based on this clock.
-        */
-       sp->psc_smbcfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8);
-       sp->psc_smbmsk = PSC_SMBMSK_ALLMASK;
-       au_sync();
-
-       /* Set the protocol timer values.  See Table 71 in the
-        * Au1550 Data Book for standard timing values.
-        */
-       sp->psc_smbtmr = PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(15) | \
-               PSC_SMBTMR_SET_PU(15) | PSC_SMBTMR_SET_SH(15) | \
-               PSC_SMBTMR_SET_SU(15) | PSC_SMBTMR_SET_CL(15) | \
-               PSC_SMBTMR_SET_CH(15);
-       au_sync();
-
-       sp->psc_smbcfg |= PSC_SMBCFG_DE_ENABLE;
-       do {
-               stat = sp->psc_smbstat;
-               au_sync();
-       } while ((stat & PSC_SMBSTAT_DR) == 0);
+       i2c_au1550_setup(priv);
 
        ret = i2c_add_numbered_adapter(&priv->adap);
        if (ret == 0) {
@@ -392,10 +417,7 @@ i2c_au1550_probe(struct platform_device *pdev)
                return 0;
        }
 
-       /* disable the PSC */
-       sp->psc_smbcfg = 0;
-       sp->psc_ctrl = PSC_CTRL_DISABLE;
-       au_sync();
+       i2c_au1550_disable(priv);
 
        release_resource(priv->ioarea);
        kfree(priv->ioarea);
@@ -409,27 +431,24 @@ static int __devexit
 i2c_au1550_remove(struct platform_device *pdev)
 {
        struct i2c_au1550_data *priv = platform_get_drvdata(pdev);
-       volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base;
 
        platform_set_drvdata(pdev, NULL);
        i2c_del_adapter(&priv->adap);
-       sp->psc_smbcfg = 0;
-       sp->psc_ctrl = PSC_CTRL_DISABLE;
-       au_sync();
+       i2c_au1550_disable(priv);
        release_resource(priv->ioarea);
        kfree(priv->ioarea);
        kfree(priv);
        return 0;
 }
 
+#ifdef CONFIG_PM
 static int
 i2c_au1550_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct i2c_au1550_data *priv = platform_get_drvdata(pdev);
-       volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base;
 
-       sp->psc_ctrl = PSC_CTRL_SUSPEND;
-       au_sync();
+       i2c_au1550_disable(priv);
+
        return 0;
 }
 
@@ -437,14 +456,15 @@ static int
 i2c_au1550_resume(struct platform_device *pdev)
 {
        struct i2c_au1550_data *priv = platform_get_drvdata(pdev);
-       volatile psc_smb_t *sp = (volatile psc_smb_t *)priv->psc_base;
 
-       sp->psc_ctrl = PSC_CTRL_ENABLE;
-       au_sync();
-       while (!(sp->psc_smbstat & PSC_SMBSTAT_SR))
-               au_sync();
+       i2c_au1550_setup(priv);
+
        return 0;
 }
+#else
+#define i2c_au1550_suspend     NULL
+#define i2c_au1550_resume      NULL
+#endif
 
 static struct platform_driver au1xpsc_smbus_driver = {
        .driver = {
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
new file mode 100644 (file)
index 0000000..8164de1
--- /dev/null
@@ -0,0 +1,745 @@
+/*
+ * Freescale CPM1/CPM2 I2C interface.
+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
+ *
+ * moved into proper i2c interface;
+ * Brad Parker (brad@heeltoe.com)
+ *
+ * Parts from dbox2_i2c.c (cvs.tuxbox.org)
+ * (C) 2000-2001 Felix Domke (tmbinc@gmx.net), Gillem (htoa@gmx.net)
+ *
+ * (C) 2007 Montavista Software, Inc.
+ * Vitaly Bordug <vitb@kernel.crashing.org>
+ *
+ * Converted to of_platform_device. Renamed to i2c-cpm.c.
+ * (C) 2007,2008 Jochen Friedrich <jochen@scram.de>
+ *
+ *  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.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/stddef.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_i2c.h>
+#include <sysdev/fsl_soc.h>
+#include <asm/cpm.h>
+
+/* Try to define this if you have an older CPU (earlier than rev D4) */
+/* However, better use a GPIO based bitbang driver in this case :/   */
+#undef I2C_CHIP_ERRATA
+
+#define CPM_MAX_READ    513
+#define CPM_MAXBD       4
+
+#define I2C_EB                 (0x10) /* Big endian mode */
+#define I2C_EB_CPM2            (0x30) /* Big endian mode, memory snoop */
+
+#define DPRAM_BASE             ((u8 __iomem __force *)cpm_muram_addr(0))
+
+/* I2C parameter RAM. */
+struct i2c_ram {
+       ushort  rbase;          /* Rx Buffer descriptor base address */
+       ushort  tbase;          /* Tx Buffer descriptor base address */
+       u_char  rfcr;           /* Rx function code */
+       u_char  tfcr;           /* Tx function code */
+       ushort  mrblr;          /* Max receive buffer length */
+       uint    rstate;         /* Internal */
+       uint    rdp;            /* Internal */
+       ushort  rbptr;          /* Rx Buffer descriptor pointer */
+       ushort  rbc;            /* Internal */
+       uint    rxtmp;          /* Internal */
+       uint    tstate;         /* Internal */
+       uint    tdp;            /* Internal */
+       ushort  tbptr;          /* Tx Buffer descriptor pointer */
+       ushort  tbc;            /* Internal */
+       uint    txtmp;          /* Internal */
+       char    res1[4];        /* Reserved */
+       ushort  rpbase;         /* Relocation pointer */
+       char    res2[2];        /* Reserved */
+};
+
+#define I2COM_START    0x80
+#define I2COM_MASTER   0x01
+#define I2CER_TXE      0x10
+#define I2CER_BUSY     0x04
+#define I2CER_TXB      0x02
+#define I2CER_RXB      0x01
+#define I2MOD_EN       0x01
+
+/* I2C Registers */
+struct i2c_reg {
+       u8      i2mod;
+       u8      res1[3];
+       u8      i2add;
+       u8      res2[3];
+       u8      i2brg;
+       u8      res3[3];
+       u8      i2com;
+       u8      res4[3];
+       u8      i2cer;
+       u8      res5[3];
+       u8      i2cmr;
+};
+
+struct cpm_i2c {
+       char *base;
+       struct of_device *ofdev;
+       struct i2c_adapter adap;
+       uint dp_addr;
+       int version; /* CPM1=1, CPM2=2 */
+       int irq;
+       int cp_command;
+       int freq;
+       struct i2c_reg __iomem *i2c_reg;
+       struct i2c_ram __iomem *i2c_ram;
+       u16 i2c_addr;
+       wait_queue_head_t i2c_wait;
+       cbd_t __iomem *tbase;
+       cbd_t __iomem *rbase;
+       u_char *txbuf[CPM_MAXBD];
+       u_char *rxbuf[CPM_MAXBD];
+       u32 txdma[CPM_MAXBD];
+       u32 rxdma[CPM_MAXBD];
+};
+
+static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id)
+{
+       struct cpm_i2c *cpm;
+       struct i2c_reg __iomem *i2c_reg;
+       struct i2c_adapter *adap = dev_id;
+       int i;
+
+       cpm = i2c_get_adapdata(dev_id);
+       i2c_reg = cpm->i2c_reg;
+
+       /* Clear interrupt. */
+       i = in_8(&i2c_reg->i2cer);
+       out_8(&i2c_reg->i2cer, i);
+
+       dev_dbg(&adap->dev, "Interrupt: %x\n", i);
+
+       wake_up_interruptible(&cpm->i2c_wait);
+
+       return i ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static void cpm_reset_i2c_params(struct cpm_i2c *cpm)
+{
+       struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+
+       /* Set up the I2C parameters in the parameter ram. */
+       out_be16(&i2c_ram->tbase, (u8 __iomem *)cpm->tbase - DPRAM_BASE);
+       out_be16(&i2c_ram->rbase, (u8 __iomem *)cpm->rbase - DPRAM_BASE);
+
+       if (cpm->version == 1) {
+               out_8(&i2c_ram->tfcr, I2C_EB);
+               out_8(&i2c_ram->rfcr, I2C_EB);
+       } else {
+               out_8(&i2c_ram->tfcr, I2C_EB_CPM2);
+               out_8(&i2c_ram->rfcr, I2C_EB_CPM2);
+       }
+
+       out_be16(&i2c_ram->mrblr, CPM_MAX_READ);
+
+       out_be32(&i2c_ram->rstate, 0);
+       out_be32(&i2c_ram->rdp, 0);
+       out_be16(&i2c_ram->rbptr, 0);
+       out_be16(&i2c_ram->rbc, 0);
+       out_be32(&i2c_ram->rxtmp, 0);
+       out_be32(&i2c_ram->tstate, 0);
+       out_be32(&i2c_ram->tdp, 0);
+       out_be16(&i2c_ram->tbptr, 0);
+       out_be16(&i2c_ram->tbc, 0);
+       out_be32(&i2c_ram->txtmp, 0);
+}
+
+static void cpm_i2c_force_close(struct i2c_adapter *adap)
+{
+       struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+       struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
+
+       dev_dbg(&adap->dev, "cpm_i2c_force_close()\n");
+
+       cpm_command(cpm->cp_command, CPM_CR_CLOSE_RX_BD);
+
+       out_8(&i2c_reg->i2cmr, 0x00);   /* Disable all interrupts */
+       out_8(&i2c_reg->i2cer, 0xff);
+}
+
+static void cpm_i2c_parse_message(struct i2c_adapter *adap,
+       struct i2c_msg *pmsg, int num, int tx, int rx)
+{
+       cbd_t __iomem *tbdf;
+       cbd_t __iomem *rbdf;
+       u_char addr;
+       u_char *tb;
+       u_char *rb;
+       struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+
+       tbdf = cpm->tbase + tx;
+       rbdf = cpm->rbase + rx;
+
+       addr = pmsg->addr << 1;
+       if (pmsg->flags & I2C_M_RD)
+               addr |= 1;
+
+       tb = cpm->txbuf[tx];
+       rb = cpm->rxbuf[rx];
+
+       /* Align read buffer */
+       rb = (u_char *) (((ulong) rb + 1) & ~1);
+
+       tb[0] = addr;           /* Device address byte w/rw flag */
+
+       out_be16(&tbdf->cbd_datlen, pmsg->len + 1);
+       out_be16(&tbdf->cbd_sc, 0);
+
+       if (!(pmsg->flags & I2C_M_NOSTART))
+               setbits16(&tbdf->cbd_sc, BD_I2C_START);
+
+       if (tx + 1 == num)
+               setbits16(&tbdf->cbd_sc, BD_SC_LAST | BD_SC_WRAP);
+
+       if (pmsg->flags & I2C_M_RD) {
+               /*
+                * To read, we need an empty buffer of the proper length.
+                * All that is used is the first byte for address, the remainder
+                * is just used for timing (and doesn't really have to exist).
+                */
+
+               dev_dbg(&adap->dev, "cpm_i2c_read(abyte=0x%x)\n", addr);
+
+               out_be16(&rbdf->cbd_datlen, 0);
+               out_be16(&rbdf->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT);
+
+               if (rx + 1 == CPM_MAXBD)
+                       setbits16(&rbdf->cbd_sc, BD_SC_WRAP);
+
+               eieio();
+               setbits16(&tbdf->cbd_sc, BD_SC_READY);
+       } else {
+               dev_dbg(&adap->dev, "cpm_i2c_write(abyte=0x%x)\n", addr);
+
+               memcpy(tb+1, pmsg->buf, pmsg->len);
+
+               eieio();
+               setbits16(&tbdf->cbd_sc, BD_SC_READY | BD_SC_INTRPT);
+       }
+}
+
+static int cpm_i2c_check_message(struct i2c_adapter *adap,
+       struct i2c_msg *pmsg, int tx, int rx)
+{
+       cbd_t __iomem *tbdf;
+       cbd_t __iomem *rbdf;
+       u_char *tb;
+       u_char *rb;
+       struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+
+       tbdf = cpm->tbase + tx;
+       rbdf = cpm->rbase + rx;
+
+       tb = cpm->txbuf[tx];
+       rb = cpm->rxbuf[rx];
+
+       /* Align read buffer */
+       rb = (u_char *) (((uint) rb + 1) & ~1);
+
+       eieio();
+       if (pmsg->flags & I2C_M_RD) {
+               dev_dbg(&adap->dev, "tx sc 0x%04x, rx sc 0x%04x\n",
+                       in_be16(&tbdf->cbd_sc), in_be16(&rbdf->cbd_sc));
+
+               if (in_be16(&tbdf->cbd_sc) & BD_SC_NAK) {
+                       dev_dbg(&adap->dev, "I2C read; No ack\n");
+                       return -ENXIO;
+               }
+               if (in_be16(&rbdf->cbd_sc) & BD_SC_EMPTY) {
+                       dev_err(&adap->dev,
+                               "I2C read; complete but rbuf empty\n");
+                       return -EREMOTEIO;
+               }
+               if (in_be16(&rbdf->cbd_sc) & BD_SC_OV) {
+                       dev_err(&adap->dev, "I2C read; Overrun\n");
+                       return -EREMOTEIO;
+               }
+               memcpy(pmsg->buf, rb, pmsg->len);
+       } else {
+               dev_dbg(&adap->dev, "tx sc %d 0x%04x\n", tx,
+                       in_be16(&tbdf->cbd_sc));
+
+               if (in_be16(&tbdf->cbd_sc) & BD_SC_NAK) {
+                       dev_dbg(&adap->dev, "I2C write; No ack\n");
+                       return -ENXIO;
+               }
+               if (in_be16(&tbdf->cbd_sc) & BD_SC_UN) {
+                       dev_err(&adap->dev, "I2C write; Underrun\n");
+                       return -EIO;
+               }
+               if (in_be16(&tbdf->cbd_sc) & BD_SC_CL) {
+                       dev_err(&adap->dev, "I2C write; Collision\n");
+                       return -EIO;
+               }
+       }
+       return 0;
+}
+
+static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+       struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+       struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
+       struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+       struct i2c_msg *pmsg;
+       int ret, i;
+       int tptr;
+       int rptr;
+       cbd_t __iomem *tbdf;
+       cbd_t __iomem *rbdf;
+
+       if (num > CPM_MAXBD)
+               return -EINVAL;
+
+       /* Check if we have any oversized READ requests */
+       for (i = 0; i < num; i++) {
+               pmsg = &msgs[i];
+               if (pmsg->len >= CPM_MAX_READ)
+                       return -EINVAL;
+       }
+
+       /* Reset to use first buffer */
+       out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
+       out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
+
+       tbdf = cpm->tbase;
+       rbdf = cpm->rbase;
+
+       tptr = 0;
+       rptr = 0;
+
+       while (tptr < num) {
+               pmsg = &msgs[tptr];
+               dev_dbg(&adap->dev, "R: %d T: %d\n", rptr, tptr);
+
+               cpm_i2c_parse_message(adap, pmsg, num, tptr, rptr);
+               if (pmsg->flags & I2C_M_RD)
+                       rptr++;
+               tptr++;
+       }
+       /* Start transfer now */
+       /* Enable RX/TX/Error interupts */
+       out_8(&i2c_reg->i2cmr, I2CER_TXE | I2CER_TXB | I2CER_RXB);
+       out_8(&i2c_reg->i2cer, 0xff);   /* Clear interrupt status */
+       /* Chip bug, set enable here */
+       setbits8(&i2c_reg->i2mod, I2MOD_EN);    /* Enable */
+       /* Begin transmission */
+       setbits8(&i2c_reg->i2com, I2COM_START);
+
+       tptr = 0;
+       rptr = 0;
+
+       while (tptr < num) {
+               /* Check for outstanding messages */
+               dev_dbg(&adap->dev, "test ready.\n");
+               pmsg = &msgs[tptr];
+               if (pmsg->flags & I2C_M_RD)
+                       ret = wait_event_interruptible_timeout(cpm->i2c_wait,
+                               !(in_be16(&rbdf[rptr].cbd_sc) & BD_SC_EMPTY),
+                               1 * HZ);
+               else
+                       ret = wait_event_interruptible_timeout(cpm->i2c_wait,
+                               !(in_be16(&tbdf[tptr].cbd_sc) & BD_SC_READY),
+                               1 * HZ);
+               if (ret == 0) {
+                       ret = -EREMOTEIO;
+                       dev_err(&adap->dev, "I2C transfer: timeout\n");
+                       goto out_err;
+               }
+               if (ret > 0) {
+                       dev_dbg(&adap->dev, "ready.\n");
+                       ret = cpm_i2c_check_message(adap, pmsg, tptr, rptr);
+                       tptr++;
+                       if (pmsg->flags & I2C_M_RD)
+                               rptr++;
+                       if (ret)
+                               goto out_err;
+               }
+       }
+#ifdef I2C_CHIP_ERRATA
+       /*
+        * Chip errata, clear enable. This is not needed on rev D4 CPUs.
+        * Disabling I2C too early may cause too short stop condition
+        */
+       udelay(4);
+       clrbits8(&i2c_reg->i2mod, I2MOD_EN);
+#endif
+       return (num);
+
+out_err:
+       cpm_i2c_force_close(adap);
+#ifdef I2C_CHIP_ERRATA
+       /*
+        * Chip errata, clear enable. This is not needed on rev D4 CPUs.
+        */
+       clrbits8(&i2c_reg->i2mod, I2MOD_EN);
+#endif
+       return ret;
+}
+
+static u32 cpm_i2c_func(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
+}
+
+/* -----exported algorithm data: ------------------------------------- */
+
+static const struct i2c_algorithm cpm_i2c_algo = {
+       .master_xfer = cpm_i2c_xfer,
+       .functionality = cpm_i2c_func,
+};
+
+static const struct i2c_adapter cpm_ops = {
+       .owner          = THIS_MODULE,
+       .name           = "i2c-cpm",
+       .algo           = &cpm_i2c_algo,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
+};
+
+static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm)
+{
+       struct of_device *ofdev = cpm->ofdev;
+       const u32 *data;
+       int len, ret, i;
+       void __iomem *i2c_base;
+       cbd_t __iomem *tbdf;
+       cbd_t __iomem *rbdf;
+       unsigned char brg;
+
+       dev_dbg(&cpm->ofdev->dev, "cpm_i2c_setup()\n");
+
+       init_waitqueue_head(&cpm->i2c_wait);
+
+       cpm->irq = of_irq_to_resource(ofdev->node, 0, NULL);
+       if (cpm->irq == NO_IRQ)
+               return -EINVAL;
+
+       /* Install interrupt handler. */
+       ret = request_irq(cpm->irq, cpm_i2c_interrupt, 0, "cpm_i2c",
+                         &cpm->adap);
+       if (ret)
+               return ret;
+
+       /* I2C parameter RAM */
+       i2c_base = of_iomap(ofdev->node, 1);
+       if (i2c_base == NULL) {
+               ret = -EINVAL;
+               goto out_irq;
+       }
+
+       if (of_device_is_compatible(ofdev->node, "fsl,cpm1-i2c")) {
+
+               /* Check for and use a microcode relocation patch. */
+               cpm->i2c_ram = i2c_base;
+               cpm->i2c_addr = in_be16(&cpm->i2c_ram->rpbase);
+
+               /*
+                * Maybe should use cpm_muram_alloc instead of hardcoding
+                * this in micropatch.c
+                */
+               if (cpm->i2c_addr) {
+                       cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr);
+                       iounmap(i2c_base);
+               }
+
+               cpm->version = 1;
+
+       } else if (of_device_is_compatible(ofdev->node, "fsl,cpm2-i2c")) {
+               cpm->i2c_addr = cpm_muram_alloc(sizeof(struct i2c_ram), 64);
+               cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr);
+               out_be16(i2c_base, cpm->i2c_addr);
+               iounmap(i2c_base);
+
+               cpm->version = 2;
+
+       } else {
+               iounmap(i2c_base);
+               ret = -EINVAL;
+               goto out_irq;
+       }
+
+       /* I2C control/status registers */
+       cpm->i2c_reg = of_iomap(ofdev->node, 0);
+       if (cpm->i2c_reg == NULL) {
+               ret = -EINVAL;
+               goto out_ram;
+       }
+
+       data = of_get_property(ofdev->node, "fsl,cpm-command", &len);
+       if (!data || len != 4) {
+               ret = -EINVAL;
+               goto out_reg;
+       }
+       cpm->cp_command = *data;
+
+       data = of_get_property(ofdev->node, "linux,i2c-class", &len);
+       if (data && len == 4)
+               cpm->adap.class = *data;
+
+       data = of_get_property(ofdev->node, "clock-frequency", &len);
+       if (data && len == 4)
+               cpm->freq = *data;
+       else
+               cpm->freq = 60000; /* use 60kHz i2c clock by default */
+
+       /*
+        * Allocate space for CPM_MAXBD transmit and receive buffer
+        * descriptors in the DP ram.
+        */
+       cpm->dp_addr = cpm_muram_alloc(sizeof(cbd_t) * 2 * CPM_MAXBD, 8);
+       if (!cpm->dp_addr) {
+               ret = -ENOMEM;
+               goto out_reg;
+       }
+
+       cpm->tbase = cpm_muram_addr(cpm->dp_addr);
+       cpm->rbase = cpm_muram_addr(cpm->dp_addr + sizeof(cbd_t) * CPM_MAXBD);
+
+       /* Allocate TX and RX buffers */
+
+       tbdf = cpm->tbase;
+       rbdf = cpm->rbase;
+
+       for (i = 0; i < CPM_MAXBD; i++) {
+               cpm->rxbuf[i] = dma_alloc_coherent(
+                       NULL, CPM_MAX_READ + 1, &cpm->rxdma[i], GFP_KERNEL);
+               if (!cpm->rxbuf[i]) {
+                       ret = -ENOMEM;
+                       goto out_muram;
+               }
+               out_be32(&rbdf[i].cbd_bufaddr, ((cpm->rxdma[i] + 1) & ~1));
+
+               cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(
+                       NULL, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL);
+               if (!cpm->txbuf[i]) {
+                       ret = -ENOMEM;
+                       goto out_muram;
+               }
+               out_be32(&tbdf[i].cbd_bufaddr, cpm->txdma[i]);
+       }
+
+       /* Initialize Tx/Rx parameters. */
+
+       cpm_reset_i2c_params(cpm);
+
+       dev_dbg(&cpm->ofdev->dev, "i2c_ram 0x%p, i2c_addr 0x%04x, freq %d\n",
+               cpm->i2c_ram, cpm->i2c_addr, cpm->freq);
+       dev_dbg(&cpm->ofdev->dev, "tbase 0x%04x, rbase 0x%04x\n",
+               (u8 __iomem *)cpm->tbase - DPRAM_BASE,
+               (u8 __iomem *)cpm->rbase - DPRAM_BASE);
+
+       cpm_command(cpm->cp_command, CPM_CR_INIT_TRX);
+
+       /*
+        * Select an invalid address. Just make sure we don't use loopback mode
+        */
+       out_8(&cpm->i2c_reg->i2add, 0x7f << 1);
+
+       /*
+        * PDIV is set to 00 in i2mod, so brgclk/32 is used as input to the
+        * i2c baud rate generator. This is divided by 2 x (DIV + 3) to get
+        * the actual i2c bus frequency.
+        */
+       brg = get_brgfreq() / (32 * 2 * cpm->freq) - 3;
+       out_8(&cpm->i2c_reg->i2brg, brg);
+
+       out_8(&cpm->i2c_reg->i2mod, 0x00);
+       out_8(&cpm->i2c_reg->i2com, I2COM_MASTER);      /* Master mode */
+
+       /* Disable interrupts. */
+       out_8(&cpm->i2c_reg->i2cmr, 0);
+       out_8(&cpm->i2c_reg->i2cer, 0xff);
+
+       return 0;
+
+out_muram:
+       for (i = 0; i < CPM_MAXBD; i++) {
+               if (cpm->rxbuf[i])
+                       dma_free_coherent(NULL, CPM_MAX_READ + 1,
+                               cpm->rxbuf[i], cpm->rxdma[i]);
+               if (cpm->txbuf[i])
+                       dma_free_coherent(NULL, CPM_MAX_READ + 1,
+                               cpm->txbuf[i], cpm->txdma[i]);
+       }
+       cpm_muram_free(cpm->dp_addr);
+out_reg:
+       iounmap(cpm->i2c_reg);
+out_ram:
+       if ((cpm->version == 1) && (!cpm->i2c_addr))
+               iounmap(cpm->i2c_ram);
+       if (cpm->version == 2)
+               cpm_muram_free(cpm->i2c_addr);
+out_irq:
+       free_irq(cpm->irq, &cpm->adap);
+       return ret;
+}
+
+static void cpm_i2c_shutdown(struct cpm_i2c *cpm)
+{
+       int i;
+
+       /* Shut down I2C. */
+       clrbits8(&cpm->i2c_reg->i2mod, I2MOD_EN);
+
+       /* Disable interrupts */
+       out_8(&cpm->i2c_reg->i2cmr, 0);
+       out_8(&cpm->i2c_reg->i2cer, 0xff);
+
+       free_irq(cpm->irq, &cpm->adap);
+
+       /* Free all memory */
+       for (i = 0; i < CPM_MAXBD; i++) {
+               dma_free_coherent(NULL, CPM_MAX_READ + 1,
+                       cpm->rxbuf[i], cpm->rxdma[i]);
+               dma_free_coherent(NULL, CPM_MAX_READ + 1,
+                       cpm->txbuf[i], cpm->txdma[i]);
+       }
+
+       cpm_muram_free(cpm->dp_addr);
+       iounmap(cpm->i2c_reg);
+
+       if ((cpm->version == 1) && (!cpm->i2c_addr))
+               iounmap(cpm->i2c_ram);
+       if (cpm->version == 2)
+               cpm_muram_free(cpm->i2c_addr);
+}
+
+static int __devinit cpm_i2c_probe(struct of_device *ofdev,
+                        const struct of_device_id *match)
+{
+       int result, len;
+       struct cpm_i2c *cpm;
+       const u32 *data;
+
+       cpm = kzalloc(sizeof(struct cpm_i2c), GFP_KERNEL);
+       if (!cpm)
+               return -ENOMEM;
+
+       cpm->ofdev = ofdev;
+
+       dev_set_drvdata(&ofdev->dev, cpm);
+
+       cpm->adap = cpm_ops;
+       i2c_set_adapdata(&cpm->adap, cpm);
+       cpm->adap.dev.parent = &ofdev->dev;
+
+       result = cpm_i2c_setup(cpm);
+       if (result) {
+               dev_err(&ofdev->dev, "Unable to init hardware\n");
+               goto out_free;
+       }
+
+       /* register new adapter to i2c module... */
+
+       data = of_get_property(ofdev->node, "linux,i2c-index", &len);
+       if (data && len == 4) {
+               cpm->adap.nr = *data;
+               result = i2c_add_numbered_adapter(&cpm->adap);
+       } else
+               result = i2c_add_adapter(&cpm->adap);
+
+       if (result < 0) {
+               dev_err(&ofdev->dev, "Unable to register with I2C\n");
+               goto out_shut;
+       }
+
+       dev_dbg(&ofdev->dev, "hw routines for %s registered.\n",
+               cpm->adap.name);
+
+       /*
+        * register OF I2C devices
+        */
+       of_register_i2c_devices(&cpm->adap, ofdev->node);
+
+       return 0;
+out_shut:
+       cpm_i2c_shutdown(cpm);
+out_free:
+       dev_set_drvdata(&ofdev->dev, NULL);
+       kfree(cpm);
+
+       return result;
+}
+
+static int __devexit cpm_i2c_remove(struct of_device *ofdev)
+{
+       struct cpm_i2c *cpm = dev_get_drvdata(&ofdev->dev);
+
+       i2c_del_adapter(&cpm->adap);
+
+       cpm_i2c_shutdown(cpm);
+
+       dev_set_drvdata(&ofdev->dev, NULL);
+       kfree(cpm);
+
+       return 0;
+}
+
+static const struct of_device_id cpm_i2c_match[] = {
+       {
+               .compatible = "fsl,cpm1-i2c",
+       },
+       {
+               .compatible = "fsl,cpm2-i2c",
+       },
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, cpm_i2c_match);
+
+static struct of_platform_driver cpm_i2c_driver = {
+       .match_table    = cpm_i2c_match,
+       .probe          = cpm_i2c_probe,
+       .remove         = __devexit_p(cpm_i2c_remove),
+       .driver         = {
+               .name   = "fsl-i2c-cpm",
+               .owner  = THIS_MODULE,
+       }
+};
+
+static int __init cpm_i2c_init(void)
+{
+       return of_register_platform_driver(&cpm_i2c_driver);
+}
+
+static void __exit cpm_i2c_exit(void)
+{
+       of_unregister_platform_driver(&cpm_i2c_driver);
+}
+
+module_init(cpm_i2c_init);
+module_exit(cpm_i2c_exit);
+
+MODULE_AUTHOR("Jochen Friedrich <jochen@scram.de>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for CPM boards");
+MODULE_LICENSE("GPL");
index 7ecbfc4..af3846e 100644 (file)
@@ -85,6 +85,7 @@
 #define DAVINCI_I2C_MDR_MST    (1 << 10)
 #define DAVINCI_I2C_MDR_TRX    (1 << 9)
 #define DAVINCI_I2C_MDR_XA     (1 << 8)
+#define DAVINCI_I2C_MDR_RM     (1 << 7)
 #define DAVINCI_I2C_MDR_IRS    (1 << 5)
 
 #define DAVINCI_I2C_IMR_AAS    (1 << 6)
@@ -112,6 +113,7 @@ struct davinci_i2c_dev {
        u8                      *buf;
        size_t                  buf_len;
        int                     irq;
+       u8                      terminate;
        struct i2c_adapter      adapter;
 };
 
@@ -142,6 +144,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
        struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
        u16 psc;
        u32 clk;
+       u32 d;
        u32 clkh;
        u32 clkl;
        u32 input_clock = clk_get_rate(dev->clk);
@@ -171,23 +174,29 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
         *       if PSC > 1 , d = 5
         */
 
-       psc = 26; /* To get 1MHz clock */
+       /* get minimum of 7 MHz clock, but max of 12 MHz */
+       psc = (input_clock / 7000000) - 1;
+       if ((input_clock / (psc + 1)) > 12000000)
+               psc++;  /* better to run under spec than over */
+       d = (psc >= 2) ? 5 : 7 - psc;
 
-       clk = ((input_clock / (psc + 1)) / (pdata->bus_freq * 1000)) - 10;
-       clkh = (50 * clk) / 100;
+       clk = ((input_clock / (psc + 1)) / (pdata->bus_freq * 1000)) - (d << 1);
+       clkh = clk >> 1;
        clkl = clk - clkh;
 
        davinci_i2c_write_reg(dev, DAVINCI_I2C_PSC_REG, psc);
        davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh);
        davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl);
 
-       dev_dbg(dev->dev, "CLK  = %d\n", clk);
+       dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
        dev_dbg(dev->dev, "PSC  = %d\n",
                davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG));
        dev_dbg(dev->dev, "CLKL = %d\n",
                davinci_i2c_read_reg(dev, DAVINCI_I2C_CLKL_REG));
        dev_dbg(dev->dev, "CLKH = %d\n",
                davinci_i2c_read_reg(dev, DAVINCI_I2C_CLKH_REG));
+       dev_dbg(dev->dev, "bus_freq = %dkHz, bus_delay = %d\n",
+               pdata->bus_freq, pdata->bus_delay);
 
        /* Take the I2C module out of reset: */
        w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
@@ -233,7 +242,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
        struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
        struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
        u32 flag;
-       u32 stat;
        u16 w;
        int r;
 
@@ -254,12 +262,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
 
        davinci_i2c_write_reg(dev, DAVINCI_I2C_CNT_REG, dev->buf_len);
 
-       init_completion(&dev->cmd_complete);
+       INIT_COMPLETION(dev->cmd_complete);
        dev->cmd_err = 0;
 
-       /* Clear any pending interrupts by reading the IVR */
-       stat = davinci_i2c_read_reg(dev, DAVINCI_I2C_IVR_REG);
-
        /* Take I2C out of reset, configure it as master and set the
         * start bit */
        flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST | DAVINCI_I2C_MDR_STT;
@@ -280,20 +285,34 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
                MOD_REG_BIT(w, DAVINCI_I2C_IMR_XRDY, 1);
        davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w);
 
+       dev->terminate = 0;
        /* write the data into mode register */
        davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
 
        r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
                                                      DAVINCI_I2C_TIMEOUT);
-       dev->buf_len = 0;
-       if (r < 0)
-               return r;
-
        if (r == 0) {
                dev_err(dev->dev, "controller timed out\n");
                i2c_davinci_init(dev);
+               dev->buf_len = 0;
                return -ETIMEDOUT;
        }
+       if (dev->buf_len) {
+               /* This should be 0 if all bytes were transferred
+                * or dev->cmd_err denotes an error.
+                * A signal may have aborted the transfer.
+                */
+               if (r >= 0) {
+                       dev_err(dev->dev, "abnormal termination buf_len=%i\n",
+                               dev->buf_len);
+                       r = -EREMOTEIO;
+               }
+               dev->terminate = 1;
+               wmb();
+               dev->buf_len = 0;
+       }
+       if (r < 0)
+               return r;
 
        /* no error */
        if (likely(!dev->cmd_err))
@@ -338,12 +357,11 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 
        for (i = 0; i < num; i++) {
                ret = i2c_davinci_xfer_msg(adap, &msgs[i], (i == (num - 1)));
+               dev_dbg(dev->dev, "%s [%d/%d] ret: %d\n", __func__, i + 1, num,
+                       ret);
                if (ret < 0)
                        return ret;
        }
-
-       dev_dbg(dev->dev, "%s:%d ret: %d\n", __func__, __LINE__, ret);
-
        return num;
 }
 
@@ -352,6 +370,27 @@ static u32 i2c_davinci_func(struct i2c_adapter *adap)
        return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
 }
 
+static void terminate_read(struct davinci_i2c_dev *dev)
+{
+       u16 w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
+       w |= DAVINCI_I2C_MDR_NACK;
+       davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
+
+       /* Throw away data */
+       davinci_i2c_read_reg(dev, DAVINCI_I2C_DRR_REG);
+       if (!dev->terminate)
+               dev_err(dev->dev, "RDR IRQ while no data requested\n");
+}
+static void terminate_write(struct davinci_i2c_dev *dev)
+{
+       u16 w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
+       w |= DAVINCI_I2C_MDR_RM | DAVINCI_I2C_MDR_STP;
+       davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
+
+       if (!dev->terminate)
+               dev_err(dev->dev, "TDR IRQ while no data to send\n");
+}
+
 /*
  * Interrupt service routine. This gets called whenever an I2C interrupt
  * occurs.
@@ -372,12 +411,15 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
 
                switch (stat) {
                case DAVINCI_I2C_IVR_AL:
+                       /* Arbitration lost, must retry */
                        dev->cmd_err |= DAVINCI_I2C_STR_AL;
+                       dev->buf_len = 0;
                        complete(&dev->cmd_complete);
                        break;
 
                case DAVINCI_I2C_IVR_NACK:
                        dev->cmd_err |= DAVINCI_I2C_STR_NACK;
+                       dev->buf_len = 0;
                        complete(&dev->cmd_complete);
                        break;
 
@@ -399,9 +441,10 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
                                davinci_i2c_write_reg(dev,
                                        DAVINCI_I2C_STR_REG,
                                        DAVINCI_I2C_IMR_RRDY);
-                       } else
-                               dev_err(dev->dev, "RDR IRQ while no "
-                                       "data requested\n");
+                       } else {
+                               /* signal can terminate transfer */
+                               terminate_read(dev);
+                       }
                        break;
 
                case DAVINCI_I2C_IVR_XRDY:
@@ -418,9 +461,10 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
                                davinci_i2c_write_reg(dev,
                                                      DAVINCI_I2C_IMR_REG,
                                                      w);
-                       } else
-                               dev_err(dev->dev, "TDR IRQ while no data to "
-                                       "send\n");
+                       } else {
+                               /* signal can terminate transfer */
+                               terminate_write(dev);
+                       }
                        break;
 
                case DAVINCI_I2C_IVR_SCD:
@@ -475,6 +519,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
                goto err_release_region;
        }
 
+       init_completion(&dev->cmd_complete);
        dev->dev = get_device(&pdev->dev);
        dev->irq = irq->start;
        platform_set_drvdata(pdev, dev);
index b7a9977..7f38c01 100644 (file)
@@ -196,13 +196,11 @@ static struct i2c_algo_pcf_data pcf_isa_data = {
        .getown     = pcf_isa_getown,
        .getclock   = pcf_isa_getclock,
        .waitforpin = pcf_isa_waitforpin,
-       .udelay     = 10,
-       .timeout    = 100,
 };
 
 static struct i2c_adapter pcf_isa_ops = {
        .owner          = THIS_MODULE,
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .id             = I2C_HW_P_ELEK,
        .algo_data      = &pcf_isa_data,
        .name           = "i2c-elektor",
index 7c1b762..79b455a 100644 (file)
@@ -140,7 +140,7 @@ static int __init i2c_gpio_probe(struct platform_device *pdev)
        adap->owner = THIS_MODULE;
        snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id);
        adap->algo_data = bit_data;
-       adap->class = I2C_CLASS_HWMON;
+       adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
        adap->dev.parent = &pdev->dev;
 
        /*
index f9972f9..1098f21 100644 (file)
@@ -1,7 +1,4 @@
 /*
-    i2c-hydra.c - Part of lm_sensors,  Linux kernel modules
-                  for hardware monitoring
-
     i2c Support for the Apple `Hydra' Mac I/O
 
     Copyright (c) 1999-2004 Geert Uytterhoeven <geert@linux-m68k.org>
index b0f771f..dc7ea32 100644 (file)
@@ -1,10 +1,8 @@
 /*
-    i2c-i801.c - Part of lm_sensors, Linux kernel modules for hardware
-              monitoring
     Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
     Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker
     <mdsxyz123@yahoo.com>
-    Copyright (C) 2007         Jean Delvare <khali@linux-fr.org>
+    Copyright (C) 2007, 2008   Jean Delvare <khali@linux-fr.org>
 
     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
@@ -64,6 +62,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 */
 #define SMBHSTSTS_INTR         0x02
 #define SMBHSTSTS_HOST_BUSY    0x01
 
+#define STATUS_FLAGS           (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_FAILED | \
+                                SMBHSTSTS_BUS_ERR | SMBHSTSTS_DEV_ERR | \
+                                SMBHSTSTS_INTR)
+
 static unsigned long i801_smba;
 static unsigned char i801_original_hstcfg;
 static struct pci_driver i801_driver;
@@ -132,105 +135,137 @@ static struct pci_dev *I801_dev;
 #define FEATURE_I2C_BLOCK_READ (1 << 3)
 static unsigned int i801_features;
 
-static int i801_transaction(int xact)
+/* Make sure the SMBus host is ready to start transmitting.
+   Return 0 if it is, -EBUSY if it is not. */
+static int i801_check_pre(void)
 {
-       int temp;
-       int result = 0;
-       int timeout = 0;
+       int status;
 
-       dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x, "
-               "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
-               inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
-               inb_p(SMBHSTDAT1));
-
-       /* Make sure the SMBus host is ready to start transmitting */
-       /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
-       if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
-               dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting...\n",
-                       temp);
-               outb_p(temp, SMBHSTSTS);
-               if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
-                       dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", temp);
-                       return -1;
-               } else {
-                       dev_dbg(&I801_dev->dev, "Successful!\n");
+       status = inb_p(SMBHSTSTS);
+       if (status & SMBHSTSTS_HOST_BUSY) {
+               dev_err(&I801_dev->dev, "SMBus is busy, can't use it!\n");
+               return -EBUSY;
+       }
+
+       status &= STATUS_FLAGS;
+       if (status) {
+               dev_dbg(&I801_dev->dev, "Clearing status flags (%02x)\n",
+                       status);
+               outb_p(status, SMBHSTSTS);
+               status = inb_p(SMBHSTSTS) & STATUS_FLAGS;
+               if (status) {
+                       dev_err(&I801_dev->dev,
+                               "Failed clearing status flags (%02x)\n",
+                               status);
+                       return -EBUSY;
                }
        }
 
-       /* the current contents of SMBHSTCNT can be overwritten, since PEC,
-        * INTREN, SMBSCMD are passed in xact */
-       outb_p(xact | I801_START, SMBHSTCNT);
+       return 0;
+}
 
-       /* We will always wait for a fraction of a second! */
-       do {
-               msleep(1);
-               temp = inb_p(SMBHSTSTS);
-       } while ((temp & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT));
+/* Convert the status register to an error code, and clear it. */
+static int i801_check_post(int status, int timeout)
+{
+       int result = 0;
 
        /* If the SMBus is still busy, we give up */
-       if (timeout >= MAX_TIMEOUT) {
-               dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
-               result = -1;
+       if (timeout) {
+               dev_err(&I801_dev->dev, "Transaction timeout\n");
                /* try to stop the current command */
                dev_dbg(&I801_dev->dev, "Terminating the current operation\n");
                outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
                msleep(1);
                outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL), SMBHSTCNT);
-       }
 
-       if (temp & SMBHSTSTS_FAILED) {
-               result = -1;
-               dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n");
+               /* Check if it worked */
+               status = inb_p(SMBHSTSTS);
+               if ((status & SMBHSTSTS_HOST_BUSY) ||
+                   !(status & SMBHSTSTS_FAILED))
+                       dev_err(&I801_dev->dev,
+                               "Failed terminating the transaction\n");
+               outb_p(STATUS_FLAGS, SMBHSTSTS);
+               return -ETIMEDOUT;
        }
 
-       if (temp & SMBHSTSTS_BUS_ERR) {
-               result = -1;
-               dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked "
-                       "until next hard reset. (sorry!)\n");
-               /* Clock stops and slave is stuck in mid-transmission */
+       if (status & SMBHSTSTS_FAILED) {
+               result = -EIO;
+               dev_err(&I801_dev->dev, "Transaction failed\n");
        }
-
-       if (temp & SMBHSTSTS_DEV_ERR) {
-               result = -1;
-               dev_dbg(&I801_dev->dev, "Error: no response!\n");
+       if (status & SMBHSTSTS_DEV_ERR) {
+               result = -ENXIO;
+               dev_dbg(&I801_dev->dev, "No response\n");
+       }
+       if (status & SMBHSTSTS_BUS_ERR) {
+               result = -EAGAIN;
+               dev_dbg(&I801_dev->dev, "Lost arbitration\n");
        }
 
-       if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00)
-               outb_p(inb(SMBHSTSTS), SMBHSTSTS);
-
-       if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
-               dev_dbg(&I801_dev->dev, "Failed reset at end of transaction "
-                       "(%02x)\n", temp);
+       if (result) {
+               /* Clear error flags */
+               outb_p(status & STATUS_FLAGS, SMBHSTSTS);
+               status = inb_p(SMBHSTSTS) & STATUS_FLAGS;
+               if (status) {
+                       dev_warn(&I801_dev->dev, "Failed clearing status "
+                                "flags at end of transaction (%02x)\n",
+                                status);
+               }
        }
-       dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, "
-               "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
-               inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
-               inb_p(SMBHSTDAT1));
+
        return result;
 }
 
+static int i801_transaction(int xact)
+{
+       int status;
+       int result;
+       int timeout = 0;
+
+       result = i801_check_pre();
+       if (result < 0)
+               return result;
+
+       /* the current contents of SMBHSTCNT can be overwritten, since PEC,
+        * INTREN, SMBSCMD are passed in xact */
+       outb_p(xact | I801_START, SMBHSTCNT);
+
+       /* We will always wait for a fraction of a second! */
+       do {
+               msleep(1);
+               status = inb_p(SMBHSTSTS);
+       } while ((status & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT));
+
+       result = i801_check_post(status, timeout >= MAX_TIMEOUT);
+       if (result < 0)
+               return result;
+
+       outb_p(SMBHSTSTS_INTR, SMBHSTSTS);
+       return 0;
+}
+
 /* wait for INTR bit as advised by Intel */
 static void i801_wait_hwpec(void)
 {
        int timeout = 0;
-       int temp;
+       int status;
 
        do {
                msleep(1);
-               temp = inb_p(SMBHSTSTS);
-       } while ((!(temp & SMBHSTSTS_INTR))
+               status = inb_p(SMBHSTSTS);
+       } while ((!(status & SMBHSTSTS_INTR))
                 && (timeout++ < MAX_TIMEOUT));
 
        if (timeout >= MAX_TIMEOUT) {
                dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
        }
-       outb_p(temp, SMBHSTSTS);
+       outb_p(status, SMBHSTSTS);
 }
 
 static int i801_block_transaction_by_block(union i2c_smbus_data *data,
                                           char read_write, int hwpec)
 {
        int i, len;
+       int status;
 
        inb_p(SMBHSTCNT); /* reset the data buffer index */
 
@@ -242,14 +277,15 @@ static int i801_block_transaction_by_block(union i2c_smbus_data *data,
                        outb_p(data->block[i+1], SMBBLKDAT);
        }
 
-       if (i801_transaction(I801_BLOCK_DATA | ENABLE_INT9 |
-                            I801_PEC_EN * hwpec))
-               return -1;
+       status = i801_transaction(I801_BLOCK_DATA | ENABLE_INT9 |
+                                 I801_PEC_EN * hwpec);
+       if (status)
+               return status;
 
        if (read_write == I2C_SMBUS_READ) {
                len = inb_p(SMBHSTDAT0);
                if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
-                       return -1;
+                       return -EPROTO;
 
                data->block[0] = len;
                for (i = 0; i < len; i++)
@@ -264,10 +300,13 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
 {
        int i, len;
        int smbcmd;
-       int temp;
-       int result = 0;
+       int status;
+       int result;
        int timeout;
-       unsigned char errmask;
+
+       result = i801_check_pre();
+       if (result < 0)
+               return result;
 
        len = data->block[0];
 
@@ -291,36 +330,6 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
                }
                outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT);
 
-               dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, "
-                       "ADD=%02x, DAT0=%02x, DAT1=%02x, BLKDAT=%02x\n", i,
-                       inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
-                       inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1), inb_p(SMBBLKDAT));
-
-               /* Make sure the SMBus host is ready to start transmitting */
-               temp = inb_p(SMBHSTSTS);
-               if (i == 1) {
-                       /* Erroneous conditions before transaction:
-                        * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
-                       errmask = 0x9f;
-               } else {
-                       /* Erroneous conditions during transaction:
-                        * Failed, Bus_Err, Dev_Err, Intr */
-                       errmask = 0x1e;
-               }
-               if (temp & errmask) {
-                       dev_dbg(&I801_dev->dev, "SMBus busy (%02x). "
-                               "Resetting...\n", temp);
-                       outb_p(temp, SMBHSTSTS);
-                       if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) {
-                               dev_err(&I801_dev->dev,
-                                       "Reset failed! (%02x)\n", temp);
-                               return -1;
-                       }
-                       if (i != 1)
-                               /* if die in middle of block transaction, fail */
-                               return -1;
-               }
-
                if (i == 1)
                        outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);
 
@@ -328,41 +337,28 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
                timeout = 0;
                do {
                        msleep(1);
-                       temp = inb_p(SMBHSTSTS);
+                       status = inb_p(SMBHSTSTS);
                }
-               while ((!(temp & SMBHSTSTS_BYTE_DONE))
+               while ((!(status & SMBHSTSTS_BYTE_DONE))
                       && (timeout++ < MAX_TIMEOUT));
 
-               /* If the SMBus is still busy, we give up */
-               if (timeout >= MAX_TIMEOUT) {
-                       /* try to stop the current command */
-                       dev_dbg(&I801_dev->dev, "Terminating the current "
-                                               "operation\n");
-                       outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
-                       msleep(1);
-                       outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL),
-                               SMBHSTCNT);
-                       result = -1;
-                       dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
-               }
-
-               if (temp & SMBHSTSTS_FAILED) {
-                       result = -1;
-                       dev_dbg(&I801_dev->dev,
-                               "Error: Failed bus transaction\n");
-               } else if (temp & SMBHSTSTS_BUS_ERR) {
-                       result = -1;
-                       dev_err(&I801_dev->dev, "Bus collision!\n");
-               } else if (temp & SMBHSTSTS_DEV_ERR) {
-                       result = -1;
-                       dev_dbg(&I801_dev->dev, "Error: no response!\n");
-               }
+               result = i801_check_post(status, timeout >= MAX_TIMEOUT);
+               if (result < 0)
+                       return result;
 
                if (i == 1 && read_write == I2C_SMBUS_READ
                 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
                        len = inb_p(SMBHSTDAT0);
-                       if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
-                               return -1;
+                       if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) {
+                               dev_err(&I801_dev->dev,
+                                       "Illegal SMBus block read size %d\n",
+                                       len);
+                               /* Recover */
+                               while (inb_p(SMBHSTSTS) & SMBHSTSTS_HOST_BUSY)
+                                       outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS);
+                               outb_p(SMBHSTSTS_INTR, SMBHSTSTS);
+                               return -EPROTO;
+                       }
                        data->block[0] = len;
                }
 
@@ -371,30 +367,19 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
                        data->block[i] = inb_p(SMBBLKDAT);
                if (read_write == I2C_SMBUS_WRITE && i+1 <= len)
                        outb_p(data->block[i+1], SMBBLKDAT);
-               if ((temp & 0x9e) != 0x00)
-                       outb_p(temp, SMBHSTSTS);  /* signals SMBBLKDAT ready */
-
-               if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) {
-                       dev_dbg(&I801_dev->dev,
-                               "Bad status (%02x) at end of transaction\n",
-                               temp);
-               }
-               dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, "
-                       "ADD=%02x, DAT0=%02x, DAT1=%02x, BLKDAT=%02x\n", i,
-                       inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
-                       inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1), inb_p(SMBBLKDAT));
 
-               if (result < 0)
-                       return result;
+               /* signals SMBBLKDAT ready */
+               outb_p(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR, SMBHSTSTS);
        }
-       return result;
+
+       return 0;
 }
 
 static int i801_set_block_buffer_mode(void)
 {
        outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_E32B, SMBAUXCTL);
        if ((inb_p(SMBAUXCTL) & SMBAUXCTL_E32B) == 0)
-               return -1;
+               return -EIO;
        return 0;
 }
 
@@ -414,7 +399,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
                } else if (!(i801_features & FEATURE_I2C_BLOCK_READ)) {
                        dev_err(&I801_dev->dev,
                                "I2C block read is unsupported!\n");
-                       return -1;
+                       return -EOPNOTSUPP;
                }
        }
 
@@ -449,7 +434,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
        return result;
 }
 
-/* Return -1 on error. */
+/* Return negative errno on error. */
 static s32 i801_access(struct i2c_adapter * adap, u16 addr,
                       unsigned short flags, char read_write, u8 command,
                       int size, union i2c_smbus_data * data)
@@ -511,10 +496,9 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
                        outb_p(command, SMBHSTCMD);
                block = 1;
                break;
-       case I2C_SMBUS_PROC_CALL:
        default:
                dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size);
-               return -1;
+               return -EOPNOTSUPP;
        }
 
        if (hwpec)      /* enable/disable hardware PEC */
@@ -537,7 +521,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
        if(block)
                return ret;
        if(ret)
-               return -1;
+               return ret;
        if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
                return 0;
 
@@ -572,7 +556,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 static struct i2c_adapter i801_adapter = {
        .owner          = THIS_MODULE,
        .id             = I2C_HW_SMBUS_I801,
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .algo           = &smbus_algorithm,
 };
 
@@ -639,6 +623,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 "
diff --git a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c
deleted file mode 100644 (file)
index 42e8d94..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
-    i2c-i810.c - Part of lm_sensors, Linux kernel modules for hardware
-              monitoring
-    Copyright (c) 1998, 1999, 2000  Frodo Looijaard <frodol@dds.nl>,
-    Philip Edelbrock <phil@netroedge.com>,
-    Ralph Metzler <rjkm@thp.uni-koeln.de>, and
-    Mark D. Studebaker <mdsxyz123@yahoo.com>
-    
-    Based on code written by Ralph Metzler <rjkm@thp.uni-koeln.de> and
-    Simon Vogl
-
-    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.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-/*
-   This interfaces to the I810/I815 to provide access to
-   the DDC Bus and the I2C Bus.
-
-   SUPPORTED DEVICES   PCI ID
-   i810AA              7121           
-   i810AB              7123           
-   i810E               7125           
-   i815                        1132           
-   i845G               2562
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <asm/io.h>
-
-/* GPIO register locations */
-#define I810_IOCONTROL_OFFSET  0x5000
-#define I810_HVSYNC            0x00    /* not used */
-#define I810_GPIOA             0x10
-#define I810_GPIOB             0x14
-
-/* bit locations in the registers */
-#define SCL_DIR_MASK           0x0001
-#define SCL_DIR                        0x0002
-#define SCL_VAL_MASK           0x0004
-#define SCL_VAL_OUT            0x0008
-#define SCL_VAL_IN             0x0010
-#define SDA_DIR_MASK           0x0100
-#define SDA_DIR                        0x0200
-#define SDA_VAL_MASK           0x0400
-#define SDA_VAL_OUT            0x0800
-#define SDA_VAL_IN             0x1000
-
-/* initialization states */
-#define INIT1                  0x1
-#define INIT2                  0x2
-#define INIT3                  0x4
-
-/* delays */
-#define CYCLE_DELAY            10
-#define TIMEOUT                        (HZ / 2)
-
-static void __iomem *ioaddr;
-
-/* The i810 GPIO registers have individual masks for each bit
-   so we never have to read before writing. Nice. */
-
-static void bit_i810i2c_setscl(void *data, int val)
-{
-       writel((val ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK,
-            ioaddr + I810_GPIOB);
-       readl(ioaddr + I810_GPIOB);     /* flush posted write */
-}
-
-static void bit_i810i2c_setsda(void *data, int val)
-{
-       writel((val ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK,
-            ioaddr + I810_GPIOB);
-       readl(ioaddr + I810_GPIOB);     /* flush posted write */
-}
-
-/* The GPIO pins are open drain, so the pins could always remain outputs.
-   However, some chip versions don't latch the inputs unless they
-   are set as inputs.
-   We rely on the i2c-algo-bit routines to set the pins high before
-   reading the input from other chips. Following guidance in the 815
-   prog. ref. guide, we do a "dummy write" of 0 to the register before
-   reading which forces the input value to be latched. We presume this
-   applies to the 810 as well; shouldn't hurt anyway. This is necessary to get
-   i2c_algo_bit bit_test=1 to pass. */
-
-static int bit_i810i2c_getscl(void *data)
-{
-       writel(SCL_DIR_MASK, ioaddr + I810_GPIOB);
-       writel(0, ioaddr + I810_GPIOB);
-       return (0 != (readl(ioaddr + I810_GPIOB) & SCL_VAL_IN));
-}
-
-static int bit_i810i2c_getsda(void *data)
-{
-       writel(SDA_DIR_MASK, ioaddr + I810_GPIOB);
-       writel(0, ioaddr + I810_GPIOB);
-       return (0 != (readl(ioaddr + I810_GPIOB) & SDA_VAL_IN));
-}
-
-static void bit_i810ddc_setscl(void *data, int val)
-{
-       writel((val ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK,
-            ioaddr + I810_GPIOA);
-       readl(ioaddr + I810_GPIOA);     /* flush posted write */
-}
-
-static void bit_i810ddc_setsda(void *data, int val)
-{
-       writel((val ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK,
-            ioaddr + I810_GPIOA);
-       readl(ioaddr + I810_GPIOA);     /* flush posted write */
-}
-
-static int bit_i810ddc_getscl(void *data)
-{
-       writel(SCL_DIR_MASK, ioaddr + I810_GPIOA);
-       writel(0, ioaddr + I810_GPIOA);
-       return (0 != (readl(ioaddr + I810_GPIOA) & SCL_VAL_IN));
-}
-
-static int bit_i810ddc_getsda(void *data)
-{
-       writel(SDA_DIR_MASK, ioaddr + I810_GPIOA);
-       writel(0, ioaddr + I810_GPIOA);
-       return (0 != (readl(ioaddr + I810_GPIOA) & SDA_VAL_IN));
-}
-
-static int config_i810(struct pci_dev *dev)
-{
-       unsigned long cadr;
-
-       /* map I810 memory */
-       cadr = dev->resource[1].start;
-       cadr += I810_IOCONTROL_OFFSET;
-       cadr &= PCI_BASE_ADDRESS_MEM_MASK;
-       ioaddr = ioremap_nocache(cadr, 0x1000);
-       if (ioaddr) {
-               bit_i810i2c_setscl(NULL, 1);
-               bit_i810i2c_setsda(NULL, 1);
-               bit_i810ddc_setscl(NULL, 1);
-               bit_i810ddc_setsda(NULL, 1);
-               return 0;
-       }
-       return -ENODEV;
-}
-
-static struct i2c_algo_bit_data i810_i2c_bit_data = {
-       .setsda         = bit_i810i2c_setsda,
-       .setscl         = bit_i810i2c_setscl,
-       .getsda         = bit_i810i2c_getsda,
-       .getscl         = bit_i810i2c_getscl,
-       .udelay         = CYCLE_DELAY,
-       .timeout        = TIMEOUT,
-};
-
-static struct i2c_adapter i810_i2c_adapter = {
-       .owner          = THIS_MODULE,
-       .id             = I2C_HW_B_I810,
-       .name           = "I810/I815 I2C Adapter",
-       .algo_data      = &i810_i2c_bit_data,
-};
-
-static struct i2c_algo_bit_data i810_ddc_bit_data = {
-       .setsda         = bit_i810ddc_setsda,
-       .setscl         = bit_i810ddc_setscl,
-       .getsda         = bit_i810ddc_getsda,
-       .getscl         = bit_i810ddc_getscl,
-       .udelay         = CYCLE_DELAY,
-       .timeout        = TIMEOUT,
-};
-
-static struct i2c_adapter i810_ddc_adapter = {
-       .owner          = THIS_MODULE,
-       .id             = I2C_HW_B_I810,
-       .name           = "I810/I815 DDC Adapter",
-       .algo_data      = &i810_ddc_bit_data,
-};
-
-static struct pci_device_id i810_ids[] __devinitdata = {
-       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG1) },
-       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3) },
-       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
-       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
-       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
-       { 0, },
-};
-
-MODULE_DEVICE_TABLE (pci, i810_ids);
-
-static int __devinit i810_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
-       int retval;
-
-       retval = config_i810(dev);
-       if (retval)
-               return retval;
-       dev_info(&dev->dev, "i810/i815 i2c device found.\n");
-
-       /* set up the sysfs linkage to our parent device */
-       i810_i2c_adapter.dev.parent = &dev->dev;
-       i810_ddc_adapter.dev.parent = &dev->dev;
-
-       retval = i2c_bit_add_bus(&i810_i2c_adapter);
-       if (retval)
-               return retval;
-       retval = i2c_bit_add_bus(&i810_ddc_adapter);
-       if (retval)
-               i2c_del_adapter(&i810_i2c_adapter);
-       return retval;
-}
-
-static void __devexit i810_remove(struct pci_dev *dev)
-{
-       i2c_del_adapter(&i810_ddc_adapter);
-       i2c_del_adapter(&i810_i2c_adapter);
-       iounmap(ioaddr);
-}
-
-static struct pci_driver i810_driver = {
-       .name           = "i810_smbus",
-       .id_table       = i810_ids,
-       .probe          = i810_probe,
-       .remove         = __devexit_p(i810_remove),
-};
-
-static int __init i2c_i810_init(void)
-{
-       return pci_register_driver(&i810_driver);
-}
-
-static void __exit i2c_i810_exit(void)
-{
-       pci_unregister_driver(&i810_driver);
-}
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
-               "Philip Edelbrock <phil@netroedge.com>, "
-               "Ralph Metzler <rjkm@thp.uni-koeln.de>, "
-               "and Mark D. Studebaker <mdsxyz123@yahoo.com>");
-MODULE_DESCRIPTION("I810/I815 I2C/DDC driver");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_i810_init);
-module_exit(i2c_i810_exit);
index 85dbf34..651f2f1 100644 (file)
 #include <asm/io.h>
 #include <linux/i2c.h>
 #include <linux/i2c-id.h>
-
-#ifdef CONFIG_IBM_OCP
-#include <asm/ocp.h>
-#include <asm/ibm4xx.h>
-#else
 #include <linux/of_platform.h>
-#endif
+#include <linux/of_i2c.h>
 
 #include "i2c-ibm_iic.h"
 
@@ -665,180 +660,6 @@ static inline u8 iic_clckdiv(unsigned int opb)
        return (u8)((opb + 9) / 10 - 1);
 }
 
-#ifdef CONFIG_IBM_OCP
-/*
- * Register single IIC interface
- */
-static int __devinit iic_probe(struct ocp_device *ocp){
-
-       struct ibm_iic_private* dev;
-       struct i2c_adapter* adap;
-       struct ocp_func_iic_data* iic_data = ocp->def->additions;
-       int ret;
-
-       if (!iic_data)
-               printk(KERN_WARNING"ibm-iic%d: missing additional data!\n",
-                       ocp->def->index);
-
-       if (!(dev = kzalloc(sizeof(*dev), GFP_KERNEL))) {
-               printk(KERN_ERR "ibm-iic%d: failed to allocate device data\n",
-                       ocp->def->index);
-               return -ENOMEM;
-       }
-
-       dev->idx = ocp->def->index;
-       ocp_set_drvdata(ocp, dev);
-
-       if (!request_mem_region(ocp->def->paddr, sizeof(struct iic_regs),
-                               "ibm_iic")) {
-               ret = -EBUSY;
-               goto fail1;
-       }
-
-       if (!(dev->vaddr = ioremap(ocp->def->paddr, sizeof(struct iic_regs)))){
-               printk(KERN_ERR "ibm-iic%d: failed to ioremap device registers\n",
-                       dev->idx);
-               ret = -ENXIO;
-               goto fail2;
-       }
-
-       init_waitqueue_head(&dev->wq);
-
-       dev->irq = iic_force_poll ? -1 : ocp->def->irq;
-       if (dev->irq >= 0){
-               /* Disable interrupts until we finish initialization,
-                  assumes level-sensitive IRQ setup...
-                */
-               iic_interrupt_mode(dev, 0);
-               if (request_irq(dev->irq, iic_handler, 0, "IBM IIC", dev)){
-                       printk(KERN_ERR "ibm-iic%d: request_irq %d failed\n",
-                               dev->idx, dev->irq);
-                       /* Fallback to the polling mode */
-                       dev->irq = -1;
-               }
-       }
-
-       if (dev->irq < 0)
-               printk(KERN_WARNING "ibm-iic%d: using polling mode\n",
-                       dev->idx);
-
-       /* Board specific settings */
-       dev->fast_mode = iic_force_fast ? 1 : (iic_data ? iic_data->fast_mode : 0);
-
-       /* clckdiv is the same for *all* IIC interfaces,
-        * but I'd rather make a copy than introduce another global. --ebs
-        */
-       dev->clckdiv = iic_clckdiv(ocp_sys_info.opb_bus_freq);
-       DBG("%d: clckdiv = %d\n", dev->idx, dev->clckdiv);
-
-       /* Initialize IIC interface */
-       iic_dev_init(dev);
-
-       /* Register it with i2c layer */
-       adap = &dev->adap;
-       adap->dev.parent = &ocp->dev;
-       strcpy(adap->name, "IBM IIC");
-       i2c_set_adapdata(adap, dev);
-       adap->id = I2C_HW_OCP;
-       adap->class = I2C_CLASS_HWMON;
-       adap->algo = &iic_algo;
-       adap->client_register = NULL;
-       adap->client_unregister = NULL;
-       adap->timeout = 1;
-
-       /*
-        * If "dev->idx" is negative we consider it as zero.
-        * The reason to do so is to avoid sysfs names that only make
-        * sense when there are multiple adapters.
-        */
-       adap->nr = dev->idx >= 0 ? dev->idx : 0;
-
-       if ((ret = i2c_add_numbered_adapter(adap)) < 0) {
-               printk(KERN_ERR "ibm-iic%d: failed to register i2c adapter\n",
-                       dev->idx);
-               goto fail;
-       }
-
-       printk(KERN_INFO "ibm-iic%d: using %s mode\n", dev->idx,
-               dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
-
-       return 0;
-
-fail:
-       if (dev->irq >= 0){
-               iic_interrupt_mode(dev, 0);
-               free_irq(dev->irq, dev);
-       }
-
-       iounmap(dev->vaddr);
-fail2:
-       release_mem_region(ocp->def->paddr, sizeof(struct iic_regs));
-fail1:
-       ocp_set_drvdata(ocp, NULL);
-       kfree(dev);
-       return ret;
-}
-
-/*
- * Cleanup initialized IIC interface
- */
-static void __devexit iic_remove(struct ocp_device *ocp)
-{
-       struct ibm_iic_private* dev = (struct ibm_iic_private*)ocp_get_drvdata(ocp);
-       BUG_ON(dev == NULL);
-       if (i2c_del_adapter(&dev->adap)){
-               printk(KERN_ERR "ibm-iic%d: failed to delete i2c adapter :(\n",
-                       dev->idx);
-               /* That's *very* bad, just shutdown IRQ ... */
-               if (dev->irq >= 0){
-                   iic_interrupt_mode(dev, 0);
-                   free_irq(dev->irq, dev);
-                   dev->irq = -1;
-               }
-       } else {
-               if (dev->irq >= 0){
-                   iic_interrupt_mode(dev, 0);
-                   free_irq(dev->irq, dev);
-               }
-               iounmap(dev->vaddr);
-               release_mem_region(ocp->def->paddr, sizeof(struct iic_regs));
-               kfree(dev);
-       }
-}
-
-static struct ocp_device_id ibm_iic_ids[] __devinitdata =
-{
-       { .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_IIC },
-       { .vendor = OCP_VENDOR_INVALID }
-};
-
-MODULE_DEVICE_TABLE(ocp, ibm_iic_ids);
-
-static struct ocp_driver ibm_iic_driver =
-{
-       .name           = "iic",
-       .id_table       = ibm_iic_ids,
-       .probe          = iic_probe,
-       .remove         = __devexit_p(iic_remove),
-#if defined(CONFIG_PM)
-       .suspend        = NULL,
-       .resume         = NULL,
-#endif
-};
-
-static int __init iic_init(void)
-{
-       printk(KERN_INFO "IBM IIC driver v" DRIVER_VERSION "\n");
-       return ocp_register_driver(&ibm_iic_driver);
-}
-
-static void __exit iic_exit(void)
-{
-       ocp_unregister_driver(&ibm_iic_driver);
-}
-
-#else  /* !CONFIG_IBM_OCP */
-
 static int __devinit iic_request_irq(struct of_device *ofdev,
                                     struct ibm_iic_private *dev)
 {
@@ -876,7 +697,7 @@ static int __devinit iic_probe(struct of_device *ofdev,
        struct device_node *np = ofdev->node;
        struct ibm_iic_private *dev;
        struct i2c_adapter *adap;
-       const u32 *indexp, *freq;
+       const u32 *freq;
        int ret;
 
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
@@ -887,14 +708,6 @@ static int __devinit iic_probe(struct of_device *ofdev,
 
        dev_set_drvdata(&ofdev->dev, dev);
 
-       indexp = of_get_property(np, "index", NULL);
-       if (!indexp) {
-               dev_err(&ofdev->dev, "no index specified\n");
-               ret = -EINVAL;
-               goto error_cleanup;
-       }
-       dev->idx = *indexp;
-
        dev->vaddr = of_iomap(np, 0);
        if (dev->vaddr == NULL) {
                dev_err(&ofdev->dev, "failed to iomap device\n");
@@ -934,17 +747,19 @@ static int __devinit iic_probe(struct of_device *ofdev,
        strlcpy(adap->name, "IBM IIC", sizeof(adap->name));
        i2c_set_adapdata(adap, dev);
        adap->id = I2C_HW_OCP;
-       adap->class = I2C_CLASS_HWMON;
+       adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
        adap->algo = &iic_algo;
        adap->timeout = 1;
-       adap->nr = dev->idx;
 
-       ret = i2c_add_numbered_adapter(adap);
+       ret = i2c_add_adapter(adap);
        if (ret  < 0) {
                dev_err(&ofdev->dev, "failed to register i2c adapter\n");
                goto error_cleanup;
        }
 
+       /* Now register all the child nodes */
+       of_register_i2c_devices(adap, np);
+
        dev_info(&ofdev->dev, "using %s mode\n",
                 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
 
@@ -987,11 +802,7 @@ static int __devexit iic_remove(struct of_device *ofdev)
 }
 
 static const struct of_device_id ibm_iic_match[] = {
-       { .compatible = "ibm,iic-405ex", },
-       { .compatible = "ibm,iic-405gp", },
-       { .compatible = "ibm,iic-440gp", },
-       { .compatible = "ibm,iic-440gpx", },
-       { .compatible = "ibm,iic-440grx", },
+       { .compatible = "ibm,iic", },
        {}
 };
 
@@ -1011,7 +822,6 @@ static void __exit iic_exit(void)
 {
        of_unregister_platform_driver(&ibm_iic_driver);
 }
-#endif /* CONFIG_IBM_OCP */
 
 module_init(iic_init);
 module_exit(iic_exit);
index 39884e7..fc2714a 100644 (file)
@@ -482,7 +482,7 @@ iop3xx_i2c_probe(struct platform_device *pdev)
        memcpy(new_adapter->name, pdev->name, strlen(pdev->name));
        new_adapter->id = I2C_HW_IOP3XX;
        new_adapter->owner = THIS_MODULE;
-       new_adapter->class = I2C_CLASS_HWMON;
+       new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
        new_adapter->dev.parent = &pdev->dev;
        new_adapter->nr = pdev->id;
 
diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c
new file mode 100644 (file)
index 0000000..b9c01aa
--- /dev/null
@@ -0,0 +1,339 @@
+/*
+    i2c-isch.c - Linux kernel driver for Intel SCH chipset SMBus
+    - Based on i2c-piix4.c
+    Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl> and
+    Philip Edelbrock <phil@netroedge.com>
+    - Intel SCH support
+    Copyright (c) 2007 - 2008 Jacob Jun Pan <jacob.jun.pan@intel.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License version 2 as
+    published by the Free Software Foundation.
+
+    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.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+   Supports:
+       Intel SCH chipsets (AF82US15W, AF82US15L, AF82UL11L)
+   Note: we assume there can only be one device, with one SMBus interface.
+*/
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/stddef.h>
+#include <linux/ioport.h>
+#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)
+#define SMBHSTSTS      (1 + sch_smba)
+#define SMBHSTADD      (4 + sch_smba) /* TSA */
+#define SMBHSTCMD      (5 + sch_smba)
+#define SMBHSTDAT0     (6 + sch_smba)
+#define SMBHSTDAT1     (7 + sch_smba)
+#define SMBBLKDAT      (0x20 + sch_smba)
+
+/* count for request_region */
+#define SMBIOSIZE      64
+
+/* PCI Address Constants */
+#define SMBBA_SCH      0x40
+
+/* Other settings */
+#define MAX_TIMEOUT    500
+
+/* I2C constants */
+#define SCH_QUICK              0x00
+#define SCH_BYTE               0x01
+#define SCH_BYTE_DATA          0x02
+#define SCH_WORD_DATA          0x03
+#define SCH_BLOCK_DATA         0x05
+
+static unsigned short sch_smba;
+static struct pci_driver sch_driver;
+static struct i2c_adapter sch_adapter;
+
+/*
+ * Start the i2c transaction -- the i2c_access will prepare the transaction
+ * and this function will execute it.
+ * return 0 for success and others for failure.
+ */
+static int sch_transaction(void)
+{
+       int temp;
+       int result = 0;
+       int timeout = 0;
+
+       dev_dbg(&sch_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, "
+               "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb(SMBHSTCNT),
+               inb(SMBHSTCMD), inb(SMBHSTADD), inb(SMBHSTDAT0),
+               inb(SMBHSTDAT1));
+
+       /* Make sure the SMBus host is ready to start transmitting */
+       temp = inb(SMBHSTSTS) & 0x0f;
+       if (temp) {
+               /* Can not be busy since we checked it in sch_access */
+               if (temp & 0x01) {
+                       dev_dbg(&sch_adapter.dev, "Completion (%02x). "
+                               "Clear...\n", temp);
+               }
+               if (temp & 0x06) {
+                       dev_dbg(&sch_adapter.dev, "SMBus error (%02x). "
+                               "Resetting...\n", temp);
+               }
+               outb(temp, SMBHSTSTS);
+               temp = inb(SMBHSTSTS) & 0x0f;
+               if (temp) {
+                       dev_err(&sch_adapter.dev,
+                               "SMBus is not ready: (%02x)\n", temp);
+                       return -EAGAIN;
+               }
+       }
+
+       /* start the transaction by setting bit 4 */
+       outb(inb(SMBHSTCNT) | 0x10, SMBHSTCNT);
+
+       do {
+               msleep(1);
+               temp = inb(SMBHSTSTS) & 0x0f;
+       } while ((temp & 0x08) && (timeout++ < MAX_TIMEOUT));
+
+       /* If the SMBus is still busy, we give up */
+       if (timeout >= MAX_TIMEOUT) {
+               dev_err(&sch_adapter.dev, "SMBus Timeout!\n");
+               result = -ETIMEDOUT;
+       }
+       if (temp & 0x04) {
+               result = -EIO;
+               dev_dbg(&sch_adapter.dev, "Bus collision! SMBus may be "
+                       "locked until next hard reset. (sorry!)\n");
+               /* Clock stops and slave is stuck in mid-transmission */
+       } else if (temp & 0x02) {
+               result = -EIO;
+               dev_err(&sch_adapter.dev, "Error: no response!\n");
+       } else if (temp & 0x01) {
+               dev_dbg(&sch_adapter.dev, "Post complete!\n");
+               outb(temp, SMBHSTSTS);
+               temp = inb(SMBHSTSTS) & 0x07;
+               if (temp & 0x06) {
+                       /* Completion clear failed */
+                       dev_dbg(&sch_adapter.dev, "Failed reset at end of "
+                               "transaction (%02x), Bus error!\n", temp);
+               }
+       } else {
+               result = -ENXIO;
+               dev_dbg(&sch_adapter.dev, "No such address.\n");
+       }
+       dev_dbg(&sch_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, "
+               "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb(SMBHSTCNT),
+               inb(SMBHSTCMD), inb(SMBHSTADD), inb(SMBHSTDAT0),
+               inb(SMBHSTDAT1));
+       return result;
+}
+
+/*
+ * This is the main access entry for i2c-sch access
+ * adap is i2c_adapter pointer, addr is the i2c device bus address, read_write
+ * (0 for read and 1 for write), size is i2c transaction type and data is the
+ * union of transaction for data to be transfered or data read from bus.
+ * return 0 for success and others for failure.
+ */
+static s32 sch_access(struct i2c_adapter *adap, u16 addr,
+                unsigned short flags, char read_write,
+                u8 command, int size, union i2c_smbus_data *data)
+{
+       int i, len, temp, rc;
+
+       /* Make sure the SMBus host is not busy */
+       temp = inb(SMBHSTSTS) & 0x0f;
+       if (temp & 0x08) {
+               dev_dbg(&sch_adapter.dev, "SMBus busy (%02x)\n", temp);
+               return -EAGAIN;
+       }
+       dev_dbg(&sch_adapter.dev, "access size: %d %s\n", size,
+               (read_write)?"READ":"WRITE");
+       switch (size) {
+       case I2C_SMBUS_QUICK:
+               outb((addr << 1) | read_write, SMBHSTADD);
+               size = SCH_QUICK;
+               break;
+       case I2C_SMBUS_BYTE:
+               outb((addr << 1) | read_write, SMBHSTADD);
+               if (read_write == I2C_SMBUS_WRITE)
+                       outb(command, SMBHSTCMD);
+               size = SCH_BYTE;
+               break;
+       case I2C_SMBUS_BYTE_DATA:
+               outb((addr << 1) | read_write, SMBHSTADD);
+               outb(command, SMBHSTCMD);
+               if (read_write == I2C_SMBUS_WRITE)
+                       outb(data->byte, SMBHSTDAT0);
+               size = SCH_BYTE_DATA;
+               break;
+       case I2C_SMBUS_WORD_DATA:
+               outb((addr << 1) | read_write, SMBHSTADD);
+               outb(command, SMBHSTCMD);
+               if (read_write == I2C_SMBUS_WRITE) {
+                       outb(data->word & 0xff, SMBHSTDAT0);
+                       outb((data->word & 0xff00) >> 8, SMBHSTDAT1);
+               }
+               size = SCH_WORD_DATA;
+               break;
+       case I2C_SMBUS_BLOCK_DATA:
+               outb((addr << 1) | read_write, SMBHSTADD);
+               outb(command, SMBHSTCMD);
+               if (read_write == I2C_SMBUS_WRITE) {
+                       len = data->block[0];
+                       if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
+                               return -EINVAL;
+                       outb(len, SMBHSTDAT0);
+                       for (i = 1; i <= len; i++)
+                               outb(data->block[i], SMBBLKDAT+i-1);
+               }
+               size = SCH_BLOCK_DATA;
+               break;
+       default:
+               dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
+               return -EOPNOTSUPP;
+       }
+       dev_dbg(&sch_adapter.dev, "write size %d to 0x%04x\n", size, SMBHSTCNT);
+       outb((inb(SMBHSTCNT) & 0xb0) | (size & 0x7), SMBHSTCNT);
+
+       rc = sch_transaction();
+       if (rc) /* Error in transaction */
+               return rc;
+
+       if ((read_write == I2C_SMBUS_WRITE) || (size == SCH_QUICK))
+               return 0;
+
+       switch (size) {
+       case SCH_BYTE:
+       case SCH_BYTE_DATA:
+               data->byte = inb(SMBHSTDAT0);
+               break;
+       case SCH_WORD_DATA:
+               data->word = inb(SMBHSTDAT0) + (inb(SMBHSTDAT1) << 8);
+               break;
+       case SCH_BLOCK_DATA:
+               data->block[0] = inb(SMBHSTDAT0);
+               if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
+                       return -EPROTO;
+               for (i = 1; i <= data->block[0]; i++)
+                       data->block[i] = inb(SMBBLKDAT+i-1);
+               break;
+       }
+       return 0;
+}
+
+static u32 sch_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+           I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+           I2C_FUNC_SMBUS_BLOCK_DATA;
+}
+
+static const struct i2c_algorithm smbus_algorithm = {
+       .smbus_xfer     = sch_access,
+       .functionality  = sch_func,
+};
+
+static struct i2c_adapter sch_adapter = {
+       .owner          = THIS_MODULE,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
+       .algo           = &smbus_algorithm,
+};
+
+static struct pci_device_id sch_ids[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) },
+       { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, sch_ids);
+
+static int __devinit sch_probe(struct pci_dev *dev,
+                               const struct pci_device_id *id)
+{
+       int retval;
+       unsigned int smba;
+
+       pci_read_config_dword(dev, SMBBA_SCH, &smba);
+       if (!(smba & (1 << 31))) {
+               dev_err(&dev->dev, "SMBus I/O space disabled!\n");
+               return -ENODEV;
+       }
+
+       sch_smba = (unsigned short)smba;
+       if (sch_smba == 0) {
+               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);
+               return -EBUSY;
+       }
+       dev_dbg(&dev->dev, "SMBA = 0x%X\n", sch_smba);
+
+       /* set up the sysfs linkage to our parent device */
+       sch_adapter.dev.parent = &dev->dev;
+
+       snprintf(sch_adapter.name, sizeof(sch_adapter.name),
+               "SMBus SCH adapter at %04x", sch_smba);
+
+       retval = i2c_add_adapter(&sch_adapter);
+       if (retval) {
+               dev_err(&dev->dev, "Couldn't register adapter!\n");
+               release_region(sch_smba, SMBIOSIZE);
+               sch_smba = 0;
+       }
+
+       return retval;
+}
+
+static void __devexit sch_remove(struct pci_dev *dev)
+{
+       if (sch_smba) {
+               i2c_del_adapter(&sch_adapter);
+               release_region(sch_smba, SMBIOSIZE);
+               sch_smba = 0;
+       }
+}
+
+static struct pci_driver sch_driver = {
+       .name           = "isch_smbus",
+       .id_table       = sch_ids,
+       .probe          = sch_probe,
+       .remove         = __devexit_p(sch_remove),
+};
+
+static int __init i2c_sch_init(void)
+{
+       return pci_register_driver(&sch_driver);
+}
+
+static void __exit i2c_sch_exit(void)
+{
+       pci_unregister_driver(&sch_driver);
+}
+
+MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>");
+MODULE_DESCRIPTION("Intel SCH SMBus driver");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_sch_init);
+module_exit(i2c_sch_exit);
index a076129..10b9342 100644 (file)
@@ -311,7 +311,7 @@ static struct i2c_adapter mpc_ops = {
        .name = "MPC adapter",
        .id = I2C_HW_MPC107,
        .algo = &mpc_algo,
-       .class = I2C_CLASS_HWMON,
+       .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .timeout = 1,
 };
 
index 036e6a8..9e8118d 100644 (file)
@@ -530,7 +530,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
        drv_data->adapter.id = I2C_HW_MV64XXX;
        drv_data->adapter.algo = &mv64xxx_i2c_algo;
        drv_data->adapter.owner = THIS_MODULE;
-       drv_data->adapter.class = I2C_CLASS_HWMON;
+       drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
        drv_data->adapter.timeout = pdata->timeout;
        drv_data->adapter.nr = pd->id;
        platform_set_drvdata(pd, drv_data);
diff --git a/drivers/i2c/busses/i2c-nforce2-s4985.c b/drivers/i2c/busses/i2c-nforce2-s4985.c
new file mode 100644 (file)
index 0000000..6a8995d
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * i2c-nforce2-s4985.c - i2c-nforce2 extras for the Tyan S4985 motherboard
+ *
+ * Copyright (C) 2008 Jean Delvare <khali@linux-fr.org>
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * We select the channels by sending commands to the Philips
+ * PCA9556 chip at I2C address 0x18. The main adapter is used for
+ * the non-multiplexed part of the bus, and 4 virtual adapters
+ * are defined for the multiplexed addresses: 0x50-0x53 (memory
+ * module EEPROM) located on channels 1-4. We define one virtual
+ * adapter per CPU, which corresponds to one multiplexed channel:
+ *   CPU0: virtual adapter 1, channel 1
+ *   CPU1: virtual adapter 2, channel 2
+ *   CPU2: virtual adapter 3, channel 3
+ *   CPU3: virtual adapter 4, channel 4
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+
+extern struct i2c_adapter *nforce2_smbus;
+
+static struct i2c_adapter *s4985_adapter;
+static struct i2c_algorithm *s4985_algo;
+
+/* Wrapper access functions for multiplexed SMBus */
+static DEFINE_MUTEX(nforce2_lock);
+
+static s32 nforce2_access_virt0(struct i2c_adapter *adap, u16 addr,
+                               unsigned short flags, char read_write,
+                               u8 command, int size,
+                               union i2c_smbus_data *data)
+{
+       int error;
+
+       /* We exclude the multiplexed addresses */
+       if ((addr & 0xfc) == 0x50 || (addr & 0xfc) == 0x30
+        || addr == 0x18)
+               return -ENXIO;
+
+       mutex_lock(&nforce2_lock);
+       error = nforce2_smbus->algo->smbus_xfer(adap, addr, flags, read_write,
+                                               command, size, data);
+       mutex_unlock(&nforce2_lock);
+
+       return error;
+}
+
+/* We remember the last used channels combination so as to only switch
+   channels when it is really needed. This greatly reduces the SMBus
+   overhead, but also assumes that nobody will be writing to the PCA9556
+   in our back. */
+static u8 last_channels;
+
+static inline s32 nforce2_access_channel(struct i2c_adapter *adap, u16 addr,
+                                        unsigned short flags, char read_write,
+                                        u8 command, int size,
+                                        union i2c_smbus_data *data,
+                                        u8 channels)
+{
+       int error;
+
+       /* We exclude the non-multiplexed addresses */
+       if ((addr & 0xfc) != 0x50 && (addr & 0xfc) != 0x30)
+               return -ENXIO;
+
+       mutex_lock(&nforce2_lock);
+       if (last_channels != channels) {
+               union i2c_smbus_data mplxdata;
+               mplxdata.byte = channels;
+
+               error = nforce2_smbus->algo->smbus_xfer(adap, 0x18, 0,
+                                                       I2C_SMBUS_WRITE, 0x01,
+                                                       I2C_SMBUS_BYTE_DATA,
+                                                       &mplxdata);
+               if (error)
+                       goto UNLOCK;
+               last_channels = channels;
+       }
+       error = nforce2_smbus->algo->smbus_xfer(adap, addr, flags, read_write,
+                                               command, size, data);
+
+UNLOCK:
+       mutex_unlock(&nforce2_lock);
+       return error;
+}
+
+static s32 nforce2_access_virt1(struct i2c_adapter *adap, u16 addr,
+                               unsigned short flags, char read_write,
+                               u8 command, int size,
+                               union i2c_smbus_data *data)
+{
+       /* CPU0: channel 1 enabled */
+       return nforce2_access_channel(adap, addr, flags, read_write, command,
+                                     size, data, 0x02);
+}
+
+static s32 nforce2_access_virt2(struct i2c_adapter *adap, u16 addr,
+                               unsigned short flags, char read_write,
+                               u8 command, int size,
+                               union i2c_smbus_data *data)
+{
+       /* CPU1: channel 2 enabled */
+       return nforce2_access_channel(adap, addr, flags, read_write, command,
+                                     size, data, 0x04);
+}
+
+static s32 nforce2_access_virt3(struct i2c_adapter *adap, u16 addr,
+                               unsigned short flags, char read_write,
+                               u8 command, int size,
+                               union i2c_smbus_data *data)
+{
+       /* CPU2: channel 3 enabled */
+       return nforce2_access_channel(adap, addr, flags, read_write, command,
+                                     size, data, 0x08);
+}
+
+static s32 nforce2_access_virt4(struct i2c_adapter *adap, u16 addr,
+                               unsigned short flags, char read_write,
+                               u8 command, int size,
+                               union i2c_smbus_data *data)
+{
+       /* CPU3: channel 4 enabled */
+       return nforce2_access_channel(adap, addr, flags, read_write, command,
+                                     size, data, 0x10);
+}
+
+static int __init nforce2_s4985_init(void)
+{
+       int i, error;
+       union i2c_smbus_data ioconfig;
+
+       /* Unregister physical bus */
+       if (!nforce2_smbus)
+               return -ENODEV;
+       error = i2c_del_adapter(nforce2_smbus);
+       if (error) {
+               dev_err(&nforce2_smbus->dev, "Physical bus removal failed\n");
+               goto ERROR0;
+       }
+
+       printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4985\n");
+       /* Define the 5 virtual adapters and algorithms structures */
+       s4985_adapter = kzalloc(5 * sizeof(struct i2c_adapter), GFP_KERNEL);
+       if (!s4985_adapter) {
+               error = -ENOMEM;
+               goto ERROR1;
+       }
+       s4985_algo = kzalloc(5 * sizeof(struct i2c_algorithm), GFP_KERNEL);
+       if (!s4985_algo) {
+               error = -ENOMEM;
+               goto ERROR2;
+       }
+
+       /* Fill in the new structures */
+       s4985_algo[0] = *(nforce2_smbus->algo);
+       s4985_algo[0].smbus_xfer = nforce2_access_virt0;
+       s4985_adapter[0] = *nforce2_smbus;
+       s4985_adapter[0].algo = s4985_algo;
+       s4985_adapter[0].dev.parent = nforce2_smbus->dev.parent;
+       for (i = 1; i < 5; i++) {
+               s4985_algo[i] = *(nforce2_smbus->algo);
+               s4985_adapter[i] = *nforce2_smbus;
+               snprintf(s4985_adapter[i].name, sizeof(s4985_adapter[i].name),
+                        "SMBus nForce2 adapter (CPU%d)", i - 1);
+               s4985_adapter[i].algo = s4985_algo + i;
+               s4985_adapter[i].dev.parent = nforce2_smbus->dev.parent;
+       }
+       s4985_algo[1].smbus_xfer = nforce2_access_virt1;
+       s4985_algo[2].smbus_xfer = nforce2_access_virt2;
+       s4985_algo[3].smbus_xfer = nforce2_access_virt3;
+       s4985_algo[4].smbus_xfer = nforce2_access_virt4;
+
+       /* Configure the PCA9556 multiplexer */
+       ioconfig.byte = 0x00; /* All I/O to output mode */
+       error = nforce2_smbus->algo->smbus_xfer(nforce2_smbus, 0x18, 0,
+                                               I2C_SMBUS_WRITE, 0x03,
+                                               I2C_SMBUS_BYTE_DATA, &ioconfig);
+       if (error) {
+               dev_err(&nforce2_smbus->dev, "PCA9556 configuration failed\n");
+               error = -EIO;
+               goto ERROR3;
+       }
+
+       /* Register virtual adapters */
+       for (i = 0; i < 5; i++) {
+               error = i2c_add_adapter(s4985_adapter + i);
+               if (error) {
+                       dev_err(&nforce2_smbus->dev,
+                               "Virtual adapter %d registration "
+                               "failed, module not inserted\n", i);
+                       for (i--; i >= 0; i--)
+                               i2c_del_adapter(s4985_adapter + i);
+                       goto ERROR3;
+               }
+       }
+
+       return 0;
+
+ERROR3:
+       kfree(s4985_algo);
+       s4985_algo = NULL;
+ERROR2:
+       kfree(s4985_adapter);
+       s4985_adapter = NULL;
+ERROR1:
+       /* Restore physical bus */
+       i2c_add_adapter(nforce2_smbus);
+ERROR0:
+       return error;
+}
+
+static void __exit nforce2_s4985_exit(void)
+{
+       if (s4985_adapter) {
+               int i;
+
+               for (i = 0; i < 5; i++)
+                       i2c_del_adapter(s4985_adapter+i);
+               kfree(s4985_adapter);
+               s4985_adapter = NULL;
+       }
+       kfree(s4985_algo);
+       s4985_algo = NULL;
+
+       /* Restore physical bus */
+       if (i2c_add_adapter(nforce2_smbus))
+               dev_err(&nforce2_smbus->dev, "Physical bus restoration "
+                       "failed\n");
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("S4985 SMBus multiplexing");
+MODULE_LICENSE("GPL");
+
+module_init(nforce2_s4985_init);
+module_exit(nforce2_s4985_exit);
index 43c9f8d..3b19bc4 100644 (file)
@@ -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");
@@ -124,6 +125,20 @@ static struct dmi_system_id __devinitdata nforce2_dmi_blacklist2[] = {
 
 static struct pci_driver nforce2_driver;
 
+/* For multiplexing support, we need a global reference to the 1st
+   SMBus channel */
+#if defined CONFIG_I2C_NFORCE2_S4985 || defined CONFIG_I2C_NFORCE2_S4985_MODULE
+struct i2c_adapter *nforce2_smbus;
+EXPORT_SYMBOL_GPL(nforce2_smbus);
+
+static void nforce2_set_reference(struct i2c_adapter *adap)
+{
+       nforce2_smbus = adap;
+}
+#else
+static inline void nforce2_set_reference(struct i2c_adapter *adap) { }
+#endif
+
 static void nforce2_abort(struct i2c_adapter *adap)
 {
        struct nforce2_smbus *smbus = adap->algo_data;
@@ -158,16 +173,16 @@ static int nforce2_check_status(struct i2c_adapter *adap)
                dev_dbg(&adap->dev, "SMBus Timeout!\n");
                if (smbus->can_abort)
                        nforce2_abort(adap);
-               return -1;
+               return -ETIMEDOUT;
        }
        if (!(temp & NVIDIA_SMB_STS_DONE) || (temp & NVIDIA_SMB_STS_STATUS)) {
                dev_dbg(&adap->dev, "Transaction failed (0x%02x)!\n", temp);
-               return -1;
+               return -EIO;
        }
        return 0;
 }
 
-/* Return -1 on error */
+/* Return negative errno on error */
 static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
                unsigned short flags, char read_write,
                u8 command, int size, union i2c_smbus_data * data)
@@ -175,7 +190,7 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
        struct nforce2_smbus *smbus = adap->algo_data;
        unsigned char protocol, pec;
        u8 len;
-       int i;
+       int i, status;
 
        protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ :
                NVIDIA_SMB_PRTCL_WRITE;
@@ -219,7 +234,7 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
                                                "Transaction failed "
                                                "(requested block size: %d)\n",
                                                len);
-                                       return -1;
+                                       return -EINVAL;
                                }
                                outb_p(len, NVIDIA_SMB_BCNT);
                                for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++)
@@ -231,14 +246,15 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
 
                default:
                        dev_err(&adap->dev, "Unsupported transaction %d\n", size);
-                       return -1;
+                       return -EOPNOTSUPP;
        }
 
        outb_p((addr & 0x7f) << 1, NVIDIA_SMB_ADDR);
        outb_p(protocol, NVIDIA_SMB_PRTCL);
 
-       if (nforce2_check_status(adap))
-               return -1;
+       status = nforce2_check_status(adap);
+       if (status)
+               return status;
 
        if (read_write == I2C_SMBUS_WRITE)
                return 0;
@@ -260,7 +276,7 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
                                dev_err(&adap->dev, "Transaction failed "
                                        "(received block size: 0x%02x)\n",
                                        len);
-                               return -1;
+                               return -EPROTO;
                        }
                        for (i = 0; i < len; i++)
                                data->block[i+1] = inb_p(NVIDIA_SMB_DATA + i);
@@ -321,21 +337,26 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
                    != PCIBIOS_SUCCESSFUL) {
                        dev_err(&dev->dev, "Error reading PCI config for %s\n",
                                name);
-                       return -1;
+                       return -EIO;
                }
 
                smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK;
                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);
-               return -1;
+               return -EBUSY;
        }
        smbus->adapter.owner = THIS_MODULE;
        smbus->adapter.id = I2C_HW_SMBUS_NFORCE2;
-       smbus->adapter.class = I2C_CLASS_HWMON;
+       smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
        smbus->adapter.algo = &smbus_algorithm;
        smbus->adapter.algo_data = smbus;
        smbus->adapter.dev.parent = &dev->dev;
@@ -346,7 +367,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
        if (error) {
                dev_err(&smbus->adapter.dev, "Failed to register adapter.\n");
                release_region(smbus->base, smbus->size);
-               return -1;
+               return error;
        }
        dev_info(&smbus->adapter.dev, "nForce2 SMBus adapter at %#x\n", smbus->base);
        return 0;
@@ -398,6 +419,7 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_
                return -ENODEV;
        }
 
+       nforce2_set_reference(&smbuses[0].adapter);
        return 0;
 }
 
@@ -406,6 +428,7 @@ static void __devexit nforce2_remove(struct pci_dev *dev)
 {
        struct nforce2_smbus *smbuses = (void*) pci_get_drvdata(dev);
 
+       nforce2_set_reference(NULL);
        if (smbuses[0].base) {
                i2c_del_adapter(&smbuses[0].adapter);
                release_region(smbuses[0].base, smbuses[0].size);
index f145692..e5193bf 100644 (file)
@@ -29,6 +29,7 @@ struct ocores_i2c {
        int pos;
        int nmsgs;
        int state; /* see STATE_ */
+       int clock_khz;
 };
 
 /* registers */
@@ -173,8 +174,7 @@ static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
                return -ETIMEDOUT;
 }
 
-static void ocores_init(struct ocores_i2c *i2c,
-                       struct ocores_i2c_platform_data *pdata)
+static void ocores_init(struct ocores_i2c *i2c)
 {
        int prescale;
        u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL);
@@ -182,7 +182,7 @@ static void ocores_init(struct ocores_i2c *i2c,
        /* make sure the device is disabled */
        oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN));
 
-       prescale = (pdata->clock_khz / (5*100)) - 1;
+       prescale = (i2c->clock_khz / (5*100)) - 1;
        oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff);
        oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8);
 
@@ -205,7 +205,7 @@ static const struct i2c_algorithm ocores_algorithm = {
 static struct i2c_adapter ocores_adapter = {
        .owner          = THIS_MODULE,
        .name           = "i2c-ocores",
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .algo           = &ocores_algorithm,
 };
 
@@ -248,7 +248,8 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev)
        }
 
        i2c->regstep = pdata->regstep;
-       ocores_init(i2c, pdata);
+       i2c->clock_khz = pdata->clock_khz;
+       ocores_init(i2c);
 
        init_waitqueue_head(&i2c->wait);
        ret = request_irq(res2->start, ocores_isr, 0, pdev->name, i2c);
@@ -312,13 +313,40 @@ static int __devexit ocores_i2c_remove(struct platform_device* pdev)
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int ocores_i2c_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct ocores_i2c *i2c = platform_get_drvdata(pdev);
+       u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL);
+
+       /* make sure the device is disabled */
+       oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN));
+
+       return 0;
+}
+
+static int ocores_i2c_resume(struct platform_device *pdev)
+{
+       struct ocores_i2c *i2c = platform_get_drvdata(pdev);
+
+       ocores_init(i2c);
+
+       return 0;
+}
+#else
+#define ocores_i2c_suspend     NULL
+#define ocores_i2c_resume      NULL
+#endif
+
 /* work with hotplug and coldplug */
 MODULE_ALIAS("platform:ocores-i2c");
 
 static struct platform_driver ocores_i2c_driver = {
-       .probe  = ocores_i2c_probe,
-       .remove = __devexit_p(ocores_i2c_remove),
-       .driver = {
+       .probe   = ocores_i2c_probe,
+       .remove  = __devexit_p(ocores_i2c_remove),
+       .suspend = ocores_i2c_suspend,
+       .resume  = ocores_i2c_resume,
+       .driver  = {
                .owner = THIS_MODULE,
                .name = "ocores-i2c",
        },
index 1603c81..adf0fbb 100644 (file)
@@ -365,7 +365,7 @@ static int __devinit pasemi_smb_probe(struct pci_dev *dev,
        smbus->adapter.owner = THIS_MODULE;
        snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
                 "PA Semi SMBus adapter at 0x%lx", smbus->base);
-       smbus->adapter.class = I2C_CLASS_HWMON;
+       smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
        smbus->adapter.algo = &smbus_algorithm;
        smbus->adapter.algo_data = smbus;
        smbus->adapter.nr = PCI_FUNC(dev->devfn);
index 9d75f51..6bb15ad 100644 (file)
@@ -163,7 +163,7 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev)
 
        i2c->reg_base = ioremap(res->start, res_len(res));
        if (!i2c->reg_base) {
-               ret = -EIO;
+               ret = -ENOMEM;
                goto e_remap;
        }
        i2c->io_base = res->start;
index ac91659..eaa9b38 100644 (file)
@@ -1,6 +1,4 @@
 /*
-    piix4.c - Part of lm_sensors, Linux kernel modules for hardware
-              monitoring
     Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl> and
     Philip Edelbrock <phil@netroedge.com>
 
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/dmi.h>
+#include <linux/acpi.h>
 #include <asm/io.h>
 
 
-struct sd {
-       const unsigned short mfr;
-       const unsigned short dev;
-       const unsigned char fn;
-       const char *name;
-};
-
 /* PIIX4 SMBus address offsets */
 #define SMBHSTSTS      (0 + piix4_smba)
 #define SMBHSLVSTS     (1 + piix4_smba)
@@ -101,8 +93,6 @@ MODULE_PARM_DESC(force_addr,
                 "Forcibly enable the PIIX4 at the given address. "
                 "EXTREMELY DANGEROUS!");
 
-static int piix4_transaction(void);
-
 static unsigned short piix4_smba;
 static int srvrworks_csb5_delay;
 static struct pci_driver piix4_driver;
@@ -141,8 +131,6 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
 {
        unsigned char temp;
 
-       dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev));
-
        if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
            (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5))
                srvrworks_csb5_delay = 1;
@@ -172,17 +160,20 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
                pci_read_config_word(PIIX4_dev, SMBBA, &piix4_smba);
                piix4_smba &= 0xfff0;
                if(piix4_smba == 0) {
-                       dev_err(&PIIX4_dev->dev, "SMB base address "
+                       dev_err(&PIIX4_dev->dev, "SMBus base address "
                                "uninitialized - upgrade BIOS or use "
                                "force_addr=0xaddr\n");
                        return -ENODEV;
                }
        }
 
+       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, "SMB region 0x%x already in use!\n",
+               dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
                        piix4_smba);
-               return -ENODEV;
+               return -EBUSY;
        }
 
        pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp);
@@ -228,13 +219,13 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
                        "(or code out of date)!\n");
 
        pci_read_config_byte(PIIX4_dev, SMBREV, &temp);
-       dev_dbg(&PIIX4_dev->dev, "SMBREV = 0x%X\n", temp);
-       dev_dbg(&PIIX4_dev->dev, "SMBA = 0x%X\n", piix4_smba);
+       dev_info(&PIIX4_dev->dev,
+                "SMBus Host Controller at 0x%x, revision %d\n",
+                piix4_smba, temp);
 
        return 0;
 }
 
-/* Another internally used function */
 static int piix4_transaction(void)
 {
        int temp;
@@ -253,7 +244,7 @@ static int piix4_transaction(void)
                outb_p(temp, SMBHSTSTS);
                if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
                        dev_err(&piix4_adapter.dev, "Failed! (%02x)\n", temp);
-                       return -1;
+                       return -EBUSY;
                } else {
                        dev_dbg(&piix4_adapter.dev, "Successful!\n");
                }
@@ -275,23 +266,23 @@ static int piix4_transaction(void)
        /* If the SMBus is still busy, we give up */
        if (timeout >= MAX_TIMEOUT) {
                dev_err(&piix4_adapter.dev, "SMBus Timeout!\n");
-               result = -1;
+               result = -ETIMEDOUT;
        }
 
        if (temp & 0x10) {
-               result = -1;
+               result = -EIO;
                dev_err(&piix4_adapter.dev, "Error: Failed bus transaction\n");
        }
 
        if (temp & 0x08) {
-               result = -1;
+               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 */
        }
 
        if (temp & 0x04) {
-               result = -1;
+               result = -ENXIO;
                dev_dbg(&piix4_adapter.dev, "Error: no response!\n");
        }
 
@@ -309,31 +300,29 @@ static int piix4_transaction(void)
        return result;
 }
 
-/* Return -1 on error. */
+/* Return negative errno on error. */
 static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
                 unsigned short flags, char read_write,
                 u8 command, int size, union i2c_smbus_data * data)
 {
        int i, len;
+       int status;
 
        switch (size) {
-       case I2C_SMBUS_PROC_CALL:
-               dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
-               return -1;
        case I2C_SMBUS_QUICK:
-               outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
+               outb_p((addr << 1) | read_write,
                       SMBHSTADD);
                size = PIIX4_QUICK;
                break;
        case I2C_SMBUS_BYTE:
-               outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
+               outb_p((addr << 1) | read_write,
                       SMBHSTADD);
                if (read_write == I2C_SMBUS_WRITE)
                        outb_p(command, SMBHSTCMD);
                size = PIIX4_BYTE;
                break;
        case I2C_SMBUS_BYTE_DATA:
-               outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
+               outb_p((addr << 1) | read_write,
                       SMBHSTADD);
                outb_p(command, SMBHSTCMD);
                if (read_write == I2C_SMBUS_WRITE)
@@ -341,7 +330,7 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
                size = PIIX4_BYTE_DATA;
                break;
        case I2C_SMBUS_WORD_DATA:
-               outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
+               outb_p((addr << 1) | read_write,
                       SMBHSTADD);
                outb_p(command, SMBHSTCMD);
                if (read_write == I2C_SMBUS_WRITE) {
@@ -351,15 +340,13 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
                size = PIIX4_WORD_DATA;
                break;
        case I2C_SMBUS_BLOCK_DATA:
-               outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
+               outb_p((addr << 1) | read_write,
                       SMBHSTADD);
                outb_p(command, SMBHSTCMD);
                if (read_write == I2C_SMBUS_WRITE) {
                        len = data->block[0];
-                       if (len < 0)
-                               len = 0;
-                       if (len > 32)
-                               len = 32;
+                       if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
+                               return -EINVAL;
                        outb_p(len, SMBHSTDAT0);
                        i = inb_p(SMBHSTCNT);   /* Reset SMBBLKDAT */
                        for (i = 1; i <= len; i++)
@@ -367,12 +354,16 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
                }
                size = PIIX4_BLOCK_DATA;
                break;
+       default:
+               dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
+               return -EOPNOTSUPP;
        }
 
        outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT);
 
-       if (piix4_transaction())        /* Error in transaction */
-               return -1;
+       status = piix4_transaction();
+       if (status)
+               return status;
 
        if ((read_write == I2C_SMBUS_WRITE) || (size == PIIX4_QUICK))
                return 0;
@@ -388,6 +379,8 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
                break;
        case PIIX4_BLOCK_DATA:
                data->block[0] = inb_p(SMBHSTDAT0);
+               if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
+                       return -EPROTO;
                i = inb_p(SMBHSTCNT);   /* Reset SMBBLKDAT */
                for (i = 1; i <= data->block[0]; i++)
                        data->block[i] = inb_p(SMBBLKDAT);
@@ -411,7 +404,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 static struct i2c_adapter piix4_adapter = {
        .owner          = THIS_MODULE,
        .id             = I2C_HW_SMBUS_PIIX4,
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .algo           = &smbus_algorithm,
 };
 
index 63b3e2c..dcf2045 100644 (file)
@@ -622,7 +622,7 @@ static struct i2c_algorithm pmcmsptwi_algo = {
 
 static struct i2c_adapter pmcmsptwi_adapter = {
        .owner          = THIS_MODULE,
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .algo           = &pmcmsptwi_algo,
        .name           = DRV_NAME,
 };
diff --git a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
deleted file mode 100644 (file)
index 07c1f1e..0000000
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- *    kernel/busses/i2c-prosavage.c
- *
- *    i2c bus driver for S3/VIA 8365/8375 graphics processor.
- *    Copyright (c) 2003 Henk Vergonet <henk@god.dyndns.org>
- *    Based on code written by:
- *     Frodo Looijaard <frodol@dds.nl>,
- *     Philip Edelbrock <phil@netroedge.com>,
- *     Ralph Metzler <rjkm@thp.uni-koeln.de>, and
- *     Mark D. Studebaker <mdsxyz123@yahoo.com>
- *     Simon Vogl
- *     and others
- *
- *    Please read the lm_sensors documentation for details on use.
- *
- *    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.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-/*  18-05-2003 HVE - created
- *  14-06-2003 HVE - adapted for lm_sensors2
- *  17-06-2003 HVE - linux 2.5.xx compatible
- *  18-06-2003 HVE - codingstyle
- *  21-06-2003 HVE - compatibility lm_sensors2 and linux 2.5.xx
- *                  codingstyle, mmio enabled
- *
- *  This driver interfaces to the I2C bus of the VIA north bridge embedded
- *  ProSavage4/8 devices. Usefull for gaining access to the TV Encoder chips.
- *
- *  Graphics cores:
- *   S3/VIA KM266/VT8375 aka ProSavage8
- *   S3/VIA KM133/VT8365 aka Savage4
- *
- *  Two serial busses are implemented:
- *   SERIAL1 - I2C serial communications interface
- *   SERIAL2 - DDC2 monitor communications interface
- *
- *  Tested on a FX41 mainboard, see http://www.shuttle.com
- * 
- *
- *  TODO:
- *  - integration with prosavage framebuffer device
- *    (Additional documentation needed :(
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <asm/io.h>
-
-/*
- * driver configuration
- */
-#define MAX_BUSSES     2
-
-struct s_i2c_bus {
-       void __iomem *mmvga;
-       int     i2c_reg;
-       int     adap_ok;
-       struct i2c_adapter              adap;
-       struct i2c_algo_bit_data        algo;
-};
-
-struct s_i2c_chip {
-       void __iomem *mmio;
-       struct s_i2c_bus        i2c_bus[MAX_BUSSES];
-};
-
-
-/*
- * i2c configuration
- */
-#define CYCLE_DELAY    10
-#define TIMEOUT                (HZ / 2)
-
-
-/* 
- * S3/VIA 8365/8375 registers
- */
-#define VGA_CR_IX      0x3d4
-#define VGA_CR_DATA    0x3d5
-
-#define CR_SERIAL1     0xa0    /* I2C serial communications interface */
-#define MM_SERIAL1     0xff20
-#define CR_SERIAL2     0xb1    /* DDC2 monitor communications interface */
-
-/* based on vt8365 documentation */
-#define I2C_ENAB       0x10
-#define I2C_SCL_OUT    0x01
-#define I2C_SDA_OUT    0x02
-#define I2C_SCL_IN     0x04
-#define I2C_SDA_IN     0x08
-
-#define SET_CR_IX(p, val)      writeb((val), (p)->mmvga + VGA_CR_IX)
-#define SET_CR_DATA(p, val)    writeb((val), (p)->mmvga + VGA_CR_DATA)
-#define GET_CR_DATA(p)         readb((p)->mmvga + VGA_CR_DATA)
-
-
-/*
- * Serial bus line handling
- *
- * serial communications register as parameter in private data
- *
- * TODO: locks with other code sections accessing video registers?
- */
-static void bit_s3via_setscl(void *bus, int val)
-{
-       struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
-       unsigned int r;
-
-       SET_CR_IX(p, p->i2c_reg);
-       r = GET_CR_DATA(p);
-       r |= I2C_ENAB;
-       if (val) {
-               r |= I2C_SCL_OUT;
-       } else {
-               r &= ~I2C_SCL_OUT;
-       }
-       SET_CR_DATA(p, r);
-}
-
-static void bit_s3via_setsda(void *bus, int val)
-{
-       struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
-       unsigned int r;
-       
-       SET_CR_IX(p, p->i2c_reg);
-       r = GET_CR_DATA(p);
-       r |= I2C_ENAB;
-       if (val) {
-               r |= I2C_SDA_OUT;
-       } else {
-               r &= ~I2C_SDA_OUT;
-       }
-       SET_CR_DATA(p, r);
-}
-
-static int bit_s3via_getscl(void *bus)
-{
-       struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
-
-       SET_CR_IX(p, p->i2c_reg);
-       return (0 != (GET_CR_DATA(p) & I2C_SCL_IN));
-}
-
-static int bit_s3via_getsda(void *bus)
-{
-       struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
-
-       SET_CR_IX(p, p->i2c_reg);
-       return (0 != (GET_CR_DATA(p) & I2C_SDA_IN));
-}
-
-
-/*
- * adapter initialisation
- */
-static int i2c_register_bus(struct pci_dev *dev, struct s_i2c_bus *p, void __iomem *mmvga, u32 i2c_reg)
-{
-       int ret;
-       p->adap.owner     = THIS_MODULE;
-       p->adap.id        = I2C_HW_B_S3VIA;
-       p->adap.algo_data = &p->algo;
-       p->adap.dev.parent = &dev->dev;
-       p->algo.setsda    = bit_s3via_setsda;
-       p->algo.setscl    = bit_s3via_setscl;
-       p->algo.getsda    = bit_s3via_getsda;
-       p->algo.getscl    = bit_s3via_getscl;
-       p->algo.udelay    = CYCLE_DELAY;
-       p->algo.timeout   = TIMEOUT;
-       p->algo.data      = p;
-       p->mmvga          = mmvga;
-       p->i2c_reg        = i2c_reg;
-    
-       ret = i2c_bit_add_bus(&p->adap);
-       if (ret) {
-               return ret;
-       }
-
-       p->adap_ok = 1;
-       return 0;
-}
-
-
-/*
- * Cleanup stuff
- */
-static void prosavage_remove(struct pci_dev *dev)
-{
-       struct s_i2c_chip *chip;
-       int i, ret;
-
-       chip = (struct s_i2c_chip *)pci_get_drvdata(dev);
-
-       if (!chip) {
-               return;
-       }
-       for (i = MAX_BUSSES - 1; i >= 0; i--) {
-               if (chip->i2c_bus[i].adap_ok == 0)
-                       continue;
-
-               ret = i2c_del_adapter(&chip->i2c_bus[i].adap);
-               if (ret) {
-                       dev_err(&dev->dev, "%s not removed\n",
-                               chip->i2c_bus[i].adap.name);
-               }
-       }
-       if (chip->mmio) {
-               iounmap(chip->mmio);
-       }
-       kfree(chip);
-}
-
-
-/*
- * Detect chip and initialize it
- */
-static int __devinit prosavage_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
-       int ret;
-       unsigned long base, len;
-       struct s_i2c_chip *chip;
-       struct s_i2c_bus  *bus;
-
-       pci_set_drvdata(dev, kzalloc(sizeof(struct s_i2c_chip), GFP_KERNEL));
-       chip = (struct s_i2c_chip *)pci_get_drvdata(dev);
-       if (chip == NULL) {
-               return -ENOMEM;
-       }
-
-       base = dev->resource[0].start & PCI_BASE_ADDRESS_MEM_MASK;
-       len  = dev->resource[0].end - base + 1;
-       chip->mmio = ioremap_nocache(base, len);
-
-       if (chip->mmio == NULL) {
-               dev_err(&dev->dev, "ioremap failed\n");
-               prosavage_remove(dev);
-               return -ENODEV;
-       }
-
-
-       /*
-        * Chip initialisation
-        */
-       /* Unlock Extended IO Space ??? */
-
-
-       /*
-        * i2c bus registration
-        */
-       bus = &chip->i2c_bus[0];
-       snprintf(bus->adap.name, sizeof(bus->adap.name),
-               "ProSavage I2C bus at %02x:%02x.%x",
-               dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-       ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL1);
-       if (ret) {
-               goto err_adap;
-       }
-       /*
-        * ddc bus registration
-        */
-       bus = &chip->i2c_bus[1];
-       snprintf(bus->adap.name, sizeof(bus->adap.name),
-               "ProSavage DDC bus at %02x:%02x.%x",
-               dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-       ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL2);
-       if (ret) {
-               goto err_adap;
-       }
-       return 0;
-err_adap:
-       dev_err(&dev->dev, "%s failed\n", bus->adap.name);
-       prosavage_remove(dev);
-       return ret;
-}
-
-
-/*
- * Data for PCI driver interface
- */
-static struct pci_device_id prosavage_pci_tbl[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_SAVAGE4) },
-       { PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_PROSAVAGE8) },
-       { 0, },
-};
-
-MODULE_DEVICE_TABLE (pci, prosavage_pci_tbl);
-
-static struct pci_driver prosavage_driver = {
-       .name           =       "prosavage_smbus",
-       .id_table       =       prosavage_pci_tbl,
-       .probe          =       prosavage_probe,
-       .remove         =       prosavage_remove,
-};
-
-static int __init i2c_prosavage_init(void)
-{
-       return pci_register_driver(&prosavage_driver);
-}
-
-static void __exit i2c_prosavage_exit(void)
-{
-       pci_unregister_driver(&prosavage_driver);
-}
-
-MODULE_DEVICE_TABLE(pci, prosavage_pci_tbl);
-MODULE_AUTHOR("Henk Vergonet");
-MODULE_DESCRIPTION("ProSavage VIA 8365/8375 smbus driver");
-MODULE_LICENSE("GPL");
-
-module_init (i2c_prosavage_init);
-module_exit (i2c_prosavage_exit);
index dde6ce9..af9e603 100644 (file)
@@ -1104,5 +1104,5 @@ static void __exit i2c_adap_pxa_exit(void)
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:pxa2xx-i2c");
 
-module_init(i2c_adap_pxa_init);
+subsys_initcall(i2c_adap_pxa_init);
 module_exit(i2c_adap_pxa_exit);
index 9e8c875..007390a 100644 (file)
@@ -590,7 +590,7 @@ static struct s3c24xx_i2c s3c24xx_i2c = {
                .owner                  = THIS_MODULE,
                .algo                   = &s3c24xx_i2c_algorithm,
                .retries                = 2,
-               .class                  = I2C_CLASS_HWMON,
+               .class                  = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        },
 };
 
diff --git a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c
deleted file mode 100644 (file)
index 8adf4ab..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
-    i2c-savage4.c - Part of lm_sensors, Linux kernel modules for hardware
-              monitoring
-    Copyright (C) 1998-2003  The LM Sensors Team
-    Alexander Wold <awold@bigfoot.com>
-    Mark D. Studebaker <mdsxyz123@yahoo.com>
-    
-    Based on i2c-voodoo3.c.
-
-    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.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* This interfaces to the I2C bus of the Savage4 to gain access to
-   the BT869 and possibly other I2C devices. The DDC bus is not
-   yet supported because its register is not memory-mapped.
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <asm/io.h>
-
-/* device IDs */
-#define PCI_CHIP_SAVAGE4       0x8A22
-#define PCI_CHIP_SAVAGE2000    0x9102
-
-#define REG                    0xff20  /* Serial Port 1 Register */
-
-/* bit locations in the register */
-#define I2C_ENAB               0x00000020
-#define I2C_SCL_OUT            0x00000001
-#define I2C_SDA_OUT            0x00000002
-#define I2C_SCL_IN             0x00000008
-#define I2C_SDA_IN             0x00000010
-
-/* delays */
-#define CYCLE_DELAY            10
-#define TIMEOUT                        (HZ / 2)
-
-
-static void __iomem *ioaddr;
-
-/* The sav GPIO registers don't have individual masks for each bit
-   so we always have to read before writing. */
-
-static void bit_savi2c_setscl(void *data, int val)
-{
-       unsigned int r;
-       r = readl(ioaddr + REG);
-       if(val)
-               r |= I2C_SCL_OUT;
-       else
-               r &= ~I2C_SCL_OUT;
-       writel(r, ioaddr + REG);
-       readl(ioaddr + REG);    /* flush posted write */
-}
-
-static void bit_savi2c_setsda(void *data, int val)
-{
-       unsigned int r;
-       r = readl(ioaddr + REG);
-       if(val)
-               r |= I2C_SDA_OUT;
-       else
-               r &= ~I2C_SDA_OUT;
-       writel(r, ioaddr + REG);
-       readl(ioaddr + REG);    /* flush posted write */
-}
-
-/* The GPIO pins are open drain, so the pins always remain outputs.
-   We rely on the i2c-algo-bit routines to set the pins high before
-   reading the input from other chips. */
-
-static int bit_savi2c_getscl(void *data)
-{
-       return (0 != (readl(ioaddr + REG) & I2C_SCL_IN));
-}
-
-static int bit_savi2c_getsda(void *data)
-{
-       return (0 != (readl(ioaddr + REG) & I2C_SDA_IN));
-}
-
-/* Configures the chip */
-
-static int config_s4(struct pci_dev *dev)
-{
-       unsigned long cadr;
-
-       /* map memory */
-       cadr = dev->resource[0].start;
-       cadr &= PCI_BASE_ADDRESS_MEM_MASK;
-       ioaddr = ioremap_nocache(cadr, 0x0080000);
-       if (ioaddr) {
-               /* writel(0x8160, ioaddr + REG2); */
-               writel(0x00000020, ioaddr + REG);
-               dev_info(&dev->dev, "Using Savage4 at %p\n", ioaddr);
-               return 0;
-       }
-       return -ENODEV;
-}
-
-static struct i2c_algo_bit_data sav_i2c_bit_data = {
-       .setsda         = bit_savi2c_setsda,
-       .setscl         = bit_savi2c_setscl,
-       .getsda         = bit_savi2c_getsda,
-       .getscl         = bit_savi2c_getscl,
-       .udelay         = CYCLE_DELAY,
-       .timeout        = TIMEOUT
-};
-
-static struct i2c_adapter savage4_i2c_adapter = {
-       .owner          = THIS_MODULE,
-       .id             = I2C_HW_B_SAVAGE,
-       .name           = "I2C Savage4 adapter",
-       .algo_data      = &sav_i2c_bit_data,
-};
-
-static struct pci_device_id savage4_ids[] __devinitdata = {
-       { PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE4) },
-       { PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE2000) },
-       { 0, }
-};
-
-MODULE_DEVICE_TABLE (pci, savage4_ids);
-
-static int __devinit savage4_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
-       int retval;
-
-       retval = config_s4(dev);
-       if (retval)
-               return retval;
-
-       /* set up the sysfs linkage to our parent device */
-       savage4_i2c_adapter.dev.parent = &dev->dev;
-
-       return i2c_bit_add_bus(&savage4_i2c_adapter);
-}
-
-static void __devexit savage4_remove(struct pci_dev *dev)
-{
-       i2c_del_adapter(&savage4_i2c_adapter);
-       iounmap(ioaddr);
-}
-
-static struct pci_driver savage4_driver = {
-       .name           = "savage4_smbus",
-       .id_table       = savage4_ids,
-       .probe          = savage4_probe,
-       .remove         = __devexit_p(savage4_remove),
-};
-
-static int __init i2c_savage4_init(void)
-{
-       return pci_register_driver(&savage4_driver);
-}
-
-static void __exit i2c_savage4_exit(void)
-{
-       pci_unregister_driver(&savage4_driver);
-}
-
-MODULE_AUTHOR("Alexander Wold <awold@bigfoot.com> "
-               "and Mark D. Studebaker <mdsxyz123@yahoo.com>");
-MODULE_DESCRIPTION("Savage4 I2C/SMBus driver");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_savage4_init);
-module_exit(i2c_savage4_exit);
index 114634d..4ddefbf 100644 (file)
@@ -143,7 +143,7 @@ static int __init i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed)
        csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ));
        csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL));
 
-       return i2c_add_adapter(i2c_adap);
+       return i2c_add_numbered_adapter(i2c_adap);
 }
 
 
@@ -156,17 +156,19 @@ static struct i2c_adapter sibyte_board_adapter[2] = {
        {
                .owner          = THIS_MODULE,
                .id             = I2C_HW_SIBYTE,
-               .class          = I2C_CLASS_HWMON,
+               .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
                .algo           = NULL,
                .algo_data      = &sibyte_board_data[0],
+               .nr             = 0,
                .name           = "SiByte SMBus 0",
        },
        {
                .owner          = THIS_MODULE,
                .id             = I2C_HW_SIBYTE,
-               .class          = I2C_CLASS_HWMON,
+               .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
                .algo           = NULL,
                .algo_data      = &sibyte_board_data[1],
+               .nr             = 1,
                .name           = "SiByte SMBus 1",
        },
 };
index 9ca8f91..dfc2d5e 100644 (file)
@@ -1,6 +1,4 @@
 /*
-    sis5595.c - Part of lm_sensors, Linux kernel modules for hardware
-              monitoring
     Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> and
     Philip Edelbrock <phil@netroedge.com>
 
@@ -62,6 +60,7 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
+#include <linux/acpi.h>
 #include <asm/io.h>
 
 static int blacklist[] = {
@@ -174,6 +173,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",
@@ -236,7 +240,7 @@ static int sis5595_transaction(struct i2c_adapter *adap)
                sis5595_write(SMB_STS_HI, temp >> 8);
                if ((temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8)) != 0x00) {
                        dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
-                       return -1;
+                       return -EBUSY;
                } else {
                        dev_dbg(&adap->dev, "Successful!\n");
                }
@@ -254,19 +258,19 @@ static int sis5595_transaction(struct i2c_adapter *adap)
        /* If the SMBus is still busy, we give up */
        if (timeout >= MAX_TIMEOUT) {
                dev_dbg(&adap->dev, "SMBus Timeout!\n");
-               result = -1;
+               result = -ETIMEDOUT;
        }
 
        if (temp & 0x10) {
                dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
-               result = -1;
+               result = -ENXIO;
        }
 
        if (temp & 0x20) {
                dev_err(&adap->dev, "Bus collision! SMBus may be locked until "
                        "next hard reset (or not...)\n");
                /* Clock stops and slave is stuck in mid-transmission */
-               result = -1;
+               result = -EIO;
        }
 
        temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
@@ -282,11 +286,13 @@ static int sis5595_transaction(struct i2c_adapter *adap)
        return result;
 }
 
-/* Return -1 on error. */
+/* Return negative errno on error. */
 static s32 sis5595_access(struct i2c_adapter *adap, u16 addr,
                          unsigned short flags, char read_write,
                          u8 command, int size, union i2c_smbus_data *data)
 {
+       int status;
+
        switch (size) {
        case I2C_SMBUS_QUICK:
                sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
@@ -318,13 +324,14 @@ static s32 sis5595_access(struct i2c_adapter *adap, u16 addr,
                break;
        default:
                dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
-               return -1;
+               return -EOPNOTSUPP;
        }
 
        sis5595_write(SMB_CTL_LO, ((size & 0x0E)));
 
-       if (sis5595_transaction(adap))
-               return -1;
+       status = sis5595_transaction(adap);
+       if (status)
+               return status;
 
        if ((size != SIS5595_PROC_CALL) &&
            ((read_write == I2C_SMBUS_WRITE) || (size == SIS5595_QUICK)))
@@ -359,7 +366,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 static struct i2c_adapter sis5595_adapter = {
        .owner          = THIS_MODULE,
        .id             = I2C_HW_SMBUS_SIS5595,
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .algo           = &smbus_algorithm,
 };
 
index 3765dd7..e7c4b79 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 */
@@ -134,7 +132,7 @@ static int sis630_transaction_start(struct i2c_adapter *adap, int size, u8 *oldc
 
                if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) {
                        dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
-                       return -1;
+                       return -EBUSY;
                 } else {
                        dev_dbg(&adap->dev, "Successful!\n");
                }
@@ -177,17 +175,17 @@ static int sis630_transaction_wait(struct i2c_adapter *adap, int size)
        /* If the SMBus is still busy, we give up */
        if (timeout >= MAX_TIMEOUT) {
                dev_dbg(&adap->dev, "SMBus Timeout!\n");
-               result = -1;
+               result = -ETIMEDOUT;
        }
 
        if (temp & 0x02) {
                dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
-               result = -1;
+               result = -ENXIO;
        }
 
        if (temp & 0x04) {
                dev_err(&adap->dev, "Bus collision!\n");
-               result = -1;
+               result = -EIO;
                /*
                  TBD: Datasheet say:
                  the software should clear this bit and restart SMBUS operation.
@@ -250,8 +248,10 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat
                        if (i==8 || (len<8 && i==len)) {
                                dev_dbg(&adap->dev, "start trans len=%d i=%d\n",len ,i);
                                /* first transaction */
-                               if (sis630_transaction_start(adap, SIS630_BLOCK_DATA, &oldclock))
-                                       return -1;
+                               rc = sis630_transaction_start(adap,
+                                               SIS630_BLOCK_DATA, &oldclock);
+                               if (rc)
+                                       return rc;
                        }
                        else if ((i-1)%8 == 7 || i==len) {
                                dev_dbg(&adap->dev, "trans_wait len=%d i=%d\n",len,i);
@@ -264,9 +264,10 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat
                                        */
                                        sis630_write(SMB_STS,0x10);
                                }
-                               if (sis630_transaction_wait(adap, SIS630_BLOCK_DATA)) {
+                               rc = sis630_transaction_wait(adap,
+                                               SIS630_BLOCK_DATA);
+                               if (rc) {
                                        dev_dbg(&adap->dev, "trans_wait failed\n");
-                                       rc = -1;
                                        break;
                                }
                        }
@@ -275,13 +276,14 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat
        else {
                /* read request */
                data->block[0] = len = 0;
-               if (sis630_transaction_start(adap, SIS630_BLOCK_DATA, &oldclock)) {
-                       return -1;
-               }
+               rc = sis630_transaction_start(adap,
+                               SIS630_BLOCK_DATA, &oldclock);
+               if (rc)
+                       return rc;
                do {
-                       if (sis630_transaction_wait(adap, SIS630_BLOCK_DATA)) {
+                       rc = sis630_transaction_wait(adap, SIS630_BLOCK_DATA);
+                       if (rc) {
                                dev_dbg(&adap->dev, "trans_wait failed\n");
-                               rc = -1;
                                break;
                        }
                        /* if this first transaction then read byte count */
@@ -311,11 +313,13 @@ static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *dat
        return rc;
 }
 
-/* Return -1 on error. */
+/* Return negative errno on error. */
 static s32 sis630_access(struct i2c_adapter *adap, u16 addr,
                         unsigned short flags, char read_write,
                         u8 command, int size, union i2c_smbus_data *data)
 {
+       int status;
+
        switch (size) {
                case I2C_SMBUS_QUICK:
                        sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
@@ -350,13 +354,14 @@ 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 I2C size\n");
-                       return -1;
-                       break;
+                       dev_warn(&adap->dev, "Unsupported transaction %d\n",
+                                size);
+                       return -EOPNOTSUPP;
        }
 
-       if (sis630_transaction(adap, size))
-               return -1;
+       status = sis630_transaction(adap, size);
+       if (status)
+               return status;
 
        if ((size != SIS630_PCALL) &&
                ((read_write == I2C_SMBUS_WRITE) || (size == SIS630_QUICK))) {
@@ -372,9 +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 -1;
-                       break;
        }
 
        return 0;
@@ -433,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)) {
@@ -458,7 +465,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,
 };
 
index dc235bb..f1bba63 100644 (file)
@@ -1,7 +1,4 @@
 /*
-    sis96x.c - Part of lm_sensors, Linux kernel modules for hardware
-              monitoring
-
     Copyright (c) 2003 Mark M. Hoffman <mhoffman@lightlink.com>
 
     This program is free software; you can redistribute it and/or modify
@@ -40,6 +37,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 */
@@ -111,7 +109,7 @@ static int sis96x_transaction(int size)
                /* check it again */
                if (((temp = sis96x_read(SMB_CNT)) & 0x03) != 0x00) {
                        dev_dbg(&sis96x_adapter.dev, "Failed (0x%02x)\n", temp);
-                       return -1;
+                       return -EBUSY;
                } else {
                        dev_dbg(&sis96x_adapter.dev, "Successful\n");
                }
@@ -136,19 +134,19 @@ static int sis96x_transaction(int size)
        /* If the SMBus is still busy, we give up */
        if (timeout >= MAX_TIMEOUT) {
                dev_dbg(&sis96x_adapter.dev, "SMBus Timeout! (0x%02x)\n", temp);
-               result = -1;
+               result = -ETIMEDOUT;
        }
 
        /* device error - probably missing ACK */
        if (temp & 0x02) {
                dev_dbg(&sis96x_adapter.dev, "Failed bus transaction!\n");
-               result = -1;
+               result = -ENXIO;
        }
 
        /* bus collision */
        if (temp & 0x04) {
                dev_dbg(&sis96x_adapter.dev, "Bus collision!\n");
-               result = -1;
+               result = -EIO;
        }
 
        /* Finish up by resetting the bus */
@@ -161,11 +159,12 @@ static int sis96x_transaction(int size)
        return result;
 }
 
-/* Return -1 on error. */
+/* Return negative errno on error. */
 static s32 sis96x_access(struct i2c_adapter * adap, u16 addr,
                         unsigned short flags, char read_write,
                         u8 command, int size, union i2c_smbus_data * data)
 {
+       int status;
 
        switch (size) {
        case I2C_SMBUS_QUICK:
@@ -200,20 +199,14 @@ static s32 sis96x_access(struct i2c_adapter * adap, u16 addr,
                        SIS96x_PROC_CALL : SIS96x_WORD_DATA);
                break;
 
-       case I2C_SMBUS_BLOCK_DATA:
-               /* TO DO: */
-               dev_info(&adap->dev, "SMBus block not implemented!\n");
-               return -1;
-               break;
-
        default:
-               dev_info(&adap->dev, "Unsupported I2C size\n");
-               return -1;
-               break;
+               dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
+               return -EOPNOTSUPP;
        }
 
-       if (sis96x_transaction(size))
-               return -1;
+       status = sis96x_transaction(size);
+       if (status)
+               return status;
 
        if ((size != SIS96x_PROC_CALL) &&
                ((read_write == I2C_SMBUS_WRITE) || (size == SIS96x_QUICK)))
@@ -249,7 +242,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 static struct i2c_adapter sis96x_adapter = {
        .owner          = THIS_MODULE,
        .id             = I2C_HW_SMBUS_SIS96X,
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .algo           = &smbus_algorithm,
 };
 
@@ -286,6 +279,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)) {
index d08eeec..1b7b2af 100644 (file)
@@ -43,7 +43,7 @@ struct stub_chip {
 
 static struct stub_chip *stub_chips;
 
-/* Return -1 on error. */
+/* Return negative errno on error. */
 static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,
        char read_write, u8 command, int size, union i2c_smbus_data * data)
 {
@@ -120,7 +120,7 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,
 
        default:
                dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n");
-               ret = -1;
+               ret = -EOPNOTSUPP;
                break;
        } /* switch (size) */
 
@@ -140,7 +140,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 
 static struct i2c_adapter stub_adapter = {
        .owner          = THIS_MODULE,
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .algo           = &smbus_algorithm,
        .name           = "SMBus stub driver",
 };
index de9db49..224aa12 100644 (file)
@@ -96,9 +96,8 @@ static int taos_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
                        sprintf(p, "$%02X", command);
                break;
        default:
-               dev_dbg(&adapter->dev, "Unsupported transaction size %d\n",
-                       size);
-               return -EINVAL;
+               dev_warn(&adapter->dev, "Unsupported transaction %d\n", size);
+               return -EOPNOTSUPP;
        }
 
        /* Send the transaction to the TAOS EVM */
index 61716f6..29cef04 100644 (file)
@@ -1,7 +1,4 @@
 /*
-    i2c-via.c - Part of lm_sensors,  Linux kernel modules
-                for hardware monitoring
-
     i2c Support for Via Technologies 82C586B South Bridge
 
     Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
@@ -87,7 +84,7 @@ static struct i2c_algo_bit_data bit_data = {
 static struct i2c_adapter vt586b_adapter = {
        .owner          = THIS_MODULE,
        .id             = I2C_HW_B_VIA,
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .name           = "VIA i2c",
        .algo_data      = &bit_data,
 };
index 77b13d0..862eb35 100644 (file)
@@ -1,6 +1,4 @@
 /*
-    i2c-viapro.c - Part of lm_sensors, Linux kernel modules for hardware
-              monitoring
     Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
     Philip Edelbrock <phil@netroedge.com>, Kyösti Mälkki <kmalkki@cc.hut.fi>,
     Mark D. Studebaker <mdsxyz123@yahoo.com>
@@ -50,6 +48,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;
@@ -152,7 +151,7 @@ static int vt596_transaction(u8 size)
                if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
                        dev_err(&vt596_adapter.dev, "SMBus reset failed! "
                                "(0x%02x)\n", temp);
-                       return -1;
+                       return -EBUSY;
                }
        }
 
@@ -167,24 +166,24 @@ static int vt596_transaction(u8 size)
 
        /* If the SMBus is still busy, we give up */
        if (timeout >= MAX_TIMEOUT) {
-               result = -1;
+               result = -ETIMEDOUT;
                dev_err(&vt596_adapter.dev, "SMBus timeout!\n");
        }
 
        if (temp & 0x10) {
-               result = -1;
+               result = -EIO;
                dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n",
                        size);
        }
 
        if (temp & 0x08) {
-               result = -1;
+               result = -EIO;
                dev_err(&vt596_adapter.dev, "SMBus collision!\n");
        }
 
        if (temp & 0x04) {
                int read = inb_p(SMBHSTADD) & 0x01;
-               result = -1;
+               result = -ENXIO;
                /* The quick and receive byte commands are used to probe
                   for chips, so errors are expected, and we don't want
                   to frighten the user. */
@@ -202,12 +201,13 @@ static int vt596_transaction(u8 size)
        return result;
 }
 
-/* Return -1 on error, 0 on success */
+/* Return negative errno on error, 0 on success */
 static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
                unsigned short flags, char read_write, u8 command,
                int size, union i2c_smbus_data *data)
 {
        int i;
+       int status;
 
        switch (size) {
        case I2C_SMBUS_QUICK:
@@ -258,8 +258,9 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
 
        outb_p(((addr & 0x7f) << 1) | read_write, SMBHSTADD);
 
-       if (vt596_transaction(size)) /* Error in transaction */
-               return -1;
+       status = vt596_transaction(size);
+       if (status)
+               return status;
 
        if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK))
                return 0;
@@ -285,9 +286,9 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
        return 0;
 
 exit_unsupported:
-       dev_warn(&vt596_adapter.dev, "Unsupported command invoked! (0x%02x)\n",
+       dev_warn(&vt596_adapter.dev, "Unsupported transaction %d\n",
                 size);
-       return -1;
+       return -EOPNOTSUPP;
 }
 
 static u32 vt596_func(struct i2c_adapter *adapter)
@@ -309,7 +310,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 static struct i2c_adapter vt596_adapter = {
        .owner          = THIS_MODULE,
        .id             = I2C_HW_SMBUS_VIA2,
-       .class          = I2C_CLASS_HWMON,
+       .class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
        .algo           = &smbus_algorithm,
 };
 
@@ -354,6 +355,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);
index 88a3447..1d4ae26 100644 (file)
@@ -1,6 +1,4 @@
 /*
-    voodoo3.c - Part of lm_sensors, Linux kernel modules for hardware
-              monitoring
     Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>,
     Philip Edelbrock <phil@netroedge.com>,
     Ralph Metzler <rjkm@thp.uni-koeln.de>, and
index 61abe0f..ed794b1 100644 (file)
@@ -442,7 +442,7 @@ static __init struct scx200_acb_iface *scx200_create_iface(const char *text,
        adapter->owner = THIS_MODULE;
        adapter->id = I2C_HW_SMBUS_SCX200;
        adapter->algo = &scx200_acb_algorithm;
-       adapter->class = I2C_CLASS_HWMON;
+       adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
        adapter->dev.parent = dev;
 
        mutex_init(&iface->mutex);
index 2da2edf..50e0a46 100644 (file)
@@ -14,6 +14,32 @@ config DS1682
          This driver can also be built as a module.  If so, the module
          will be called ds1682.
 
+config AT24
+       tristate "EEPROMs from most vendors"
+       depends on SYSFS && EXPERIMENTAL
+       help
+         Enable this driver to get read/write support to most I2C EEPROMs,
+         after you configure the driver to know about each EEPROM on
+         your target board.  Use these generic chip names, instead of
+         vendor-specific ones like at24c64 or 24lc02:
+
+            24c00, 24c01, 24c02, spd (readonly 24c02), 24c04, 24c08,
+            24c16, 24c32, 24c64, 24c128, 24c256, 24c512, 24c1024
+
+         Unless you like data loss puzzles, always be sure that any chip
+         you configure as a 24c32 (32 kbit) or larger is NOT really a
+         24c16 (16 kbit) or smaller, and vice versa. Marking the chip
+         as read-only won't help recover from this. Also, if your chip
+         has any software write-protect mechanism you may want to review the
+         code to make sure this driver won't turn it on by accident.
+
+         If you use this with an SMBus adapter instead of an I2C adapter,
+         full functionality is not available.  Only smaller devices are
+         supported (24c16 and below, max 4 kByte).
+
+         This driver can also be built as a module.  If so, the module
+         will be called at24.
+
 config SENSORS_EEPROM
        tristate "EEPROM reader"
        depends on EXPERIMENTAL
@@ -26,8 +52,8 @@ config SENSORS_EEPROM
          will be called eeprom.
 
 config SENSORS_PCF8574
-       tristate "Philips PCF8574 and PCF8574A"
-       depends on EXPERIMENTAL
+       tristate "Philips PCF8574 and PCF8574A (DEPRECATED)"
+       depends on EXPERIMENTAL && GPIO_PCF857X = "n"
        default n
        help
          If you say yes here you get support for Philips PCF8574 and 
@@ -36,12 +62,16 @@ config SENSORS_PCF8574
          This driver can also be built as a module.  If so, the module
          will be called pcf8574.
 
+         This driver is deprecated and will be dropped soon. Use
+         drivers/gpio/pcf857x.c instead.
+
          These devices are hard to detect and rarely found on mainstream
          hardware.  If unsure, say N.
 
 config PCF8575
-       tristate "Philips PCF8575"
+       tristate "Philips PCF8575 (DEPRECATED)"
        default n
+       depends on GPIO_PCF857X = "n"
        help
          If you say yes here you get support for Philips PCF8575 chip.
          This chip is a 16-bit I/O expander for the I2C bus.  Several other
@@ -50,12 +80,15 @@ config PCF8575
          This driver can also be built as a module.  If so, the module
          will be called pcf8575.
 
+         This driver is deprecated and will be dropped soon. Use
+         drivers/gpio/pcf857x.c instead.
+
          This device is hard to detect and is rarely found on mainstream
          hardware.  If unsure, say N.
 
 config SENSORS_PCA9539
        tristate "Philips PCA9539 16-bit I/O port (DEPRECATED)"
-       depends on EXPERIMENTAL && GPIO_PCA9539 = "n"
+       depends on EXPERIMENTAL && GPIO_PCA953X = "n"
        help
          If you say yes here you get support for the Philips PCA9539
          16-bit I/O port.
@@ -64,7 +97,7 @@ config SENSORS_PCA9539
          will be called pca9539.
 
          This driver is deprecated and will be dropped soon. Use
-         drivers/gpio/pca9539.c instead.
+         drivers/gpio/pca953x.c instead.
 
 config SENSORS_PCF8591
        tristate "Philips PCF8591"
index e47aca0..39e3e69 100644 (file)
@@ -10,6 +10,7 @@
 #
 
 obj-$(CONFIG_DS1682)           += ds1682.o
+obj-$(CONFIG_AT24)             +=&nbs