aboutsummaryrefslogtreecommitdiffstats
path: root/i2c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-06-16 15:47:28 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-16 15:47:28 -0700
commitae4fdf0ab440307765180d3bf027037c8a67d0ba (patch)
tree95e6c99160b6cb36d6ca6ea9e285f45da39c3742 /i2c
parent5b88ea4d35a4788dcfbc3047149276898e194a4b (diff)
downloadpatches-ae4fdf0ab440307765180d3bf027037c8a67d0ba.tar.gz
i2c patches added
Diffstat (limited to 'i2c')
-rw-r--r--i2c/hwmon-kconfig-header-fix.patch27
-rw-r--r--i2c/hwmon-lm70-new-driver.patch267
-rw-r--r--i2c/hwmon-vid-add-core-and-conroe-support.patch97
-rw-r--r--i2c/i2c-i801-01-fix-block-transaction-poll-loops.patch45
-rw-r--r--i2c/i2c-i801-02-remove-force_addr-parameter.patch93
-rw-r--r--i2c/i2c-i801-03-remove-pci-function-check.patch35
-rw-r--r--i2c/i2c-i801-04-cleanups.patch117
-rw-r--r--i2c/i2c-i801-05-better-pci-subsystem-integration.patch116
-rw-r--r--i2c/i2c-i801-06-merge-setup-function.patch178
-rw-r--r--i2c/i2c-mark-data-const-for-write-block.patch61
-rw-r--r--i2c/i2c-opencores-cleanup.patch61
-rw-r--r--i2c/i2c-scx200_acb-documentation-update.patch66
-rw-r--r--i2c/i2c-scx200_acb-mark-scx200_acb_probe-init.patch30
-rw-r--r--i2c/i2c-scx200_acb-use-PCI-IO-resource-when-appropriate.patch304
14 files changed, 1497 insertions, 0 deletions
diff --git a/i2c/hwmon-kconfig-header-fix.patch b/i2c/hwmon-kconfig-header-fix.patch
new file mode 100644
index 0000000000000..d43bb98672e48
--- /dev/null
+++ b/i2c/hwmon-kconfig-header-fix.patch
@@ -0,0 +1,27 @@
+From khali@linux-fr.org Mon Jun 12 12:55:28 2006
+Date: Mon, 12 Jun 2006 21:55:28 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Cc: LM Sensors <lm-sensors@lm-sensors.org>, Kaiwan N Billimoria <kaiwan@designergraphix.com>
+Subject: [PATCH 12/14] hwmon: Fix the Kconfig header
+Message-Id: <20060612215528.e72133d5.khali@linux-fr.org>
+Content-Disposition: inline; filename=hwmon-kconfig-header-fix.patch
+
+Hardware monitoring chips don't have to be on the I2C bus.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hwmon/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- gregkh-2.6.orig/drivers/hwmon/Kconfig
++++ gregkh-2.6/drivers/hwmon/Kconfig
+@@ -1,5 +1,5 @@
+ #
+-# I2C Sensor chip drivers configuration
++# Hardware monitoring chip drivers configuration
+ #
+
+ menu "Hardware Monitoring support"
diff --git a/i2c/hwmon-lm70-new-driver.patch b/i2c/hwmon-lm70-new-driver.patch
new file mode 100644
index 0000000000000..b4c6478cd80bf
--- /dev/null
+++ b/i2c/hwmon-lm70-new-driver.patch
@@ -0,0 +1,267 @@
+From khali@linux-fr.org Mon Jun 12 13:00:12 2006
+Date: Mon, 12 Jun 2006 22:00:05 +0200
+From: Kaiwan N Billimoria <kaiwan@designergraphix.com>
+To: Greg KH <greg@kroah.com>
+Cc: LM Sensors <lm-sensors@lm-sensors.org>, Kaiwan N Billimoria <kaiwan@designergraphix.com>
+Subject: [PATCH 13/14] lm70: New hardware monitoring driver
+Message-Id: <20060612220005.cd9ce8ad.khali@linux-fr.org>
+Content-Disposition: inline; filename=hwmon-lm70-new-driver.patch
+
+From: Kaiwan N Billimoria <kaiwan@designergraphix.com>
+
+This driver implements support for the National Semiconductor LM70
+temperature sensor.
+
+The LM70 temperature sensor chip supports a single temperature sensor.
+It communicates with a host processor (or microcontroller) via an
+SPI/Microwire Bus interface.
+
+Communication with the LM70 is simple: when the temperature is to be sensed,
+the driver accesses the LM70 using SPI communication: 16 SCLK cycles
+comprise the MOSI/MISO loop. At the end of the transfer, the 11-bit 2's
+complement digital temperature (sent via the SIO line), is available in the
+driver for interpretation. This driver makes use of the kernel's in-core
+SPI support.
+
+Signed-off-by: Kaiwan N Billimoria <kaiwan@designergraphix.com>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/hwmon/lm70 | 31 ++++++++
+ drivers/hwmon/Kconfig | 10 ++
+ drivers/hwmon/Makefile | 1
+ drivers/hwmon/lm70.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 207 insertions(+)
+
+--- /dev/null
++++ gregkh-2.6/Documentation/hwmon/lm70
+@@ -0,0 +1,31 @@
++Kernel driver lm70
++==================
++
++Supported chip:
++ * National Semiconductor LM70
++ Datasheet: http://www.national.com/pf/LM/LM70.html
++
++Author:
++ Kaiwan N Billimoria <kaiwan@designergraphix.com>
++
++Description
++-----------
++
++This driver implements support for the National Semiconductor LM70
++temperature sensor.
++
++The LM70 temperature sensor chip supports a single temperature sensor.
++It communicates with a host processor (or microcontroller) via an
++SPI/Microwire Bus interface.
++
++Communication with the LM70 is simple: when the temperature is to be sensed,
++the driver accesses the LM70 using SPI communication: 16 SCLK cycles
++comprise the MOSI/MISO loop. At the end of the transfer, the 11-bit 2's
++complement digital temperature (sent via the SIO line), is available in the
++driver for interpretation. This driver makes use of the kernel's in-core
++SPI support.
++
++Thanks to
++---------
++Jean Delvare <khali@linux-fr.org> for mentoring the hwmon-side driver
++development.
+--- gregkh-2.6.orig/drivers/hwmon/Kconfig
++++ gregkh-2.6/drivers/hwmon/Kconfig
+@@ -204,6 +204,16 @@ config SENSORS_LM63
+ This driver can also be built as a module. If so, the module
+ will be called lm63.
+
++config SENSORS_LM70
++ tristate "National Semiconductor LM70"
++ depends on HWMON && SPI_MASTER && EXPERIMENTAL
++ help
++ If you say yes here you get support for the National Semiconductor
++ LM70 digital temperature sensor chip.
++
++ This driver can also be built as a module. If so, the module
++ will be called lm70.
++
+ config SENSORS_LM75
+ tristate "National Semiconductor LM75 and compatibles"
+ depends on HWMON && I2C
+--- gregkh-2.6.orig/drivers/hwmon/Makefile
++++ gregkh-2.6/drivers/hwmon/Makefile
+@@ -28,6 +28,7 @@ obj-$(CONFIG_SENSORS_GL520SM) += gl520sm
+ obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o
+ obj-$(CONFIG_SENSORS_IT87) += it87.o
+ obj-$(CONFIG_SENSORS_LM63) += lm63.o
++obj-$(CONFIG_SENSORS_LM70) += lm70.o
+ obj-$(CONFIG_SENSORS_LM75) += lm75.o
+ obj-$(CONFIG_SENSORS_LM77) += lm77.o
+ obj-$(CONFIG_SENSORS_LM78) += lm78.o
+--- /dev/null
++++ gregkh-2.6/drivers/hwmon/lm70.c
+@@ -0,0 +1,165 @@
++/*
++ * lm70.c
++ *
++ * The LM70 is a temperature sensor chip from National Semiconductor (NS).
++ * Copyright (C) 2006 Kaiwan N Billimoria <kaiwan@designergraphix.com>
++ *
++ * The LM70 communicates with a host processor via an SPI/Microwire Bus
++ * interface. The complete datasheet is available at National's website
++ * here:
++ * http://www.national.com/pf/LM/LM70.html
++ *
++ * 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/init.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/device.h>
++#include <linux/err.h>
++#include <linux/sysfs.h>
++#include <linux/hwmon.h>
++#include <linux/spi/spi.h>
++#include <asm/semaphore.h>
++
++#define DRVNAME "lm70"
++
++struct lm70 {
++ struct class_device *cdev;
++ struct semaphore sem;
++};
++
++/* sysfs hook function */
++static ssize_t lm70_sense_temp(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct spi_device *spi = to_spi_device(dev);
++ int status, val;
++ u8 rxbuf[2];
++ s16 raw=0;
++ struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
++
++ if (down_interruptible(&p_lm70->sem))
++ return -ERESTARTSYS;
++
++ /*
++ * spi_read() requires a DMA-safe buffer; so we use
++ * spi_write_then_read(), transmitting 0 bytes.
++ */
++ status = spi_write_then_read(spi, NULL, 0, &rxbuf[0], 2);
++ if (status < 0) {
++ printk(KERN_WARNING
++ "spi_write_then_read failed with status %d\n", status);
++ goto out;
++ }
++ dev_dbg(dev, "rxbuf[1] : 0x%x rxbuf[0] : 0x%x\n", rxbuf[1], rxbuf[0]);
++
++ raw = (rxbuf[1] << 8) + rxbuf[0];
++ dev_dbg(dev, "raw=0x%x\n", raw);
++
++ /*
++ * The "raw" temperature read into rxbuf[] is a 16-bit signed 2's
++ * complement value. Only the MSB 11 bits (1 sign + 10 temperature
++ * bits) are meaningful; the LSB 5 bits are to be discarded.
++ * See the datasheet.
++ *
++ * Further, each bit represents 0.25 degrees Celsius; so, multiply
++ * by 0.25. Also multiply by 1000 to represent in millidegrees
++ * Celsius.
++ * So it's equivalent to multiplying by 0.25 * 1000 = 250.
++ */
++ val = ((int)raw/32) * 250;
++ status = sprintf(buf, "%+d\n", val); /* millidegrees Celsius */
++out:
++ up(&p_lm70->sem);
++ return status;
++}
++
++static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL);
++
++/*----------------------------------------------------------------------*/
++
++static int __devinit lm70_probe(struct spi_device *spi)
++{
++ struct lm70 *p_lm70;
++ int status;
++
++ p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL);
++ if (!p_lm70)
++ return -ENOMEM;
++
++ init_MUTEX(&p_lm70->sem);
++
++ /* sysfs hook */
++ p_lm70->cdev = hwmon_device_register(&spi->dev);
++ if (IS_ERR(p_lm70->cdev)) {
++ dev_dbg(&spi->dev, "hwmon_device_register failed.\n");
++ status = PTR_ERR(p_lm70->cdev);
++ goto out_dev_reg_failed;
++ }
++ dev_set_drvdata(&spi->dev, p_lm70);
++
++ if ((status = device_create_file(&spi->dev, &dev_attr_temp1_input))) {
++ dev_dbg(&spi->dev, "device_create_file failure.\n");
++ goto out_dev_create_file_failed;
++ }
++
++ return 0;
++
++out_dev_create_file_failed:
++ hwmon_device_unregister(p_lm70->cdev);
++out_dev_reg_failed:
++ dev_set_drvdata(&spi->dev, NULL);
++ kfree(p_lm70);
++ return status;
++}
++
++static int __exit lm70_remove(struct spi_device *spi)
++{
++ struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
++
++ device_remove_file(&spi->dev, &dev_attr_temp1_input);
++ hwmon_device_unregister(p_lm70->cdev);
++ dev_set_drvdata(&spi->dev, NULL);
++ kfree(p_lm70);
++
++ return 0;
++}
++
++static struct spi_driver lm70_driver = {
++ .driver = {
++ .name = "lm70",
++ .owner = THIS_MODULE,
++ },
++ .probe = lm70_probe,
++ .remove = __devexit_p(lm70_remove),
++};
++
++static int __init init_lm70(void)
++{
++ return spi_register_driver(&lm70_driver);
++}
++
++static void __exit cleanup_lm70(void)
++{
++ spi_unregister_driver(&lm70_driver);
++}
++
++module_init(init_lm70);
++module_exit(cleanup_lm70);
++
++MODULE_AUTHOR("Kaiwan N Billimoria");
++MODULE_DESCRIPTION("National Semiconductor LM70 Linux driver");
++MODULE_LICENSE("GPL");
diff --git a/i2c/hwmon-vid-add-core-and-conroe-support.patch b/i2c/hwmon-vid-add-core-and-conroe-support.patch
new file mode 100644
index 0000000000000..da633740be56d
--- /dev/null
+++ b/i2c/hwmon-vid-add-core-and-conroe-support.patch
@@ -0,0 +1,97 @@
+From khali@linux-fr.org Mon Jun 12 13:00:57 2006
+Date: Mon, 12 Jun 2006 22:00:53 +0200
+From: Rudolf Marek <r.marek@sh.cvut.cz>
+To: Greg KH <greg@kroah.com>
+Cc: LM Sensors <lm-sensors@lm-sensors.org>, Rudolf Marek <r.marek@sh.cvut.cz>
+Subject: [PATCH 14/14] hwmon-vid: Add support for Intel Core and Conroe
+Message-Id: <20060612220053.622e56c6.khali@linux-fr.org>
+Content-Disposition: inline; filename=hwmon-vid-add-core-and-conroe-support.patch
+
+From: Rudolf Marek <r.marek@sh.cvut.cz>
+
+This patch adds support for two new VID codes, supporting Intel mobile Core
+processors and new Conroe based platforms.
+
+Signed-off-by: Rudolf Marek <r.marek@sh.cvut.cz>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hwmon/hwmon-vid.c | 35 ++++++++++++++++++++++++++++-------
+ 1 file changed, 28 insertions(+), 7 deletions(-)
+
+--- gregkh-2.6.orig/drivers/hwmon/hwmon-vid.c
++++ gregkh-2.6/drivers/hwmon/hwmon-vid.c
+@@ -58,11 +58,20 @@
+ doesn't seem to be any named specification for these. The conversion
+ tables are detailed directly in the various Pentium M datasheets:
+ http://www.intel.com/design/intarch/pentiumm/docs_pentiumm.htm
++
++ The 14 specification corresponds to Intel Core series. There
++ doesn't seem to be any named specification for these. The conversion
++ tables are detailed directly in the various Pentium Core datasheets:
++ http://www.intel.com/design/mobile/datashts/309221.htm
++
++ The 110 (VRM 11) specification corresponds to Intel Conroe based series.
++ http://www.intel.com/design/processor/applnots/313214.htm
+ */
+
+ /* vrm is the VRM/VRD document version multiplied by 10.
+- val is the 4-, 5- or 6-bit VID code.
+- Returned value is in mV to avoid floating point in the kernel. */
++ val is the 4-bit or more VID code.
++ Returned value is in mV to avoid floating point in the kernel.
++ Some VID have some bits in uV scale, this is rounded to mV */
+ int vid_from_reg(int val, u8 vrm)
+ {
+ int vid;
+@@ -70,18 +79,24 @@ int vid_from_reg(int val, u8 vrm)
+ switch(vrm) {
+
+ case 100: /* VRD 10.0 */
++ /* compute in uV, round to mV */
+ val &= 0x3f;
+ if((val & 0x1f) == 0x1f)
+ return 0;
+ if((val & 0x1f) <= 0x09 || val == 0x0a)
+- vid = 10875 - (val & 0x1f) * 250;
++ vid = 1087500 - (val & 0x1f) * 25000;
+ else
+- vid = 18625 - (val & 0x1f) * 250;
++ vid = 1862500 - (val & 0x1f) * 25000;
+ if(val & 0x20)
+- vid -= 125;
+- vid /= 10; /* only return 3 dec. places for now */
+- return vid;
++ vid -= 12500;
++ return((vid + 500) / 1000);
+
++ case 110: /* Intel Conroe */
++ /* compute in uV, round to mV */
++ val &= 0xff;
++ if(((val & 0x7e) == 0xfe) || (!(val & 0x7e)))
++ return 0;
++ return((1600000 - (val - 2) * 6250 + 500) / 1000);
+ case 24: /* Opteron processor */
+ val &= 0x1f;
+ return(val == 0x1f ? 0 : 1550 - val * 25);
+@@ -113,6 +128,10 @@ int vid_from_reg(int val, u8 vrm)
+ case 13:
+ val &= 0x3f;
+ return(1708 - val * 16);
++ case 14: /* Intel Core */
++ /* compute in uV, round to mV */
++ val &= 0x7f;
++ return(val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000);
+ default: /* report 0 for unknown */
+ printk(KERN_INFO "hwmon-vid: requested unknown VRM version\n");
+ return 0;
+@@ -145,6 +164,8 @@ static struct vrm_model vrm_models[] = {
+ {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */
+ {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */
+ {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */
++ {X86_VENDOR_INTEL, 0x6, 0xE, ANY, 14}, /* Intel Core (65 nm) */
++ {X86_VENDOR_INTEL, 0x6, 0xF, ANY, 110}, /* Intel Conroe */
+ {X86_VENDOR_INTEL, 0x6, ANY, ANY, 82}, /* any P6 */
+ {X86_VENDOR_INTEL, 0x7, ANY, ANY, 0}, /* Itanium */
+ {X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90}, /* P4 */
diff --git a/i2c/i2c-i801-01-fix-block-transaction-poll-loops.patch b/i2c/i2c-i801-01-fix-block-transaction-poll-loops.patch
new file mode 100644
index 0000000000000..cfbfec3780004
--- /dev/null
+++ b/i2c/i2c-i801-01-fix-block-transaction-poll-loops.patch
@@ -0,0 +1,45 @@
+From khali@linux-fr.org Mon Jun 12 12:49:39 2006
+Date: Mon, 12 Jun 2006 21:49:36 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Cc: LM Sensors <lm-sensors@lm-sensors.org>
+Subject: [PATCH 06/14] i2c-i801: Fix block transaction poll loops
+Message-Id: <20060612214936.d81fd1b9.khali@linux-fr.org>
+Content-Disposition: inline; filename=i2c-i801-01-fix-block-transaction-poll-loops.patch
+
+i2c-i801: Fix block transaction poll loops
+
+Two of the three poll loops have the poll and sleep swapped,
+causing an extra sleep to occur after the polled condition is
+fulfilled. In practice, this doubles the amount of sleep time for
+every block transaction.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/i2c/busses/i2c-i801.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- gregkh-2.6.orig/drivers/i2c/busses/i2c-i801.c
++++ gregkh-2.6/drivers/i2c/busses/i2c-i801.c
+@@ -334,8 +334,8 @@ static int i801_block_transaction(union
+ /* We will always wait for a fraction of a second! */
+ timeout = 0;
+ do {
+- temp = inb_p(SMBHSTSTS);
+ msleep(1);
++ temp = inb_p(SMBHSTSTS);
+ }
+ while ((!(temp & 0x80))
+ && (timeout++ < MAX_TIMEOUT));
+@@ -393,8 +393,8 @@ static int i801_block_transaction(union
+ /* wait for INTR bit as advised by Intel */
+ timeout = 0;
+ do {
+- temp = inb_p(SMBHSTSTS);
+ msleep(1);
++ temp = inb_p(SMBHSTSTS);
+ } while ((!(temp & 0x02))
+ && (timeout++ < MAX_TIMEOUT));
+
diff --git a/i2c/i2c-i801-02-remove-force_addr-parameter.patch b/i2c/i2c-i801-02-remove-force_addr-parameter.patch
new file mode 100644
index 0000000000000..46f6b5b3dfa42
--- /dev/null
+++ b/i2c/i2c-i801-02-remove-force_addr-parameter.patch
@@ -0,0 +1,93 @@
+From khali@linux-fr.org Mon Jun 12 12:50:22 2006
+Date: Mon, 12 Jun 2006 21:50:11 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Cc: LM Sensors <lm-sensors@lm-sensors.org>
+Subject: [PATCH 07/14] i2c-i801: Remove force_addr parameter
+Message-Id: <20060612215011.c5843671.khali@linux-fr.org>
+Content-Disposition: inline; filename=i2c-i801-02-remove-force_addr-parameter.patch
+
+i2c-i801: Remove force_addr parameter
+
+Remove the force_addr module parameter. It doesn't appear to ever
+have been needed, and PCI resources shouldn't be arbitrarily
+changed anyway.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/i2c/busses/i2c-i801 | 3 +--
+ drivers/i2c/busses/i2c-i801.c | 35 +++++++----------------------------
+ 2 files changed, 8 insertions(+), 30 deletions(-)
+
+--- gregkh-2.6.orig/Documentation/i2c/busses/i2c-i801
++++ gregkh-2.6/Documentation/i2c/busses/i2c-i801
+@@ -21,8 +21,7 @@ Authors:
+ Module Parameters
+ -----------------
+
+-* force_addr: int
+- Forcibly enable the ICH at the given address. EXTREMELY DANGEROUS!
++None.
+
+
+ Description
+--- gregkh-2.6.orig/drivers/i2c/busses/i2c-i801.c
++++ gregkh-2.6/drivers/i2c/busses/i2c-i801.c
+@@ -92,15 +92,6 @@
+ #define I801_START 0x40
+ #define I801_PEC_EN 0x80 /* ICH4 only */
+
+-/* insmod parameters */
+-
+-/* If force_addr is set to anything different from 0, we forcibly enable
+- the I801 at the given address. VERY DANGEROUS! */
+-static u16 force_addr;
+-module_param(force_addr, ushort, 0);
+-MODULE_PARM_DESC(force_addr,
+- "Forcibly enable the I801 at the given address. "
+- "EXTREMELY DANGEROUS!");
+
+ static int i801_transaction(void);
+ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
+@@ -129,16 +120,12 @@ static int i801_setup(struct pci_dev *de
+ isich4 = 0;
+
+ /* Determine the address of the SMBus areas */
+- if (force_addr) {
+- i801_smba = force_addr & 0xfff0;
+- } else {
+- pci_read_config_word(I801_dev, SMBBA, &i801_smba);
+- i801_smba &= 0xfff0;
+- if(i801_smba == 0) {
+- dev_err(&dev->dev, "SMB base address uninitialized "
+- "- upgrade BIOS or use force_addr=0xaddr\n");
+- return -ENODEV;
+- }
++ pci_read_config_word(I801_dev, SMBBA, &i801_smba);
++ i801_smba &= 0xfff0;
++ if (!i801_smba) {
++ dev_err(&dev->dev, "SMBus base address uninitialized, "
++ "upgrade BIOS\n");
++ return -ENODEV;
+ }
+
+ if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) {
+@@ -152,15 +139,7 @@ static int i801_setup(struct pci_dev *de
+ temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
+ pci_write_config_byte(I801_dev, SMBHSTCFG, temp);
+
+- /* If force_addr is set, we program the new address here. Just to make
+- sure, we disable the device first. */
+- if (force_addr) {
+- pci_write_config_byte(I801_dev, SMBHSTCFG, temp & 0xfe);
+- pci_write_config_word(I801_dev, SMBBA, i801_smba);
+- pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 0x01);
+- dev_warn(&dev->dev, "WARNING: I801 SMBus interface set to "
+- "new address %04x!\n", i801_smba);
+- } else if ((temp & 1) == 0) {
++ if (!(temp & 1)) {
+ pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 1);
+ dev_warn(&dev->dev, "enabling SMBus device\n");
+ }
diff --git a/i2c/i2c-i801-03-remove-pci-function-check.patch b/i2c/i2c-i801-03-remove-pci-function-check.patch
new file mode 100644
index 0000000000000..7e4f8153fd17e
--- /dev/null
+++ b/i2c/i2c-i801-03-remove-pci-function-check.patch
@@ -0,0 +1,35 @@
+From khali@linux-fr.org Mon Jun 12 12:51:28 2006
+Date: Mon, 12 Jun 2006 21:51:20 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Cc: LM Sensors <lm-sensors@lm-sensors.org>
+Subject: [PATCH 08/14] i2c-i801: Remove PCI function check
+Message-Id: <20060612215120.0578fd85.khali@linux-fr.org>
+Content-Disposition: inline; filename=i2c-i801-03-remove-pci-function-check.patch
+
+i2c-i801: Remove PCI function check
+
+Remove the PCI function number check when probing devices.
+This check is redundant, each function has a separate PCI device
+ID, so checking for that ID is sufficient.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/i2c/busses/i2c-i801.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+--- gregkh-2.6.orig/drivers/i2c/busses/i2c-i801.c
++++ gregkh-2.6/drivers/i2c/busses/i2c-i801.c
+@@ -107,10 +107,6 @@ static int i801_setup(struct pci_dev *de
+ int error_return = 0;
+ unsigned char temp;
+
+- /* Note: we keep on searching until we have found 'function 3' */
+- if(PCI_FUNC(dev->devfn) != 3)
+- return -ENODEV;
+-
+ I801_dev = dev;
+ if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) ||
+ (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) ||
diff --git a/i2c/i2c-i801-04-cleanups.patch b/i2c/i2c-i801-04-cleanups.patch
new file mode 100644
index 0000000000000..fb963863fbed1
--- /dev/null
+++ b/i2c/i2c-i801-04-cleanups.patch
@@ -0,0 +1,117 @@
+From khali@linux-fr.org Mon Jun 12 12:52:12 2006
+Date: Mon, 12 Jun 2006 21:52:02 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Cc: LM Sensors <lm-sensors@lm-sensors.org>
+Subject: [PATCH 09/14] i2c-i801: Cleanups
+Message-Id: <20060612215202.7c2541df.khali@linux-fr.org>
+Content-Disposition: inline; filename=i2c-i801-04-cleanups.patch
+
+i2c-i801: Cleanups
+
+Various cleanups to the i2c-i801 driver:
+* Fix documentation file and self file name references.
+* i801_setup can be marked __devinit.
+* Drop useless error local variable and label in i801_setup.
+* Avoid a double PCI configuration register write in some cases.
+* Use symbolic names for SMBHSTCFG bits.
+* Transmit the error code returned by i801_setup instead of forcing it
+ to an arbitrary value.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/i2c/busses/i2c-i801.c | 32 +++++++++++++-------------------
+ 1 file changed, 13 insertions(+), 19 deletions(-)
+
+--- gregkh-2.6.orig/drivers/i2c/busses/i2c-i801.c
++++ gregkh-2.6/drivers/i2c/busses/i2c-i801.c
+@@ -1,5 +1,5 @@
+ /*
+- i801.c - Part of lm_sensors, Linux kernel modules for hardware
++ 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
+@@ -36,7 +36,7 @@
+ This driver supports several versions of Intel's I/O Controller Hubs (ICH).
+ For SMBus support, they are similar to the PIIX4 and are part
+ of Intel's '810' and other chipsets.
+- See the doc/busses/i2c-i801 file for details.
++ See the file Documentation/i2c/busses/i2c-i801 for details.
+ I2C Block Read and Process Call are not supported.
+ */
+
+@@ -102,9 +102,8 @@ static struct pci_driver i801_driver;
+ static struct pci_dev *I801_dev;
+ static int isich4;
+
+-static int i801_setup(struct pci_dev *dev)
++static int __devinit i801_setup(struct pci_dev *dev)
+ {
+- int error_return = 0;
+ unsigned char temp;
+
+ I801_dev = dev;
+@@ -115,7 +114,7 @@ static int i801_setup(struct pci_dev *de
+ else
+ isich4 = 0;
+
+- /* Determine the address of the SMBus areas */
++ /* Determine the address of the SMBus area */
+ pci_read_config_word(I801_dev, SMBBA, &i801_smba);
+ i801_smba &= 0xfff0;
+ if (!i801_smba) {
+@@ -127,20 +126,18 @@ static int i801_setup(struct pci_dev *de
+ if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) {
+ dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n",
+ i801_smba);
+- error_return = -EBUSY;
+- goto END;
++ return -EBUSY;
+ }
+
+ pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
+ temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
+- pci_write_config_byte(I801_dev, SMBHSTCFG, temp);
+-
+- if (!(temp & 1)) {
+- pci_write_config_byte(I801_dev, SMBHSTCFG, temp | 1);
++ if (!(temp & SMBHSTCFG_HST_EN)) {
+ dev_warn(&dev->dev, "enabling SMBus device\n");
++ temp |= SMBHSTCFG_HST_EN;
+ }
++ pci_write_config_byte(I801_dev, SMBHSTCFG, temp);
+
+- if (temp & 0x02)
++ if (temp & SMBHSTCFG_SMB_SMI_EN)
+ dev_dbg(&dev->dev, "I801 using Interrupt SMI# for SMBus.\n");
+ else
+ dev_dbg(&dev->dev, "I801 using PCI Interrupt for SMBus.\n");
+@@ -149,8 +146,7 @@ static int i801_setup(struct pci_dev *de
+ dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
+ dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba);
+
+-END:
+- return error_return;
++ return 0;
+ }
+
+ static int i801_transaction(void)
+@@ -516,12 +512,10 @@ MODULE_DEVICE_TABLE (pci, i801_ids);
+
+ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
+ {
++ int err;
+
+- if (i801_setup(dev)) {
+- dev_warn(&dev->dev,
+- "I801 not detected, module not inserted.\n");
+- return -ENODEV;
+- }
++ if ((err = i801_setup(dev)))
++ return err;
+
+ /* set up the driverfs linkage to our parent device */
+ i801_adapter.dev.parent = &dev->dev;
diff --git a/i2c/i2c-i801-05-better-pci-subsystem-integration.patch b/i2c/i2c-i801-05-better-pci-subsystem-integration.patch
new file mode 100644
index 0000000000000..efe1dbbad3f59
--- /dev/null
+++ b/i2c/i2c-i801-05-better-pci-subsystem-integration.patch
@@ -0,0 +1,116 @@
+From khali@linux-fr.org Mon Jun 12 12:53:08 2006
+Date: Mon, 12 Jun 2006 21:53:02 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Cc: LM Sensors <lm-sensors@lm-sensors.org>
+Subject: [PATCH 10/14] i2c-i801: Better pci subsystem integration
+Message-Id: <20060612215302.3540ed7b.khali@linux-fr.org>
+Content-Disposition: inline; filename=i2c-i801-05-better-pci-subsystem-integration.patch
+
+i2c-i801: Better pci subsystem integration
+
+Integrate the i2c-i801 driver better with the pci subsystem, by
+calling pci_{enable,disable}_device and requesting the I/O region
+by BAR rather than direct configuration space access.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/i2c/busses/i2c-i801.c | 38 +++++++++++++++++++++++++++-----------
+ 1 file changed, 27 insertions(+), 11 deletions(-)
+
+--- gregkh-2.6.orig/drivers/i2c/busses/i2c-i801.c
++++ gregkh-2.6/drivers/i2c/busses/i2c-i801.c
+@@ -66,7 +66,7 @@
+ #define SMBAUXCTL (13 + i801_smba) /* ICH4 only */
+
+ /* PCI Address Constants */
+-#define SMBBA 0x020
++#define SMBBAR 4
+ #define SMBHSTCFG 0x040
+ #define SMBREV 0x008
+
+@@ -97,7 +97,7 @@ static int i801_transaction(void);
+ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
+ int command, int hwpec);
+
+-static unsigned short i801_smba;
++static unsigned long i801_smba;
+ static struct pci_driver i801_driver;
+ static struct pci_dev *I801_dev;
+ static int isich4;
+@@ -105,6 +105,7 @@ static int isich4;
+ static int __devinit i801_setup(struct pci_dev *dev)
+ {
+ unsigned char temp;
++ int err;
+
+ I801_dev = dev;
+ if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) ||
+@@ -114,19 +115,28 @@ static int __devinit i801_setup(struct p
+ else
+ isich4 = 0;
+
++ err = pci_enable_device(dev);
++ if (err) {
++ dev_err(&dev->dev, "Failed to enable SMBus device (%d)\n",
++ err);
++ goto exit;
++ }
++
+ /* Determine the address of the SMBus area */
+- pci_read_config_word(I801_dev, SMBBA, &i801_smba);
+- i801_smba &= 0xfff0;
++ i801_smba = pci_resource_start(dev, SMBBAR);
+ if (!i801_smba) {
+ dev_err(&dev->dev, "SMBus base address uninitialized, "
+ "upgrade BIOS\n");
+- return -ENODEV;
++ err = -ENODEV;
++ goto exit_disable;
+ }
+
+- if (!request_region(i801_smba, (isich4 ? 16 : 8), i801_driver.name)) {
+- dev_err(&dev->dev, "I801_smb region 0x%x already in use!\n",
+- i801_smba);
+- return -EBUSY;
++ err = pci_request_region(dev, SMBBAR, i801_driver.name);
++ if (err) {
++ dev_err(&dev->dev, "Failed to request SMBus region "
++ "0x%lx-0x%lx\n", i801_smba,
++ pci_resource_end(dev, SMBBAR));
++ goto exit_disable;
+ }
+
+ pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
+@@ -147,6 +157,11 @@ static int __devinit i801_setup(struct p
+ dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba);
+
+ return 0;
++
++exit_disable:
++ pci_disable_device(dev);
++exit:
++ return err;
+ }
+
+ static int i801_transaction(void)
+@@ -521,14 +536,15 @@ static int __devinit i801_probe(struct p
+ i801_adapter.dev.parent = &dev->dev;
+
+ snprintf(i801_adapter.name, I2C_NAME_SIZE,
+- "SMBus I801 adapter at %04x", i801_smba);
++ "SMBus I801 adapter at %04lx", i801_smba);
+ return i2c_add_adapter(&i801_adapter);
+ }
+
+ static void __devexit i801_remove(struct pci_dev *dev)
+ {
+ i2c_del_adapter(&i801_adapter);
+- release_region(i801_smba, (isich4 ? 16 : 8));
++ pci_release_region(dev, SMBBAR);
++ pci_disable_device(dev);
+ }
+
+ static struct pci_driver i801_driver = {
diff --git a/i2c/i2c-i801-06-merge-setup-function.patch b/i2c/i2c-i801-06-merge-setup-function.patch
new file mode 100644
index 0000000000000..0b1fbea04f4b4
--- /dev/null
+++ b/i2c/i2c-i801-06-merge-setup-function.patch
@@ -0,0 +1,178 @@
+From khali@linux-fr.org Mon Jun 12 12:53:41 2006
+Date: Mon, 12 Jun 2006 21:53:41 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Cc: LM Sensors <lm-sensors@lm-sensors.org>
+Subject: [PATCH 11/14] i2c-i801: Merge setup function
+Message-Id: <20060612215341.cdc67d11.khali@linux-fr.org>
+Content-Disposition: inline; filename=i2c-i801-06-merge-setup-function.patch
+
+i2c-i801: Merge setup function
+
+Merge i801_setup into i801_probe, as it doesn't make much sense to
+have them split. This lets us handle errors better. Christopher
+Hellwig had been suggesting this back in March 2003 when the driver
+was merged.
+
+Also drop two useless debug messages (revision and base address can be
+obtained from lspci, procfs or sysfs.)
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/i2c/busses/i2c-i801.c | 121 +++++++++++++++++++-----------------------
+ 1 file changed, 55 insertions(+), 66 deletions(-)
+
+--- gregkh-2.6.orig/drivers/i2c/busses/i2c-i801.c
++++ gregkh-2.6/drivers/i2c/busses/i2c-i801.c
+@@ -68,7 +68,6 @@
+ /* PCI Address Constants */
+ #define SMBBAR 4
+ #define SMBHSTCFG 0x040
+-#define SMBREV 0x008
+
+ /* Host configuration bits for SMBHSTCFG */
+ #define SMBHSTCFG_HST_EN 1
+@@ -102,68 +101,6 @@ static struct pci_driver i801_driver;
+ static struct pci_dev *I801_dev;
+ static int isich4;
+
+-static int __devinit i801_setup(struct pci_dev *dev)
+-{
+- unsigned char temp;
+- int err;
+-
+- I801_dev = dev;
+- if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) ||
+- (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) ||
+- (dev->device == PCI_DEVICE_ID_INTEL_ESB_4))
+- isich4 = 1;
+- else
+- isich4 = 0;
+-
+- err = pci_enable_device(dev);
+- if (err) {
+- dev_err(&dev->dev, "Failed to enable SMBus device (%d)\n",
+- err);
+- goto exit;
+- }
+-
+- /* Determine the address of the SMBus area */
+- i801_smba = pci_resource_start(dev, SMBBAR);
+- if (!i801_smba) {
+- dev_err(&dev->dev, "SMBus base address uninitialized, "
+- "upgrade BIOS\n");
+- err = -ENODEV;
+- goto exit_disable;
+- }
+-
+- err = pci_request_region(dev, SMBBAR, i801_driver.name);
+- if (err) {
+- dev_err(&dev->dev, "Failed to request SMBus region "
+- "0x%lx-0x%lx\n", i801_smba,
+- pci_resource_end(dev, SMBBAR));
+- goto exit_disable;
+- }
+-
+- pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
+- temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
+- if (!(temp & SMBHSTCFG_HST_EN)) {
+- dev_warn(&dev->dev, "enabling SMBus device\n");
+- temp |= SMBHSTCFG_HST_EN;
+- }
+- pci_write_config_byte(I801_dev, SMBHSTCFG, temp);
+-
+- if (temp & SMBHSTCFG_SMB_SMI_EN)
+- dev_dbg(&dev->dev, "I801 using Interrupt SMI# for SMBus.\n");
+- else
+- dev_dbg(&dev->dev, "I801 using PCI Interrupt for SMBus.\n");
+-
+- pci_read_config_byte(I801_dev, SMBREV, &temp);
+- dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
+- dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba);
+-
+- return 0;
+-
+-exit_disable:
+- pci_disable_device(dev);
+-exit:
+- return err;
+-}
+-
+ static int i801_transaction(void)
+ {
+ int temp;
+@@ -527,17 +464,69 @@ MODULE_DEVICE_TABLE (pci, i801_ids);
+
+ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
+ {
++ unsigned char temp;
+ int err;
+
+- if ((err = i801_setup(dev)))
+- return err;
++ I801_dev = dev;
++ if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) ||
++ (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) ||
++ (dev->device == PCI_DEVICE_ID_INTEL_ESB_4))
++ isich4 = 1;
++ else
++ isich4 = 0;
++
++ err = pci_enable_device(dev);
++ if (err) {
++ dev_err(&dev->dev, "Failed to enable SMBus PCI device (%d)\n",
++ err);
++ goto exit;
++ }
++
++ /* Determine the address of the SMBus area */
++ i801_smba = pci_resource_start(dev, SMBBAR);
++ if (!i801_smba) {
++ dev_err(&dev->dev, "SMBus base address uninitialized, "
++ "upgrade BIOS\n");
++ err = -ENODEV;
++ goto exit_disable;
++ }
++
++ err = pci_request_region(dev, SMBBAR, i801_driver.name);
++ if (err) {
++ dev_err(&dev->dev, "Failed to request SMBus region "
++ "0x%lx-0x%lx\n", i801_smba,
++ pci_resource_end(dev, SMBBAR));
++ goto exit_disable;
++ }
++
++ pci_read_config_byte(I801_dev, SMBHSTCFG, &temp);
++ temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */
++ if (!(temp & SMBHSTCFG_HST_EN)) {
++ dev_info(&dev->dev, "Enabling SMBus device\n");
++ temp |= SMBHSTCFG_HST_EN;
++ }
++ pci_write_config_byte(I801_dev, SMBHSTCFG, temp);
++
++ if (temp & SMBHSTCFG_SMB_SMI_EN)
++ dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n");
++ else
++ dev_dbg(&dev->dev, "SMBus using PCI Interrupt\n");
+
+ /* set up the driverfs linkage to our parent device */
+ i801_adapter.dev.parent = &dev->dev;
+
+ snprintf(i801_adapter.name, I2C_NAME_SIZE,
+ "SMBus I801 adapter at %04lx", i801_smba);
+- return i2c_add_adapter(&i801_adapter);
++ err = i2c_add_adapter(&i801_adapter);
++ if (err) {
++ dev_err(&dev->dev, "Failed to add SMBus adapter\n");
++ goto exit_disable;
++ }
++
++exit_disable:
++ pci_disable_device(dev);
++exit:
++ return err;
+ }
+
+ static void __devexit i801_remove(struct pci_dev *dev)
diff --git a/i2c/i2c-mark-data-const-for-write-block.patch b/i2c/i2c-mark-data-const-for-write-block.patch
new file mode 100644
index 0000000000000..7f5c429d7fc18
--- /dev/null
+++ b/i2c/i2c-mark-data-const-for-write-block.patch
@@ -0,0 +1,61 @@
+From khali@linux-fr.org Mon Jun 12 12:42:21 2006
+Date: Mon, 12 Jun 2006 21:42:20 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Cc: LM Sensors <lm-sensors@lm-sensors.org>, Krzysztof Halasa <khc@pm.waw.pl>
+Subject: [PATCH 02/14] i2c: Mark block write buffers as const
+Message-Id: <20060612214220.46bb23be.khali@linux-fr.org>
+Content-Disposition: inline; filename=i2c-mark-data-const-for-write-block.patch
+
+From: Krzysztof Halasa <khc@pm.waw.pl>
+
+The attached patch marks i2c_smbus_write_block_data() and
+i2c_smbus_write_i2c_block_data() buffers as const.
+
+Signed-off-by: Krzysztof Halasa <khc@pm.waw.pl>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/i2c/i2c-core.c | 4 ++--
+ include/linux/i2c.h | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- gregkh-2.6.orig/drivers/i2c/i2c-core.c
++++ gregkh-2.6/drivers/i2c/i2c-core.c
+@@ -916,7 +916,7 @@ s32 i2c_smbus_write_word_data(struct i2c
+ }
+
+ s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command,
+- u8 length, u8 *values)
++ u8 length, const u8 *values)
+ {
+ union i2c_smbus_data data;
+
+@@ -944,7 +944,7 @@ s32 i2c_smbus_read_i2c_block_data(struct
+ }
+
+ s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command,
+- u8 length, u8 *values)
++ u8 length, const u8 *values)
+ {
+ union i2c_smbus_data data;
+
+--- gregkh-2.6.orig/include/linux/i2c.h
++++ gregkh-2.6/include/linux/i2c.h
+@@ -96,13 +96,13 @@ extern s32 i2c_smbus_write_word_data(str
+ u8 command, u16 value);
+ extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
+ u8 command, u8 length,
+- u8 *values);
++ const u8 *values);
+ /* Returns the number of read bytes */
+ extern s32 i2c_smbus_read_i2c_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);
++ const u8 *values);
+
+ /*
+ * A driver is capable of handling one or more physical devices present on
diff --git a/i2c/i2c-opencores-cleanup.patch b/i2c/i2c-opencores-cleanup.patch
new file mode 100644
index 0000000000000..1ede51b4a2f32
--- /dev/null
+++ b/i2c/i2c-opencores-cleanup.patch
@@ -0,0 +1,61 @@
+From khali@linux-fr.org Mon Jun 12 12:41:03 2006
+Date: Mon, 12 Jun 2006 21:40:53 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Cc: LM Sensors <lm-sensors@lm-sensors.org>, Peter Korsgaard <jacmet@sunsite.dk>
+Subject: [PATCH 01/14] i2c-ocores: Minor cleanups
+Message-Id: <20060612214053.4c7ebc0c.khali@linux-fr.org>
+Content-Disposition: inline; filename=i2c-opencores-cleanup.patch
+
+From: Peter Korsgaard <jacmet@sunsite.dk>
+
+Minor cleanup to the i2c-ocores driver.
+
+Peter Korsgaard will maintain the i2c-ocores driver.
+
+Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ MAINTAINERS | 6 ++++++
+ drivers/i2c/busses/i2c-ocores.c | 6 ++----
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+--- gregkh-2.6.orig/MAINTAINERS
++++ gregkh-2.6/MAINTAINERS
+@@ -2051,6 +2051,12 @@ M: adaplas@pol.net
+ L: linux-fbdev-devel@lists.sourceforge.net
+ S: Maintained
+
++OPENCORES I2C BUS DRIVER
++P: Peter Korsgaard
++M: jacmet@sunsite.dk
++L: lm-sensors@lm-sensors.org
++S: Maintained
++
+ ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
+ P: Mark Fasheh
+ M: mark.fasheh@oracle.com
+--- gregkh-2.6.orig/drivers/i2c/busses/i2c-ocores.c
++++ gregkh-2.6/drivers/i2c/busses/i2c-ocores.c
+@@ -38,8 +38,8 @@ struct ocores_i2c {
+ #define OCI2C_PREHIGH 1
+ #define OCI2C_CONTROL 2
+ #define OCI2C_DATA 3
+-#define OCI2C_CMD 4
+-#define OCI2C_STATUS 4
++#define OCI2C_CMD 4 /* write only */
++#define OCI2C_STATUS 4 /* read only, same address as OCI2C_CMD */
+
+ #define OCI2C_CTRL_IEN 0x40
+ #define OCI2C_CTRL_EN 0x80
+@@ -209,8 +209,6 @@ static struct i2c_adapter ocores_adapter
+ .name = "i2c-ocores",
+ .class = I2C_CLASS_HWMON,
+ .algo = &ocores_algorithm,
+- .timeout = 2,
+- .retries = 1,
+ };
+
+
diff --git a/i2c/i2c-scx200_acb-documentation-update.patch b/i2c/i2c-scx200_acb-documentation-update.patch
new file mode 100644
index 0000000000000..5cf2c211c12ce
--- /dev/null
+++ b/i2c/i2c-scx200_acb-documentation-update.patch
@@ -0,0 +1,66 @@
+From khali@linux-fr.org Mon Jun 12 12:48:10 2006
+Date: Mon, 12 Jun 2006 21:48:08 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Cc: LM Sensors <lm-sensors@lm-sensors.org>, Jordan Crouse <jordan.crouse@amd.com>
+Subject: [PATCH 05/14] scx200_acb: Documentation update
+Message-Id: <20060612214808.35510747.khali@linux-fr.org>
+Content-Disposition: inline; filename=i2c-scx200_acb-documentation-update.patch
+
+Documentation update for the scx200_acb driver. Hopefully this will
+help future users.
+
+References:
+
+[lm-sensors] Support of i2c-nscacb (April, May 2005)
+ http://lists.lm-sensors.org/pipermail/lm-sensors/2005-April/011756.html
+ http://lists.lm-sensors.org/pipermail/lm-sensors/2005-May/012043.html
+
+[lm-sensors] making a geode i2c slave driver (April 2006)
+ http://lists.lm-sensors.org/pipermail/lm-sensors/2006-April/015998.html
+
+Kernel bug #6445
+ http://bugzilla.kernel.org/show_bug.cgi?id=6445
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/i2c/busses/scx200_acb | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+--- gregkh-2.6.orig/Documentation/i2c/busses/scx200_acb
++++ gregkh-2.6/Documentation/i2c/busses/scx200_acb
+@@ -2,14 +2,31 @@ Kernel driver scx200_acb
+
+ Author: Christer Weinigel <wingel@nano-system.com>
+
++The driver supersedes the older, never merged driver named i2c-nscacb.
++
+ Module Parameters
+ -----------------
+
+-* base: int
++* base: up to 4 ints
+ Base addresses for the ACCESS.bus controllers on SCx200 and SC1100 devices
+
++ By default the driver uses two base addresses 0x820 and 0x840.
++ If you want only one base address, specify the second as 0 so as to
++ override this default.
++
+ Description
+ -----------
+
+ Enable the use of the ACCESS.bus controller on the Geode SCx200 and
+ SC1100 processors and the CS5535 and CS5536 Geode companion devices.
++
++Device-specific notes
++---------------------
++
++The SC1100 WRAP boards are known to use base addresses 0x810 and 0x820.
++If the scx200_acb driver is built into the kernel, add the following
++parameter to your boot command line:
++ scx200_acb.base=0x810,0x820
++If the scx200_acb driver is built as a module, add the following line to
++the file /etc/modprobe.conf instead:
++ options scx200_acb base=0x810,0x820
diff --git a/i2c/i2c-scx200_acb-mark-scx200_acb_probe-init.patch b/i2c/i2c-scx200_acb-mark-scx200_acb_probe-init.patch
new file mode 100644
index 0000000000000..d7431ca3f2e52
--- /dev/null
+++ b/i2c/i2c-scx200_acb-mark-scx200_acb_probe-init.patch
@@ -0,0 +1,30 @@
+From khali@linux-fr.org Mon Jun 12 12:46:10 2006
+Date: Mon, 12 Jun 2006 21:46:04 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Cc: LM Sensors <lm-sensors@lm-sensors.org>, Jordan Crouse <jordan.crouse@amd.com>
+Subject: [PATCH 04/14] scx200_acb: Mark scx200_acb_probe __init
+Message-Id: <20060612214604.3050e740.khali@linux-fr.org>
+Content-Disposition: inline; filename=i2c-scx200_acb-mark-scx200_acb_probe-init.patch
+
+In i2c bus driver scx200_acb, function scx200_acb_probe can be
+tagged __init.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/i2c/busses/scx200_acb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- gregkh-2.6.orig/drivers/i2c/busses/scx200_acb.c
++++ gregkh-2.6/drivers/i2c/busses/scx200_acb.c
+@@ -384,7 +384,7 @@ static struct i2c_algorithm scx200_acb_a
+ static struct scx200_acb_iface *scx200_acb_list;
+ static DECLARE_MUTEX(scx200_acb_list_mutex);
+
+-static int scx200_acb_probe(struct scx200_acb_iface *iface)
++static __init int scx200_acb_probe(struct scx200_acb_iface *iface)
+ {
+ u8 val;
+
diff --git a/i2c/i2c-scx200_acb-use-PCI-IO-resource-when-appropriate.patch b/i2c/i2c-scx200_acb-use-PCI-IO-resource-when-appropriate.patch
new file mode 100644
index 0000000000000..09e3bff6fa11a
--- /dev/null
+++ b/i2c/i2c-scx200_acb-use-PCI-IO-resource-when-appropriate.patch
@@ -0,0 +1,304 @@
+From khali@linux-fr.org Mon Jun 12 12:44:31 2006
+Date: Mon, 12 Jun 2006 21:44:28 +0200
+From: Jordan Crouse <jordan.crouse@amd.com>
+To: Greg KH <greg@kroah.com>
+Cc: LM Sensors <lm-sensors@lm-sensors.org>, Jordan Crouse <jordan.crouse@amd.com>
+Subject: [PATCH 03/14] scx200_acb: Use PCI I/O resource when appropriate
+Message-Id: <20060612214428.f1a2c46b.khali@linux-fr.org>
+Content-Disposition: inline; filename=i2c-scx200_acb-use-PCI-IO-resource-when-appropriate.patch
+
+From: Jordan Crouse <jordan.crouse@amd.com>
+
+On the CS5535 and CS5536, the I/O resource is allocated through PCI,
+so use that instead of using the MSR backdoor.
+
+Signed-off-by: Jordan Crouse <jordan.crouse@amd.com>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/i2c/busses/scx200_acb.c | 200 +++++++++++++++++++++++++++++-----------
+ 1 file changed, 147 insertions(+), 53 deletions(-)
+
+--- gregkh-2.6.orig/drivers/i2c/busses/scx200_acb.c
++++ gregkh-2.6/drivers/i2c/busses/scx200_acb.c
+@@ -33,7 +33,6 @@
+ #include <linux/delay.h>
+ #include <linux/mutex.h>
+ #include <asm/io.h>
+-#include <asm/msr.h>
+
+ #include <linux/scx200.h>
+
+@@ -85,6 +84,10 @@ struct scx200_acb_iface {
+ u8 *ptr;
+ char needs_reset;
+ unsigned len;
++
++ /* PCI device info */
++ struct pci_dev *pdev;
++ int bar;
+ };
+
+ /* Register Definitions */
+@@ -417,17 +420,16 @@ static int scx200_acb_probe(struct scx20
+ return 0;
+ }
+
+-static int __init scx200_acb_create(const char *text, int base, int index)
++static __init struct scx200_acb_iface *scx200_create_iface(const char *text,
++ int index)
+ {
+ struct scx200_acb_iface *iface;
+ struct i2c_adapter *adapter;
+- int rc;
+
+ iface = kzalloc(sizeof(*iface), GFP_KERNEL);
+ if (!iface) {
+ printk(KERN_ERR NAME ": can't allocate memory\n");
+- rc = -ENOMEM;
+- goto errout;
++ return NULL;
+ }
+
+ adapter = &iface->adapter;
+@@ -440,26 +442,27 @@ static int __init scx200_acb_create(con
+
+ mutex_init(&iface->mutex);
+
+- if (!request_region(base, 8, adapter->name)) {
+- printk(KERN_ERR NAME ": can't allocate io 0x%x-0x%x\n",
+- base, base + 8-1);
+- rc = -EBUSY;
+- goto errout_free;
+- }
+- iface->base = base;
++ return iface;
++}
++
++static int __init scx200_acb_create(struct scx200_acb_iface *iface)
++{
++ struct i2c_adapter *adapter;
++ int rc;
++
++ adapter = &iface->adapter;
+
+ rc = scx200_acb_probe(iface);
+ if (rc) {
+ printk(KERN_WARNING NAME ": probe failed\n");
+- goto errout_release;
++ return rc;
+ }
+
+ scx200_acb_reset(iface);
+
+ if (i2c_add_adapter(adapter) < 0) {
+ printk(KERN_ERR NAME ": failed to register\n");
+- rc = -ENODEV;
+- goto errout_release;
++ return -ENODEV;
+ }
+
+ down(&scx200_acb_list_mutex);
+@@ -468,64 +471,148 @@ static int __init scx200_acb_create(con
+ up(&scx200_acb_list_mutex);
+
+ return 0;
++}
+
+- errout_release:
+- release_region(iface->base, 8);
++static __init int scx200_create_pci(const char *text, struct pci_dev *pdev,
++ int bar)
++{
++ struct scx200_acb_iface *iface;
++ int rc;
++
++ iface = scx200_create_iface(text, 0);
++
++ if (iface == NULL)
++ return -ENOMEM;
++
++ iface->pdev = pdev;
++ iface->bar = bar;
++
++ pci_enable_device_bars(iface->pdev, 1 << iface->bar);
++
++ rc = pci_request_region(iface->pdev, iface->bar, iface->adapter.name);
++
++ if (rc != 0) {
++ printk(KERN_ERR NAME ": can't allocate PCI BAR %d\n",
++ iface->bar);
++ goto errout_free;
++ }
++
++ iface->base = pci_resource_start(iface->pdev, iface->bar);
++ rc = scx200_acb_create(iface);
++
++ if (rc == 0)
++ return 0;
++
++ pci_release_region(iface->pdev, iface->bar);
++ pci_dev_put(iface->pdev);
+ errout_free:
+ kfree(iface);
+- errout:
+ return rc;
+ }
+
+-static struct pci_device_id scx200[] = {
+- { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
+- { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
+- { },
+-};
++static int __init scx200_create_isa(const char *text, unsigned long base,
++ int index)
++{
++ struct scx200_acb_iface *iface;
++ int rc;
++
++ iface = scx200_create_iface(text, index);
++
++ if (iface == NULL)
++ return -ENOMEM;
++
++ if (request_region(base, 8, iface->adapter.name) == 0) {
++ printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n",
++ base, base + 8 - 1);
++ rc = -EBUSY;
++ goto errout_free;
++ }
++
++ iface->base = base;
++ rc = scx200_acb_create(iface);
++
++ if (rc == 0)
++ return 0;
+
+-static struct pci_device_id divil_pci[] = {
+- { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) },
+- { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
+- { } /* NULL entry */
++ release_region(base, 8);
++ errout_free:
++ kfree(iface);
++ return rc;
++}
++
++/* Driver data is an index into the scx200_data array that indicates
++ * the name and the BAR where the I/O address resource is located. ISA
++ * devices are flagged with a bar value of -1 */
++
++static struct pci_device_id scx200_pci[] = {
++ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE),
++ .driver_data = 0 },
++ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE),
++ .driver_data = 0 },
++ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA),
++ .driver_data = 1 },
++ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA),
++ .driver_data = 2 }
+ };
+
+-#define MSR_LBAR_SMB 0x5140000B
++static struct {
++ const char *name;
++ int bar;
++} scx200_data[] = {
++ { "SCx200", -1 },
++ { "CS5535", 0 },
++ { "CS5536", 0 }
++};
+
+-static __init int scx200_add_cs553x(void)
++static __init int scx200_scan_pci(void)
+ {
+- u32 low, hi;
+- u32 smb_base;
+-
+- /* Grab & reserve the SMB I/O range */
+- rdmsr(MSR_LBAR_SMB, low, hi);
++ int data, dev;
++ int rc = -ENODEV;
++ struct pci_dev *pdev;
++
++ for(dev = 0; dev < ARRAY_SIZE(scx200_pci); dev++) {
++ pdev = pci_get_device(scx200_pci[dev].vendor,
++ scx200_pci[dev].device, NULL);
++
++ if (pdev == NULL)
++ continue;
++
++ data = scx200_pci[dev].driver_data;
++
++ /* if .bar is greater or equal to zero, this is a
++ * PCI device - otherwise, we assume
++ that the ports are ISA based
++ */
++
++ if (scx200_data[data].bar >= 0)
++ rc = scx200_create_pci(scx200_data[data].name, pdev,
++ scx200_data[data].bar);
++ else {
++ int i;
++
++ for (i = 0; i < MAX_DEVICES; ++i) {
++ if (base[i] == 0)
++ continue;
++
++ rc = scx200_create_isa(scx200_data[data].name,
++ base[i],
++ i);
++ }
++ }
+
+- /* Check the IO mask and whether SMB is enabled */
+- if (hi != 0x0000F001) {
+- printk(KERN_WARNING NAME ": SMBus not enabled\n");
+- return -ENODEV;
++ break;
+ }
+
+- /* SMBus IO size is 8 bytes */
+- smb_base = low & 0x0000FFF8;
+-
+- return scx200_acb_create("CS5535", smb_base, 0);
++ return rc;
+ }
+
+ static int __init scx200_acb_init(void)
+ {
+- int i;
+- int rc = -ENODEV;
++ int rc;
+
+ pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
+
+- /* Verify that this really is a SCx200 processor */
+- if (pci_dev_present(scx200)) {
+- for (i = 0; i < MAX_DEVICES; ++i) {
+- if (base[i] > 0)
+- rc = scx200_acb_create("SCx200", base[i], i);
+- }
+- } else if (pci_dev_present(divil_pci))
+- rc = scx200_add_cs553x();
++ rc = scx200_scan_pci();
+
+ /* If at least one bus was created, init must succeed */
+ if (scx200_acb_list)
+@@ -543,7 +630,14 @@ static void __exit scx200_acb_cleanup(vo
+ up(&scx200_acb_list_mutex);
+
+ i2c_del_adapter(&iface->adapter);
+- release_region(iface->base, 8);
++
++ if (iface->pdev) {
++ pci_release_region(iface->pdev, iface->bar);
++ pci_dev_put(iface->pdev);
++ }
++ else
++ release_region(iface->base, 8);
++
+ kfree(iface);
+ down(&scx200_acb_list_mutex);
+ }