Browse Source

Merge branch 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6

* 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6:
  i2c: Fix platform driver hotplug/coldplug
  i2c: New driver for the SuperH Mobile I2C bus controller
  i2c/scx200_acb: Don't use 0 as NULL pointer
  i2c-bfin-twi: Fix mismatch in add timer and delete timer
  i2c-bfin-twi: Just let i2c-bfin-twi driver depends on BLACKFIN
  i2c-bfin-twi: Use simpler comment headers and strip out information that is maintained in the scm's log
  i2c-bfin-twi: Cleanup driver descriptions, versions and some module useful information
  i2c-bfin-twi: Add missing pin mux operation
  i2c-bfin-twi: Add platform_resource interface to support multi-port TWI controllers
  i2c-bfin-twi: Add repeat start feature to avoid break of a bundle of i2c master xfer operation
  i2c: Remove trailing whitespaces in busses/Kconfig
  i2c: Replace remaining __FUNCTION__ occurrences
  i2c: Renesas SH7760 I2C master driver
  i2c-dev: Split i2cdev_ioctl
  i2c-ibm_iic: Support building as an of_platform driver
  i2c-ibm_iic: Change the log levels
  i2c: Add platform driver on top of the new pca-algorithm
  i2c-algo-pca: Extend for future drivers
  i2c-algo-pca: Remove trailing whitespaces and unnecessary UTF
  i2c: Remove the algorithm drivers from the config menu
Linus Torvalds 17 years ago
parent
commit
b24a31442e

+ 5 - 34
drivers/i2c/algos/Kconfig

@@ -1,45 +1,16 @@
 #
-# Character device configuration
+# I2C algorithm drivers configuration
 #
 
-menu "I2C Algorithms"
-
 config I2C_ALGOBIT
-	tristate "I2C bit-banging interfaces"
-	help
-	  This allows you to use a range of I2C adapters called bit-banging
-	  adapters.  Say Y if you own an I2C adapter belonging to this class
-	  and then say Y to the specific driver for you adapter below.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-algo-bit.
+	tristate
 
 config I2C_ALGOPCF
-	tristate "I2C PCF 8584 interfaces"
-	help
-	  This allows you to use a range of I2C adapters called PCF adapters.
-	  Say Y if you own an I2C adapter belonging to this class and then say
-	  Y to the specific driver for you adapter below.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-algo-pcf.
+	tristate
 
 config I2C_ALGOPCA
-	tristate "I2C PCA 9564 interfaces"
-	help
-	  This allows you to use a range of I2C adapters called PCA adapters.
-	  Say Y if you own an I2C adapter belonging to this class and then say
-	  Y to the specific driver for you adapter below.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-algo-pca.
+	tristate
 
 config I2C_ALGO_SGI
-	tristate "I2C SGI interfaces"
+	tristate
 	depends on SGI_IP22 || SGI_IP32 || X86_VISWS
-	help
-	  Supports the SGI interfaces like the ones found on SGI Indy VINO
-	  or SGI O2 MACE.
-
-endmenu
-

+ 63 - 63
drivers/i2c/algos/i2c-algo-pca.c

@@ -1,6 +1,7 @@
 /*
- *  i2c-algo-pca.c i2c driver algorithms for PCA9564 adapters                
+ *  i2c-algo-pca.c i2c driver algorithms for PCA9564 adapters
  *    Copyright (C) 2004 Arcom Control Systems
+ *    Copyright (C) 2008 Pengutronix
  *
  *  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
@@ -21,14 +22,10 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-pca.h>
-#include "i2c-algo-pca.h"
-
-#define DRIVER "i2c-algo-pca"
 
 #define DEB1(fmt, args...) do { if (i2c_debug>=1) printk(fmt, ## args); } while(0)
 #define DEB2(fmt, args...) do { if (i2c_debug>=2) printk(fmt, ## args); } while(0)
@@ -36,15 +33,15 @@
 
 static int i2c_debug;
 
-#define pca_outw(adap, reg, val) adap->write_byte(adap, reg, val)
-#define pca_inw(adap, reg) adap->read_byte(adap, reg)
+#define pca_outw(adap, reg, val) adap->write_byte(adap->data, reg, val)
+#define pca_inw(adap, reg) adap->read_byte(adap->data, reg)
 
 #define pca_status(adap) pca_inw(adap, I2C_PCA_STA)
-#define pca_clock(adap) adap->get_clock(adap)
-#define pca_own(adap) adap->get_own(adap)
+#define pca_clock(adap) adap->i2c_clock
 #define pca_set_con(adap, val) pca_outw(adap, I2C_PCA_CON, val)
 #define pca_get_con(adap) pca_inw(adap, I2C_PCA_CON)
-#define pca_wait(adap) adap->wait_for_interrupt(adap)
+#define pca_wait(adap) adap->wait_for_completion(adap->data)
+#define pca_reset(adap) adap->reset_chip(adap->data)
 
 /*
  * Generate a start condition on the i2c bus.
@@ -99,7 +96,7 @@ static void pca_stop(struct i2c_algo_pca_data *adap)
  *
  * returns after the address has been sent
  */
-static void pca_address(struct i2c_algo_pca_data *adap, 
+static void pca_address(struct i2c_algo_pca_data *adap,
 			struct i2c_msg *msg)
 {
 	int sta = pca_get_con(adap);
@@ -108,9 +105,9 @@ static void pca_address(struct i2c_algo_pca_data *adap,
 	addr = ( (0x7f & msg->addr) << 1 );
 	if (msg->flags & I2C_M_RD )
 		addr |= 1;
-	DEB2("=== SLAVE ADDRESS %#04x+%c=%#04x\n", 
+	DEB2("=== SLAVE ADDRESS %#04x+%c=%#04x\n",
 	     msg->addr, msg->flags & I2C_M_RD ? 'R' : 'W', addr);
-	
+
 	pca_outw(adap, I2C_PCA_DAT, addr);
 
 	sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
@@ -124,7 +121,7 @@ static void pca_address(struct i2c_algo_pca_data *adap,
  *
  * Returns after the byte has been transmitted
  */
-static void pca_tx_byte(struct i2c_algo_pca_data *adap, 
+static void pca_tx_byte(struct i2c_algo_pca_data *adap,
 			__u8 b)
 {
 	int sta = pca_get_con(adap);
@@ -142,19 +139,19 @@ static void pca_tx_byte(struct i2c_algo_pca_data *adap,
  *
  * returns immediately.
  */
-static void pca_rx_byte(struct i2c_algo_pca_data *adap, 
+static void pca_rx_byte(struct i2c_algo_pca_data *adap,
 			__u8 *b, int ack)
 {
 	*b = pca_inw(adap, I2C_PCA_DAT);
 	DEB2("=== READ %#04x %s\n", *b, ack ? "ACK" : "NACK");
 }
 
-/* 
+/*
  * Setup ACK or NACK for next received byte and wait for it to arrive.
  *
  * Returns after next byte has arrived.
  */
-static void pca_rx_ack(struct i2c_algo_pca_data *adap, 
+static void pca_rx_ack(struct i2c_algo_pca_data *adap,
 		       int ack)
 {
 	int sta = pca_get_con(adap);
@@ -168,15 +165,6 @@ static void pca_rx_ack(struct i2c_algo_pca_data *adap,
 	pca_wait(adap);
 }
 
-/* 
- * Reset the i2c bus / SIO 
- */
-static void pca_reset(struct i2c_algo_pca_data *adap)
-{
-	/* apparently only an external reset will do it. not a lot can be done */
-	printk(KERN_ERR DRIVER ": Haven't figured out how to do a reset yet\n");
-}
-
 static int pca_xfer(struct i2c_adapter *i2c_adap,
                     struct i2c_msg *msgs,
                     int num)
@@ -187,7 +175,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
 	int numbytes = 0;
 	int state;
 	int ret;
-	int timeout = 100;
+	int timeout = i2c_adap->timeout;
 
 	while ((state = pca_status(adap)) != 0xf8 && timeout--) {
 		msleep(10);
@@ -203,14 +191,14 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
 		for (curmsg = 0; curmsg < num; curmsg++) {
 			int addr, i;
 			msg = &msgs[curmsg];
-			
+
 			addr = (0x7f & msg->addr) ;
-		
+
 			if (msg->flags & I2C_M_RD )
-				printk(KERN_INFO "    [%02d] RD %d bytes from %#02x [%#02x, ...]\n", 
+				printk(KERN_INFO "    [%02d] RD %d bytes from %#02x [%#02x, ...]\n",
 				       curmsg, msg->len, addr, (addr<<1) | 1);
 			else {
-				printk(KERN_INFO "    [%02d] WR %d bytes to %#02x [%#02x%s", 
+				printk(KERN_INFO "    [%02d] WR %d bytes to %#02x [%#02x%s",
 				       curmsg, msg->len, addr, addr<<1,
 				       msg->len == 0 ? "" : ", ");
 				for(i=0; i < msg->len; i++)
@@ -237,7 +225,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
 		case 0x10: /* A repeated start condition has been transmitted */
 			pca_address(adap, msg);
 			break;
-			
+
 		case 0x18: /* SLA+W has been transmitted; ACK has been received */
 		case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */
 			if (numbytes < msg->len) {
@@ -287,7 +275,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
 		case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */
 			DEB2("Arbitration lost\n");
 			goto out;
-			
+
 		case 0x58: /* Data byte has been received; NOT ACK has been returned */
 			if ( numbytes == msg->len - 1 ) {
 				pca_rx_byte(adap, &msg->buf[numbytes], 0);
@@ -317,16 +305,16 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
 			pca_reset(adap);
 			goto out;
 		default:
-			printk(KERN_ERR DRIVER ": unhandled SIO state 0x%02x\n", state);
+			dev_err(&i2c_adap->dev, "unhandled SIO state 0x%02x\n", state);
 			break;
 		}
-		
+
 	}
 
 	ret = curmsg;
  out:
 	DEB1(KERN_CRIT "}}} transfered %d/%d messages. "
-	     "status is %#04x. control is %#04x\n", 
+	     "status is %#04x. control is %#04x\n",
 	     curmsg, num, pca_status(adap),
 	     pca_get_con(adap));
 	return ret;
@@ -337,53 +325,65 @@ static u32 pca_func(struct i2c_adapter *adap)
         return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 }
 
-static int pca_init(struct i2c_algo_pca_data *adap)
+static const struct i2c_algorithm pca_algo = {
+	.master_xfer	= pca_xfer,
+	.functionality	= pca_func,
+};
+
+static int pca_init(struct i2c_adapter *adap)
 {
 	static int freqs[] = {330,288,217,146,88,59,44,36};
-	int own, clock;
+	int clock;
+	struct i2c_algo_pca_data *pca_data = adap->algo_data;
+
+	if (pca_data->i2c_clock > 7) {
+		printk(KERN_WARNING "%s: Invalid I2C clock speed selected. Trying default.\n",
+			adap->name);
+		pca_data->i2c_clock = I2C_PCA_CON_59kHz;
+	}
+
+	adap->algo = &pca_algo;
 
-	own = pca_own(adap);
-	clock = pca_clock(adap);
-	DEB1(KERN_INFO DRIVER ": own address is %#04x\n", own);
-	DEB1(KERN_INFO DRIVER ": clock freqeuncy is %dkHz\n", freqs[clock]);
+	pca_reset(pca_data);
 
-	pca_outw(adap, I2C_PCA_ADR, own << 1);
+	clock = pca_clock(pca_data);
+	DEB1(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, freqs[clock]);
 
-	pca_set_con(adap, I2C_PCA_CON_ENSIO | clock);
-	udelay(500); /* 500 µs for oscilator to stabilise */
+	pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock);
+	udelay(500); /* 500 us for oscilator to stabilise */
 
 	return 0;
 }
 
-static const struct i2c_algorithm pca_algo = {
-	.master_xfer	= pca_xfer,
-	.functionality	= pca_func,
-};
-
-/* 
- * registering functions to load algorithms at runtime 
+/*
+ * registering functions to load algorithms at runtime
  */
 int i2c_pca_add_bus(struct i2c_adapter *adap)
 {
-	struct i2c_algo_pca_data *pca_adap = adap->algo_data;
 	int rval;
 
-	/* register new adapter to i2c module... */
-	adap->algo = &pca_algo;
+	rval = pca_init(adap);
+	if (rval)
+		return rval;
 
-	adap->timeout = 100;		/* default values, should	*/
-	adap->retries = 3;		/* be replaced by defines	*/
+	return i2c_add_adapter(adap);
+}
+EXPORT_SYMBOL(i2c_pca_add_bus);
 
-	if ((rval = pca_init(pca_adap)))
-		return rval;
+int i2c_pca_add_numbered_bus(struct i2c_adapter *adap)
+{
+	int rval;
 
-	rval = i2c_add_adapter(adap);
+	rval = pca_init(adap);
+	if (rval)
+		return rval;
 
-	return rval;
+	return i2c_add_numbered_adapter(adap);
 }
-EXPORT_SYMBOL(i2c_pca_add_bus);
+EXPORT_SYMBOL(i2c_pca_add_numbered_bus);
 
-MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>");
+MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, "
+	"Wolfram Sang <w.sang@pengutronix.de>");
 MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm");
 MODULE_LICENSE("GPL");
 

+ 0 - 26
drivers/i2c/algos/i2c-algo-pca.h

@@ -1,26 +0,0 @@
-#ifndef I2C_PCA9564_H
-#define I2C_PCA9564_H 1
-
-#define I2C_PCA_STA		0x00 /* STATUS  Read Only  */
-#define I2C_PCA_TO		0x00 /* TIMEOUT Write Only */
-#define I2C_PCA_DAT		0x01 /* DATA    Read/Write */
-#define I2C_PCA_ADR		0x02 /* OWN ADR Read/Write */
-#define I2C_PCA_CON		0x03 /* CONTROL Read/Write */
-
-#define I2C_PCA_CON_AA		0x80 /* Assert Acknowledge */
-#define I2C_PCA_CON_ENSIO	0x40 /* Enable */
-#define I2C_PCA_CON_STA		0x20 /* Start */
-#define I2C_PCA_CON_STO		0x10 /* Stop */
-#define I2C_PCA_CON_SI		0x08 /* Serial Interrupt */
-#define I2C_PCA_CON_CR		0x07 /* Clock Rate (MASK) */
-
-#define I2C_PCA_CON_330kHz	0x00
-#define I2C_PCA_CON_288kHz	0x01
-#define I2C_PCA_CON_217kHz	0x02
-#define I2C_PCA_CON_146kHz	0x03
-#define I2C_PCA_CON_88kHz	0x04
-#define I2C_PCA_CON_59kHz	0x05
-#define I2C_PCA_CON_44kHz	0x06
-#define I2C_PCA_CON_36kHz	0x07
-
-#endif /* I2C_PCA9564_H */

+ 53 - 20
drivers/i2c/busses/Kconfig

@@ -100,9 +100,12 @@ config I2C_AU1550
 
 config I2C_BLACKFIN_TWI
 	tristate "Blackfin TWI I2C support"
-	depends on BF534 || BF536 || BF537
+	depends on BLACKFIN
 	help
-	  This is the TWI I2C device driver for Blackfin 534/536/537/54x.
+	  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.
 
@@ -135,7 +138,7 @@ config I2C_ELEKTOR
 	  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 
+	  This support is also available as a module.  If so, the module
 	  will be called i2c-elektor.
 
 config I2C_GPIO
@@ -190,7 +193,7 @@ config I2C_I810
 	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 
+	  810/815 family of mainboard I2C interfaces.  Specifically, the
 	  following versions of the chipset are supported:
 	    i810AA
 	    i810AB
@@ -246,10 +249,10 @@ config I2C_PIIX4
 
 config I2C_IBM_IIC
 	tristate "IBM PPC 4xx on-chip I2C interface"
-	depends on IBM_OCP
+	depends on 4xx
 	help
-	  Say Y here if you want to use IIC peripheral found on 
-	  embedded IBM PPC 4xx based systems. 
+	  Say Y here if you want to use IIC peripheral found on
+	  embedded IBM PPC 4xx based systems.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-ibm_iic.
@@ -269,7 +272,7 @@ config I2C_IXP2000
 	depends on ARCH_IXP2000
 	select I2C_ALGOBIT
 	help
-	  Say Y here if you have an Intel IXP2000 (2400, 2800, 2850) based 
+	  Say Y here if you have an Intel IXP2000 (2400, 2800, 2850) based
 	  system and are using GPIO lines for an I2C bus.
 
 	  This support is also available as a module. If so, the module
@@ -354,7 +357,7 @@ config I2C_PARPORT
 	  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 
+	  This support is also available as a module.  If so, the module
 	  will be called i2c-parport.
 
 config I2C_PARPORT_LIGHT
@@ -372,12 +375,12 @@ config I2C_PARPORT_LIGHT
 	  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.
-	  
+
 	  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 support is also available as a module.  If so, the module 
+	  This support is also available as a module.  If so, the module
 	  will be called i2c-parport-light.
 
 config I2C_PASEMI
@@ -401,7 +404,7 @@ config I2C_PROSAVAGE
 
 	  This driver is deprecated in favor of the savagefb driver.
 
-	  This support is also available as a module.  If so, the module 
+	  This support is also available as a module.  If so, the module
 	  will be called i2c-prosavage.
 
 config I2C_S3C2410
@@ -417,7 +420,7 @@ config I2C_SAVAGE4
 	depends on PCI
 	select I2C_ALGOBIT
 	help
-	  If you say yes to this option, support will be included for the 
+	  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.
@@ -452,7 +455,7 @@ config SCx200_I2C
 
 	  If you don't know what to do here, say N.
 
-	  This support is also available as a module.  If so, the module 
+	  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
@@ -483,14 +486,14 @@ config SCx200_ACB
 
 	  If you don't know what to do here, say N.
 
-	  This support is also available as a module.  If so, the module 
+	  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 
+	  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
@@ -500,7 +503,7 @@ config I2C_SIS630
 	tristate "SiS 630/730"
 	depends on PCI
 	help
-	  If you say yes to this option, support will be included for the 
+	  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
@@ -632,9 +635,9 @@ config I2C_PCA_ISA
 	select I2C_ALGOPCA
 	default n
 	help
-	  This driver supports ISA boards using the Philips PCA 9564
-	  Parallel bus to I2C bus controller
-	  
+	  This driver supports ISA boards using the Philips PCA9564
+	  parallel bus to I2C bus controller.
+
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-pca-isa.
 
@@ -643,6 +646,17 @@ config I2C_PCA_ISA
 	  delays when I2C/SMBus chip drivers are loaded (e.g. at boot
 	  time).  If unsure, say N.
 
+config I2C_PCA_PLATFORM
+	tristate "PCA9564 as platform device"
+	select I2C_ALGOPCA
+	default n
+	help
+	  This driver supports a memory mapped Philips PCA9564
+	  parallel bus to I2C bus controller.
+
+	  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
@@ -672,4 +686,23 @@ 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
+	help
+	  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-sh7760.
+
+config I2C_SH_MOBILE
+	tristate "SuperH Mobile I2C Controller"
+	depends on SUPERH
+	help
+	  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.
+
 endmenu

+ 3 - 0
drivers/i2c/busses/Makefile

@@ -30,6 +30,7 @@ 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
@@ -37,6 +38,8 @@ 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

+ 1 - 1
drivers/i2c/busses/i2c-at91.c

@@ -298,7 +298,7 @@ static int at91_i2c_resume(struct platform_device *pdev)
 #endif
 
 /* work with "modprobe at91_i2c" from hotplugging or coldplugging */
-MODULE_ALIAS("at91_i2c");
+MODULE_ALIAS("platform:at91_i2c");
 
 static struct platform_driver at91_i2c_driver = {
 	.probe		= at91_i2c_probe,

+ 1 - 0
drivers/i2c/busses/i2c-au1550.c

@@ -472,6 +472,7 @@ i2c_au1550_exit(void)
 MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC.");
 MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:au1xpsc_smbus");
 
 module_init (i2c_au1550_init);
 module_exit (i2c_au1550_exit);

+ 295 - 180
drivers/i2c/busses/i2c-bfin-twi.c

@@ -1,25 +1,11 @@
 /*
- * drivers/i2c/busses/i2c-bfin-twi.c
+ * Blackfin On-Chip Two Wire Interface Driver
  *
- * Description: Driver for Blackfin Two Wire Interface
+ * Copyright 2005-2007 Analog Devices Inc.
  *
- * Author:      sonicz  <sonic.zhang@analog.com>
+ * Enter bugs at http://blackfin.uclinux.org/
  *
- * Copyright (c) 2005-2007 Analog Devices, Inc.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Licensed under the GPL-2 or later.
  */
 
 #include <linux/module.h>
@@ -34,14 +20,16 @@
 #include <linux/platform_device.h>
 
 #include <asm/blackfin.h>
+#include <asm/portmux.h>
 #include <asm/irq.h>
 
 #define POLL_TIMEOUT       (2 * HZ)
 
 /* SMBus mode*/
-#define TWI_I2C_MODE_STANDARD		0x01
-#define TWI_I2C_MODE_STANDARDSUB	0x02
-#define TWI_I2C_MODE_COMBINED		0x04
+#define TWI_I2C_MODE_STANDARD		1
+#define TWI_I2C_MODE_STANDARDSUB	2
+#define TWI_I2C_MODE_COMBINED		3
+#define TWI_I2C_MODE_REPEAT		4
 
 struct bfin_twi_iface {
 	int			irq;
@@ -58,39 +46,74 @@ struct bfin_twi_iface {
 	struct timer_list	timeout_timer;
 	struct i2c_adapter	adap;
 	struct completion	complete;
+	struct i2c_msg 		*pmsg;
+	int			msg_num;
+	int			cur_msg;
+	void __iomem		*regs_base;
 };
 
-static struct bfin_twi_iface twi_iface;
+
+#define DEFINE_TWI_REG(reg, off) \
+static inline u16 read_##reg(struct bfin_twi_iface *iface) \
+	{ return bfin_read16(iface->regs_base + (off)); } \
+static inline void write_##reg(struct bfin_twi_iface *iface, u16 v) \
+	{ bfin_write16(iface->regs_base + (off), v); }
+
+DEFINE_TWI_REG(CLKDIV, 0x00)
+DEFINE_TWI_REG(CONTROL, 0x04)
+DEFINE_TWI_REG(SLAVE_CTL, 0x08)
+DEFINE_TWI_REG(SLAVE_STAT, 0x0C)
+DEFINE_TWI_REG(SLAVE_ADDR, 0x10)
+DEFINE_TWI_REG(MASTER_CTL, 0x14)
+DEFINE_TWI_REG(MASTER_STAT, 0x18)
+DEFINE_TWI_REG(MASTER_ADDR, 0x1C)
+DEFINE_TWI_REG(INT_STAT, 0x20)
+DEFINE_TWI_REG(INT_MASK, 0x24)
+DEFINE_TWI_REG(FIFO_CTL, 0x28)
+DEFINE_TWI_REG(FIFO_STAT, 0x2C)
+DEFINE_TWI_REG(XMT_DATA8, 0x80)
+DEFINE_TWI_REG(XMT_DATA16, 0x84)
+DEFINE_TWI_REG(RCV_DATA8, 0x88)
+DEFINE_TWI_REG(RCV_DATA16, 0x8C)
+
+static const u16 pin_req[2][3] = {
+	{P_TWI0_SCL, P_TWI0_SDA, 0},
+	{P_TWI1_SCL, P_TWI1_SDA, 0},
+};
 
 static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
 {
-	unsigned short twi_int_status = bfin_read_TWI_INT_STAT();
-	unsigned short mast_stat = bfin_read_TWI_MASTER_STAT();
+	unsigned short twi_int_status = read_INT_STAT(iface);
+	unsigned short mast_stat = read_MASTER_STAT(iface);
 
 	if (twi_int_status & XMTSERV) {
 		/* Transmit next data */
 		if (iface->writeNum > 0) {
-			bfin_write_TWI_XMT_DATA8(*(iface->transPtr++));
+			write_XMT_DATA8(iface, *(iface->transPtr++));
 			iface->writeNum--;
 		}
 		/* start receive immediately after complete sending in
 		 * combine mode.
 		 */
-		else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
-			bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL()
-				| MDIR | RSTART);
-		} else if (iface->manual_stop)
-			bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL()
-				| STOP);
+		else if (iface->cur_mode == TWI_I2C_MODE_COMBINED)
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) | MDIR | RSTART);
+		else if (iface->manual_stop)
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) | STOP);
+		else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
+				iface->cur_msg+1 < iface->msg_num)
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) | RSTART);
 		SSYNC();
 		/* Clear status */
-		bfin_write_TWI_INT_STAT(XMTSERV);
+		write_INT_STAT(iface, XMTSERV);
 		SSYNC();
 	}
 	if (twi_int_status & RCVSERV) {
 		if (iface->readNum > 0) {
 			/* Receive next data */
-			*(iface->transPtr) = bfin_read_TWI_RCV_DATA8();
+			*(iface->transPtr) = read_RCV_DATA8(iface);
 			if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
 				/* Change combine mode into sub mode after
 				 * read first data.
@@ -105,28 +128,33 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
 			iface->transPtr++;
 			iface->readNum--;
 		} else if (iface->manual_stop) {
-			bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL()
-				| STOP);
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) | STOP);
+			SSYNC();
+		} else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
+				iface->cur_msg+1 < iface->msg_num) {
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) | RSTART);
 			SSYNC();
 		}
 		/* Clear interrupt source */
-		bfin_write_TWI_INT_STAT(RCVSERV);
+		write_INT_STAT(iface, RCVSERV);
 		SSYNC();
 	}
 	if (twi_int_status & MERR) {
-		bfin_write_TWI_INT_STAT(MERR);
-		bfin_write_TWI_INT_MASK(0);
-		bfin_write_TWI_MASTER_STAT(0x3e);
-		bfin_write_TWI_MASTER_CTL(0);
+		write_INT_STAT(iface, MERR);
+		write_INT_MASK(iface, 0);
+		write_MASTER_STAT(iface, 0x3e);
+		write_MASTER_CTL(iface, 0);
 		SSYNC();
-		iface->result = -1;
+		iface->result = -EIO;
 		/* if both err and complete int stats are set, return proper
 		 * results.
 		 */
 		if (twi_int_status & MCOMP) {
-			bfin_write_TWI_INT_STAT(MCOMP);
-			bfin_write_TWI_INT_MASK(0);
-			bfin_write_TWI_MASTER_CTL(0);
+			write_INT_STAT(iface, MCOMP);
+			write_INT_MASK(iface, 0);
+			write_MASTER_CTL(iface, 0);
 			SSYNC();
 			/* If it is a quick transfer, only address bug no data,
 			 * not an err, return 1.
@@ -143,7 +171,7 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
 		return;
 	}
 	if (twi_int_status & MCOMP) {
-		bfin_write_TWI_INT_STAT(MCOMP);
+		write_INT_STAT(iface, MCOMP);
 		SSYNC();
 		if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
 			if (iface->readNum == 0) {
@@ -152,28 +180,63 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
 				 */
 				iface->readNum = 1;
 				iface->manual_stop = 1;
-				bfin_write_TWI_MASTER_CTL(
-					bfin_read_TWI_MASTER_CTL()
-					| (0xff << 6));
+				write_MASTER_CTL(iface,
+					read_MASTER_CTL(iface) | (0xff << 6));
 			} else {
 				/* set the readd number in other
 				 * combine mode.
 				 */
-				bfin_write_TWI_MASTER_CTL(
-					(bfin_read_TWI_MASTER_CTL() &
+				write_MASTER_CTL(iface,
+					(read_MASTER_CTL(iface) &
 					(~(0xff << 6))) |
-					( iface->readNum << 6));
+					(iface->readNum << 6));
+			}
+			/* remove restart bit and enable master receive */
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) & ~RSTART);
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) | MEN | MDIR);
+			SSYNC();
+		} else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
+				iface->cur_msg+1 < iface->msg_num) {
+			iface->cur_msg++;
+			iface->transPtr = iface->pmsg[iface->cur_msg].buf;
+			iface->writeNum = iface->readNum =
+				iface->pmsg[iface->cur_msg].len;
+			/* Set Transmit device address */
+			write_MASTER_ADDR(iface,
+				iface->pmsg[iface->cur_msg].addr);
+			if (iface->pmsg[iface->cur_msg].flags & I2C_M_RD)
+				iface->read_write = I2C_SMBUS_READ;
+			else {
+				iface->read_write = I2C_SMBUS_WRITE;
+				/* Transmit first data */
+				if (iface->writeNum > 0) {
+					write_XMT_DATA8(iface,
+						*(iface->transPtr++));
+					iface->writeNum--;
+					SSYNC();
+				}
+			}
+
+			if (iface->pmsg[iface->cur_msg].len <= 255)
+				write_MASTER_CTL(iface,
+				iface->pmsg[iface->cur_msg].len << 6);
+			else {
+				write_MASTER_CTL(iface, 0xff << 6);
+				iface->manual_stop = 1;
 			}
 			/* remove restart bit and enable master receive */
-			bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() &
-				~RSTART);
-			bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() |
-				MEN | MDIR);
+			write_MASTER_CTL(iface,
+				read_MASTER_CTL(iface) & ~RSTART);
+			write_MASTER_CTL(iface, read_MASTER_CTL(iface) |
+				MEN | ((iface->read_write == I2C_SMBUS_READ) ?
+				MDIR : 0));
 			SSYNC();
 		} else {
 			iface->result = 1;
-			bfin_write_TWI_INT_MASK(0);
-			bfin_write_TWI_MASTER_CTL(0);
+			write_INT_MASK(iface, 0);
+			write_MASTER_CTL(iface, 0);
 			SSYNC();
 			complete(&iface->complete);
 		}
@@ -221,91 +284,85 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap,
 {
 	struct bfin_twi_iface *iface = adap->algo_data;
 	struct i2c_msg *pmsg;
-	int i, ret;
 	int rc = 0;
 
-	if (!(bfin_read_TWI_CONTROL() & TWI_ENA))
+	if (!(read_CONTROL(iface) & TWI_ENA))
 		return -ENXIO;
 
-	while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) {
+	while (read_MASTER_STAT(iface) & BUSBUSY)
 		yield();
+
+	iface->pmsg = msgs;
+	iface->msg_num = num;
+	iface->cur_msg = 0;
+
+	pmsg = &msgs[0];
+	if (pmsg->flags & I2C_M_TEN) {
+		dev_err(&adap->dev, "10 bits addr not supported!\n");
+		return -EINVAL;
 	}
 
-	ret = 0;
-	for (i = 0; rc >= 0 && i < num; i++) {
-		pmsg = &msgs[i];
-		if (pmsg->flags & I2C_M_TEN) {
-			dev_err(&(adap->dev), "i2c-bfin-twi: 10 bits addr "
-				"not supported !\n");
-			rc = -EINVAL;
-			break;
-		}
+	iface->cur_mode = TWI_I2C_MODE_REPEAT;
+	iface->manual_stop = 0;
+	iface->transPtr = pmsg->buf;
+	iface->writeNum = iface->readNum = pmsg->len;
+	iface->result = 0;
+	iface->timeout_count = 10;
+	init_completion(&(iface->complete));
+	/* Set Transmit device address */
+	write_MASTER_ADDR(iface, pmsg->addr);
 
-		iface->cur_mode = TWI_I2C_MODE_STANDARD;
-		iface->manual_stop = 0;
-		iface->transPtr = pmsg->buf;
-		iface->writeNum = iface->readNum = pmsg->len;
-		iface->result = 0;
-		iface->timeout_count = 10;
-		/* Set Transmit device address */
-		bfin_write_TWI_MASTER_ADDR(pmsg->addr);
-
-		/* FIFO Initiation. Data in FIFO should be
-		 *  discarded before start a new operation.
-		 */
-		bfin_write_TWI_FIFO_CTL(0x3);
-		SSYNC();
-		bfin_write_TWI_FIFO_CTL(0);
-		SSYNC();
+	/* FIFO Initiation. Data in FIFO should be
+	 *  discarded before start a new operation.
+	 */
+	write_FIFO_CTL(iface, 0x3);
+	SSYNC();
+	write_FIFO_CTL(iface, 0);
+	SSYNC();
 
-		if (pmsg->flags & I2C_M_RD)
-			iface->read_write = I2C_SMBUS_READ;
-		else {
-			iface->read_write = I2C_SMBUS_WRITE;
-			/* Transmit first data */
-			if (iface->writeNum > 0) {
-				bfin_write_TWI_XMT_DATA8(*(iface->transPtr++));
-				iface->writeNum--;
-				SSYNC();
-			}
+	if (pmsg->flags & I2C_M_RD)
+		iface->read_write = I2C_SMBUS_READ;
+	else {
+		iface->read_write = I2C_SMBUS_WRITE;
+		/* Transmit first data */
+		if (iface->writeNum > 0) {
+			write_XMT_DATA8(iface, *(iface->transPtr++));
+			iface->writeNum--;
+			SSYNC();
 		}
+	}
 
-		/* clear int stat */
-		bfin_write_TWI_INT_STAT(MERR|MCOMP|XMTSERV|RCVSERV);
+	/* clear int stat */
+	write_INT_STAT(iface, MERR | MCOMP | XMTSERV | RCVSERV);
 
-		/* Interrupt mask . Enable XMT, RCV interrupt */
-		bfin_write_TWI_INT_MASK(MCOMP | MERR |
-			((iface->read_write == I2C_SMBUS_READ)?
-			RCVSERV : XMTSERV));
-		SSYNC();
+	/* Interrupt mask . Enable XMT, RCV interrupt */
+	write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV);
+	SSYNC();
 
-		if (pmsg->len > 0 && pmsg->len <= 255)
-			bfin_write_TWI_MASTER_CTL(pmsg->len << 6);
-		else if (pmsg->len > 255) {
-			bfin_write_TWI_MASTER_CTL(0xff << 6);
-			iface->manual_stop = 1;
-		} else
-			break;
+	if (pmsg->len <= 255)
+		write_MASTER_CTL(iface, pmsg->len << 6);
+	else {
+		write_MASTER_CTL(iface, 0xff << 6);
+		iface->manual_stop = 1;
+	}
 
-		iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
-		add_timer(&iface->timeout_timer);
+	iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
+	add_timer(&iface->timeout_timer);
 
-		/* Master enable */
-		bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
-			((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
-			((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
-		SSYNC();
+	/* Master enable */
+	write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
+		((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
+		((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
+	SSYNC();
 
-		wait_for_completion(&iface->complete);
+	wait_for_completion(&iface->complete);
 
-		rc = iface->result;
-		if (rc == 1)
-			ret++;
-		else if (rc == -1)
-			break;
-	}
+	rc = iface->result;
 
-	return ret;
+	if (rc == 1)
+		return num;
+	else
+		return rc;
 }
 
 /*
@@ -319,12 +376,11 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 	struct bfin_twi_iface *iface = adap->algo_data;
 	int rc = 0;
 
-	if (!(bfin_read_TWI_CONTROL() & TWI_ENA))
+	if (!(read_CONTROL(iface) & TWI_ENA))
 		return -ENXIO;
 
-	while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) {
+	while (read_MASTER_STAT(iface) & BUSBUSY)
 		yield();
-	}
 
 	iface->writeNum = 0;
 	iface->readNum = 0;
@@ -392,19 +448,20 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 	iface->read_write = read_write;
 	iface->command = command;
 	iface->timeout_count = 10;
+	init_completion(&(iface->complete));
 
 	/* FIFO Initiation. Data in FIFO should be discarded before
 	 * start a new operation.
 	 */
-	bfin_write_TWI_FIFO_CTL(0x3);
+	write_FIFO_CTL(iface, 0x3);
 	SSYNC();
-	bfin_write_TWI_FIFO_CTL(0);
+	write_FIFO_CTL(iface, 0);
 
 	/* clear int stat */
-	bfin_write_TWI_INT_STAT(MERR|MCOMP|XMTSERV|RCVSERV);
+	write_INT_STAT(iface, MERR | MCOMP | XMTSERV | RCVSERV);
 
 	/* Set Transmit device address */
-	bfin_write_TWI_MASTER_ADDR(addr);
+	write_MASTER_ADDR(iface, addr);
 	SSYNC();
 
 	iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
@@ -412,60 +469,64 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 
 	switch (iface->cur_mode) {
 	case TWI_I2C_MODE_STANDARDSUB:
-		bfin_write_TWI_XMT_DATA8(iface->command);
-		bfin_write_TWI_INT_MASK(MCOMP | MERR |
+		write_XMT_DATA8(iface, iface->command);
+		write_INT_MASK(iface, MCOMP | MERR |
 			((iface->read_write == I2C_SMBUS_READ) ?
 			RCVSERV : XMTSERV));
 		SSYNC();
 
 		if (iface->writeNum + 1 <= 255)
-			bfin_write_TWI_MASTER_CTL((iface->writeNum + 1) << 6);
+			write_MASTER_CTL(iface, (iface->writeNum + 1) << 6);
 		else {
-			bfin_write_TWI_MASTER_CTL(0xff << 6);
+			write_MASTER_CTL(iface, 0xff << 6);
 			iface->manual_stop = 1;
 		}
 		/* Master enable */
-		bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
+		write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
 			((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
 		break;
 	case TWI_I2C_MODE_COMBINED:
-		bfin_write_TWI_XMT_DATA8(iface->command);
-		bfin_write_TWI_INT_MASK(MCOMP | MERR | RCVSERV | XMTSERV);
+		write_XMT_DATA8(iface, iface->command);
+		write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV);
 		SSYNC();
 
 		if (iface->writeNum > 0)
-			bfin_write_TWI_MASTER_CTL((iface->writeNum + 1) << 6);
+			write_MASTER_CTL(iface, (iface->writeNum + 1) << 6);
 		else
-			bfin_write_TWI_MASTER_CTL(0x1 << 6);
+			write_MASTER_CTL(iface, 0x1 << 6);
 		/* Master enable */
-		bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
+		write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
 			((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));
 		break;
 	default:
-		bfin_write_TWI_MASTER_CTL(0);
+		write_MASTER_CTL(iface, 0);
 		if (size != I2C_SMBUS_QUICK) {
 			/* Don't access xmit data register when this is a
 			 * read operation.
 			 */
 			if (iface->read_write != I2C_SMBUS_READ) {
 				if (iface->writeNum > 0) {
-					bfin_write_TWI_XMT_DATA8(*(iface->transPtr++));
+					write_XMT_DATA8(iface,
+						*(iface->transPtr++));
 					if (iface->writeNum <= 255)
-						bfin_write_TWI_MASTER_CTL(iface->writeNum << 6);
+						write_MASTER_CTL(iface,
+							iface->writeNum << 6);
 					else {
-						bfin_write_TWI_MASTER_CTL(0xff << 6);
+						write_MASTER_CTL(iface,
+							0xff << 6);
 						iface->manual_stop = 1;
 					}
 					iface->writeNum--;
 				} else {
-					bfin_write_TWI_XMT_DATA8(iface->command);
-					bfin_write_TWI_MASTER_CTL(1 << 6);
+					write_XMT_DATA8(iface, iface->command);
+					write_MASTER_CTL(iface, 1 << 6);
 				}
 			} else {
 				if (iface->readNum > 0 && iface->readNum <= 255)
-					bfin_write_TWI_MASTER_CTL(iface->readNum << 6);
+					write_MASTER_CTL(iface,
+						iface->readNum << 6);
 				else if (iface->readNum > 255) {
-					bfin_write_TWI_MASTER_CTL(0xff << 6);
+					write_MASTER_CTL(iface, 0xff << 6);
 					iface->manual_stop = 1;
 				} else {
 					del_timer(&iface->timeout_timer);
@@ -473,13 +534,13 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 				}
 			}
 		}
-		bfin_write_TWI_INT_MASK(MCOMP | MERR |
+		write_INT_MASK(iface, MCOMP | MERR |
 			((iface->read_write == I2C_SMBUS_READ) ?
 			RCVSERV : XMTSERV));
 		SSYNC();
 
 		/* Master enable */
-		bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN |
+		write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
 			((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
 			((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
 		break;
@@ -514,10 +575,10 @@ static struct i2c_algorithm bfin_twi_algorithm = {
 
 static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state)
 {
-/*	struct bfin_twi_iface *iface = platform_get_drvdata(dev);*/
+	struct bfin_twi_iface *iface = platform_get_drvdata(dev);
 
 	/* Disable TWI */
-	bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() & ~TWI_ENA);
+	write_CONTROL(iface, read_CONTROL(iface) & ~TWI_ENA);
 	SSYNC();
 
 	return 0;
@@ -525,24 +586,52 @@ static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state)
 
 static int i2c_bfin_twi_resume(struct platform_device *dev)
 {
-/*	struct bfin_twi_iface *iface = platform_get_drvdata(dev);*/
+	struct bfin_twi_iface *iface = platform_get_drvdata(dev);
 
 	/* Enable TWI */
-	bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA);
+	write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA);
 	SSYNC();
 
 	return 0;
 }
 
-static int i2c_bfin_twi_probe(struct platform_device *dev)
+static int i2c_bfin_twi_probe(struct platform_device *pdev)
 {
-	struct bfin_twi_iface *iface = &twi_iface;
+	struct bfin_twi_iface *iface;
 	struct i2c_adapter *p_adap;
+	struct resource *res;
 	int rc;
 
+	iface = kzalloc(sizeof(struct bfin_twi_iface), GFP_KERNEL);
+	if (!iface) {
+		dev_err(&pdev->dev, "Cannot allocate memory\n");
+		rc = -ENOMEM;
+		goto out_error_nomem;
+	}
+
 	spin_lock_init(&(iface->lock));
-	init_completion(&(iface->complete));
-	iface->irq = IRQ_TWI;
+
+	/* Find and map our resources */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
+		rc = -ENOENT;
+		goto out_error_get_res;
+	}
+
+	iface->regs_base = ioremap(res->start, res->end - res->start + 1);
+	if (iface->regs_base == NULL) {
+		dev_err(&pdev->dev, "Cannot map IO\n");
+		rc = -ENXIO;
+		goto out_error_ioremap;
+	}
+
+	iface->irq = platform_get_irq(pdev, 0);
+	if (iface->irq < 0) {
+		dev_err(&pdev->dev, "No IRQ specified\n");
+		rc = -ENOENT;
+		goto out_error_no_irq;
+	}
 
 	init_timer(&(iface->timeout_timer));
 	iface->timeout_timer.function = bfin_twi_timeout;
@@ -550,39 +639,63 @@ static int i2c_bfin_twi_probe(struct platform_device *dev)
 
 	p_adap = &iface->adap;
 	p_adap->id = I2C_HW_BLACKFIN;
-	p_adap->nr = dev->id;
-	strlcpy(p_adap->name, dev->name, sizeof(p_adap->name));
+	p_adap->nr = pdev->id;
+	strlcpy(p_adap->name, pdev->name, sizeof(p_adap->name));
 	p_adap->algo = &bfin_twi_algorithm;
 	p_adap->algo_data = iface;
 	p_adap->class = I2C_CLASS_ALL;
-	p_adap->dev.parent = &dev->dev;
+	p_adap->dev.parent = &pdev->dev;
+
+	rc = peripheral_request_list(pin_req[pdev->id], "i2c-bfin-twi");
+	if (rc) {
+		dev_err(&pdev->dev, "Can't setup pin mux!\n");
+		goto out_error_pin_mux;
+	}
 
 	rc = request_irq(iface->irq, bfin_twi_interrupt_entry,
-		IRQF_DISABLED, dev->name, iface);
+		IRQF_DISABLED, pdev->name, iface);
 	if (rc) {
-		dev_err(&(p_adap->dev), "i2c-bfin-twi: can't get IRQ %d !\n",
-			iface->irq);
-		return -ENODEV;
+		dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq);
+		rc = -ENODEV;
+		goto out_error_req_irq;
 	}
 
 	/* Set TWI internal clock as 10MHz */
-	bfin_write_TWI_CONTROL(((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F);
+	write_CONTROL(iface, ((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F);
 
 	/* Set Twi interface clock as specified */
-	bfin_write_TWI_CLKDIV((( 5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ )
-			<< 8) | (( 5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ )
+	write_CLKDIV(iface, ((5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ)
+			<< 8) | ((5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ)
 			& 0xFF));
 
 	/* Enable TWI */
-	bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA);
+	write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA);
 	SSYNC();
 
 	rc = i2c_add_numbered_adapter(p_adap);
-	if (rc < 0)
-		free_irq(iface->irq, iface);
-	else
-		platform_set_drvdata(dev, iface);
+	if (rc < 0) {
+		dev_err(&pdev->dev, "Can't add i2c adapter!\n");
+		goto out_error_add_adapter;
+	}
+
+	platform_set_drvdata(pdev, iface);
 
+	dev_info(&pdev->dev, "Blackfin BF5xx on-chip I2C TWI Contoller, "
+		"regs_base@%p\n", iface->regs_base);
+
+	return 0;
+
+out_error_add_adapter:
+	free_irq(iface->irq, iface);
+out_error_req_irq:
+out_error_no_irq:
+	peripheral_free_list(pin_req[pdev->id]);
+out_error_pin_mux:
+	iounmap(iface->regs_base);
+out_error_ioremap:
+out_error_get_res:
+	kfree(iface);
+out_error_nomem:
 	return rc;
 }
 
@@ -594,6 +707,9 @@ static int i2c_bfin_twi_remove(struct platform_device *pdev)
 
 	i2c_del_adapter(&(iface->adap));
 	free_irq(iface->irq, iface);
+	peripheral_free_list(pin_req[pdev->id]);
+	iounmap(iface->regs_base);
+	kfree(iface);
 
 	return 0;
 }
@@ -611,8 +727,6 @@ static struct platform_driver i2c_bfin_twi_driver = {
 
 static int __init i2c_bfin_twi_init(void)
 {
-	pr_info("I2C: Blackfin I2C TWI driver\n");
-
 	return platform_driver_register(&i2c_bfin_twi_driver);
 }
 
@@ -621,9 +735,10 @@ static void __exit i2c_bfin_twi_exit(void)
 	platform_driver_unregister(&i2c_bfin_twi_driver);
 }
 
-MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for Blackfin TWI");
-MODULE_LICENSE("GPL");
-
 module_init(i2c_bfin_twi_init);
 module_exit(i2c_bfin_twi_exit);
+
+MODULE_AUTHOR("Bryan Wu, Sonic Zhang");
+MODULE_DESCRIPTION("Blackfin BF5xx on-chip I2C TWI Contoller Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:i2c-bfin-twi");

+ 6 - 3
drivers/i2c/busses/i2c-davinci.c

@@ -328,7 +328,7 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 	int i;
 	int ret;
 
-	dev_dbg(dev->dev, "%s: msgs: %d\n", __FUNCTION__, num);
+	dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num);
 
 	ret = i2c_davinci_wait_bus_not_busy(dev, 1);
 	if (ret < 0) {
@@ -342,7 +342,7 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 			return ret;
 	}
 
-	dev_dbg(dev->dev, "%s:%d ret: %d\n", __FUNCTION__, __LINE__, ret);
+	dev_dbg(dev->dev, "%s:%d ret: %d\n", __func__, __LINE__, ret);
 
 	return num;
 }
@@ -364,7 +364,7 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
 	u16 w;
 
 	while ((stat = davinci_i2c_read_reg(dev, DAVINCI_I2C_IVR_REG))) {
-		dev_dbg(dev->dev, "%s: stat=0x%x\n", __FUNCTION__, stat);
+		dev_dbg(dev->dev, "%s: stat=0x%x\n", __func__, stat);
 		if (count++ == 100) {
 			dev_warn(dev->dev, "Too much work in one IRQ\n");
 			break;
@@ -553,6 +553,9 @@ static int davinci_i2c_remove(struct platform_device *pdev)
 	return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:i2c_davinci");
+
 static struct platform_driver davinci_i2c_driver = {
 	.probe		= davinci_i2c_probe,
 	.remove		= davinci_i2c_remove,

+ 1 - 0
drivers/i2c/busses/i2c-gpio.c

@@ -220,3 +220,4 @@ module_exit(i2c_gpio_exit);
 MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
 MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:i2c-gpio");

+ 191 - 6
drivers/i2c/busses/i2c-ibm_iic.c

@@ -6,6 +6,9 @@
  * Copyright (c) 2003, 2004 Zultys Technologies.
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  *
+ * Copyright (c) 2008 PIKA Technologies
+ * Sean MacLennan <smaclennan@pikatech.com>
+ *
  * Based on original work by
  * 	Ian DaSilva  <idasilva@mvista.com>
  *      Armin Kuster <akuster@mvista.com>
@@ -39,12 +42,17 @@
 #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 "i2c-ibm_iic.h"
 
-#define DRIVER_VERSION "2.1"
+#define DRIVER_VERSION "2.2"
 
 MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION);
 MODULE_LICENSE("GPL");
@@ -650,13 +658,14 @@ static inline u8 iic_clckdiv(unsigned int opb)
 	opb /= 1000000;
 
 	if (opb < 20 || opb > 150){
-		printk(KERN_CRIT "ibm-iic: invalid OPB clock frequency %u MHz\n",
+		printk(KERN_WARNING "ibm-iic: invalid OPB clock frequency %u MHz\n",
 			opb);
 		opb = opb < 20 ? 20 : 150;
 	}
 	return (u8)((opb + 9) / 10 - 1);
 }
 
+#ifdef CONFIG_IBM_OCP
 /*
  * Register single IIC interface
  */
@@ -672,7 +681,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){
 			ocp->def->index);
 
 	if (!(dev = kzalloc(sizeof(*dev), GFP_KERNEL))) {
-		printk(KERN_CRIT "ibm-iic%d: failed to allocate device data\n",
+		printk(KERN_ERR "ibm-iic%d: failed to allocate device data\n",
 			ocp->def->index);
 		return -ENOMEM;
 	}
@@ -687,7 +696,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){
 	}
 
 	if (!(dev->vaddr = ioremap(ocp->def->paddr, sizeof(struct iic_regs)))){
-		printk(KERN_CRIT "ibm-iic%d: failed to ioremap device registers\n",
+		printk(KERN_ERR "ibm-iic%d: failed to ioremap device registers\n",
 			dev->idx);
 		ret = -ENXIO;
 		goto fail2;
@@ -745,7 +754,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){
 	adap->nr = dev->idx >= 0 ? dev->idx : 0;
 
 	if ((ret = i2c_add_numbered_adapter(adap)) < 0) {
-		printk(KERN_CRIT "ibm-iic%d: failed to register i2c adapter\n",
+		printk(KERN_ERR "ibm-iic%d: failed to register i2c adapter\n",
 			dev->idx);
 		goto fail;
 	}
@@ -778,7 +787,7 @@ 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_CRIT "ibm-iic%d: failed to delete i2c adapter :(\n",
+		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){
@@ -828,5 +837,181 @@ 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)
+{
+	struct device_node *np = ofdev->node;
+	int irq;
+
+	if (iic_force_poll)
+		return NO_IRQ;
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (irq == NO_IRQ) {
+		dev_err(&ofdev->dev, "irq_of_parse_and_map failed\n");
+		return NO_IRQ;
+	}
+
+	/* Disable interrupts until we finish initialization, assumes
+	 *  level-sensitive IRQ setup...
+	 */
+	iic_interrupt_mode(dev, 0);
+	if (request_irq(irq, iic_handler, 0, "IBM IIC", dev)) {
+		dev_err(&ofdev->dev, "request_irq %d failed\n", irq);
+		/* Fallback to the polling mode */
+		return NO_IRQ;
+	}
+
+	return irq;
+}
+
+/*
+ * Register single IIC interface
+ */
+static int __devinit iic_probe(struct of_device *ofdev,
+			       const struct of_device_id *match)
+{
+	struct device_node *np = ofdev->node;
+	struct ibm_iic_private *dev;
+	struct i2c_adapter *adap;
+	const u32 *indexp, *freq;
+	int ret;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev) {
+		dev_err(&ofdev->dev, "failed to allocate device data\n");
+		return -ENOMEM;
+	}
+
+	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");
+		ret = -ENXIO;
+		goto error_cleanup;
+	}
+
+	init_waitqueue_head(&dev->wq);
+
+	dev->irq = iic_request_irq(ofdev, dev);
+	if (dev->irq == NO_IRQ)
+		dev_warn(&ofdev->dev, "using polling mode\n");
+
+	/* Board specific settings */
+	if (iic_force_fast || of_get_property(np, "fast-mode", NULL))
+		dev->fast_mode = 1;
+
+	freq = of_get_property(np, "clock-frequency", NULL);
+	if (freq == NULL) {
+		freq = of_get_property(np->parent, "clock-frequency", NULL);
+		if (freq == NULL) {
+			dev_err(&ofdev->dev, "Unable to get bus frequency\n");
+			ret = -EINVAL;
+			goto error_cleanup;
+		}
+	}
+
+	dev->clckdiv = iic_clckdiv(*freq);
+	dev_dbg(&ofdev->dev, "clckdiv = %d\n", dev->clckdiv);
+
+	/* Initialize IIC interface */
+	iic_dev_init(dev);
+
+	/* Register it with i2c layer */
+	adap = &dev->adap;
+	adap->dev.parent = &ofdev->dev;
+	strlcpy(adap->name, "IBM IIC", sizeof(adap->name));
+	i2c_set_adapdata(adap, dev);
+	adap->id = I2C_HW_OCP;
+	adap->class = I2C_CLASS_HWMON;
+	adap->algo = &iic_algo;
+	adap->timeout = 1;
+	adap->nr = dev->idx;
+
+	ret = i2c_add_numbered_adapter(adap);
+	if (ret  < 0) {
+		dev_err(&ofdev->dev, "failed to register i2c adapter\n");
+		goto error_cleanup;
+	}
+
+	dev_info(&ofdev->dev, "using %s mode\n",
+		 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
+
+	return 0;
+
+error_cleanup:
+	if (dev->irq != NO_IRQ) {
+		iic_interrupt_mode(dev, 0);
+		free_irq(dev->irq, dev);
+	}
+
+	if (dev->vaddr)
+		iounmap(dev->vaddr);
+
+	dev_set_drvdata(&ofdev->dev, NULL);
+	kfree(dev);
+	return ret;
+}
+
+/*
+ * Cleanup initialized IIC interface
+ */
+static int __devexit iic_remove(struct of_device *ofdev)
+{
+	struct ibm_iic_private *dev = dev_get_drvdata(&ofdev->dev);
+
+	dev_set_drvdata(&ofdev->dev, NULL);
+
+	i2c_del_adapter(&dev->adap);
+
+	if (dev->irq != NO_IRQ) {
+		iic_interrupt_mode(dev, 0);
+		free_irq(dev->irq, dev);
+	}
+
+	iounmap(dev->vaddr);
+	kfree(dev);
+
+	return 0;
+}
+
+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", },
+	{}
+};
+
+static struct of_platform_driver ibm_iic_driver = {
+	.name	= "ibm-iic",
+	.match_table = ibm_iic_match,
+	.probe	= iic_probe,
+	.remove	= __devexit_p(iic_remove),
+};
+
+static int __init iic_init(void)
+{
+	return of_register_platform_driver(&ibm_iic_driver);
+}
+
+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);

+ 1 - 0
drivers/i2c/busses/i2c-iop3xx.c

@@ -550,3 +550,4 @@ module_exit (i2c_iop3xx_exit);
 MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>");
 MODULE_DESCRIPTION("IOP3xx iic algorithm and driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:IOP3xx-I2C");

+ 1 - 0
drivers/i2c/busses/i2c-ixp2000.c

@@ -164,4 +164,5 @@ module_exit(ixp2000_i2c_exit);
 MODULE_AUTHOR ("Deepak Saxena <dsaxena@plexity.net>");
 MODULE_DESCRIPTION("IXP2000 GPIO-based I2C bus driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:IXP2000-I2C");
 

+ 3 - 0
drivers/i2c/busses/i2c-mpc.c

@@ -392,6 +392,9 @@ static int fsl_i2c_remove(struct platform_device *pdev)
 	return 0;
 };
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:fsl-i2c");
+
 /* Structure for a device driver */
 static struct platform_driver fsl_i2c_driver = {
 	.probe = fsl_i2c_probe,

+ 3 - 0
drivers/i2c/busses/i2c-ocores.c

@@ -312,6 +312,9 @@ static int __devexit ocores_i2c_remove(struct platform_device* pdev)
 	return 0;
 }
 
+/* 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),

+ 1 - 0
drivers/i2c/busses/i2c-omap.c

@@ -693,3 +693,4 @@ module_exit(omap_i2c_exit_driver);
 MODULE_AUTHOR("MontaVista Software, Inc. (and others)");
 MODULE_DESCRIPTION("TI OMAP I2C bus adapter");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:i2c_omap");

+ 20 - 33
drivers/i2c/busses/i2c-pca-isa.c

@@ -1,6 +1,7 @@
 /*
  *  i2c-pca-isa.c driver for PCA9564 on ISA boards
  *    Copyright (C) 2004 Arcom Control Systems
+ *    Copyright (C) 2008 Pengutronix
  *
  *  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
@@ -22,11 +23,9 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/delay.h>
-#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/wait.h>
-
 #include <linux/isa.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-pca.h>
@@ -34,13 +33,9 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include "../algos/i2c-algo-pca.h"
-
+#define DRIVER "i2c-pca-isa"
 #define IO_SIZE 4
 
-#undef DEBUG_IO
-//#define DEBUG_IO
-
 static unsigned long base   = 0x330;
 static int irq 	  = 10;
 
@@ -48,22 +43,9 @@ static int irq 	  = 10;
  * in the actual clock rate */
 static int clock  = I2C_PCA_CON_59kHz;
 
-static int own    = 0x55;
-
 static wait_queue_head_t pca_wait;
 
-static int pca_isa_getown(struct i2c_algo_pca_data *adap)
-{
-	return (own);
-}
-
-static int pca_isa_getclock(struct i2c_algo_pca_data *adap)
-{
-	return (clock);
-}
-
-static void
-pca_isa_writebyte(struct i2c_algo_pca_data *adap, int reg, int val)
+static void pca_isa_writebyte(void *pd, int reg, int val)
 {
 #ifdef DEBUG_IO
 	static char *names[] = { "T/O", "DAT", "ADR", "CON" };
@@ -72,44 +54,49 @@ pca_isa_writebyte(struct i2c_algo_pca_data *adap, int reg, int val)
 	outb(val, base+reg);
 }
 
-static int
-pca_isa_readbyte(struct i2c_algo_pca_data *adap, int reg)
+static int pca_isa_readbyte(void *pd, int reg)
 {
 	int res = inb(base+reg);
 #ifdef DEBUG_IO
 	{
-		static char *names[] = { "STA", "DAT", "ADR", "CON" };	
+		static char *names[] = { "STA", "DAT", "ADR", "CON" };
 		printk("*** read  %s => %#04x\n", names[reg], res);
 	}
 #endif
 	return res;
 }
 
-static int pca_isa_waitforinterrupt(struct i2c_algo_pca_data *adap)
+static int pca_isa_waitforcompletion(void *pd)
 {
 	int ret = 0;
 
 	if (irq > -1) {
 		ret = wait_event_interruptible(pca_wait,
-					       pca_isa_readbyte(adap, I2C_PCA_CON) & I2C_PCA_CON_SI);
+					       pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI);
 	} else {
-		while ((pca_isa_readbyte(adap, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0) 
+		while ((pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)
 			udelay(100);
 	}
 	return ret;
 }
 
+static void pca_isa_resetchip(void *pd)
+{
+	/* apparently only an external reset will do it. not a lot can be done */
+	printk(KERN_WARNING DRIVER ": Haven't figured out how to do a reset yet\n");
+}
+
 static irqreturn_t pca_handler(int this_irq, void *dev_id) {
 	wake_up_interruptible(&pca_wait);
 	return IRQ_HANDLED;
 }
 
 static struct i2c_algo_pca_data pca_isa_data = {
-	.get_own		= pca_isa_getown,
-	.get_clock		= pca_isa_getclock,
+	/* .data intentionally left NULL, not needed with ISA */
 	.write_byte		= pca_isa_writebyte,
 	.read_byte		= pca_isa_readbyte,
-	.wait_for_interrupt	= pca_isa_waitforinterrupt,
+	.wait_for_completion	= pca_isa_waitforcompletion,
+	.reset_chip		= pca_isa_resetchip,
 };
 
 static struct i2c_adapter pca_isa_ops = {
@@ -117,6 +104,7 @@ static struct i2c_adapter pca_isa_ops = {
 	.id		= I2C_HW_A_ISA,
 	.algo_data	= &pca_isa_data,
 	.name		= "PCA9564 ISA Adapter",
+	.timeout	= 100,
 };
 
 static int __devinit pca_isa_probe(struct device *dev, unsigned int id)
@@ -144,6 +132,7 @@ static int __devinit pca_isa_probe(struct device *dev, unsigned int id)
 		}
 	}
 
+	pca_isa_data.i2c_clock = clock;
 	if (i2c_pca_add_bus(&pca_isa_ops) < 0) {
 		dev_err(dev, "Failed to add i2c bus\n");
 		goto out_irq;
@@ -178,7 +167,7 @@ static struct isa_driver pca_isa_driver = {
 	.remove		= __devexit_p(pca_isa_remove),
 	.driver = {
 		.owner	= THIS_MODULE,
-		.name	= "i2c-pca-isa",
+		.name	= DRIVER,
 	}
 };
 
@@ -204,7 +193,5 @@ MODULE_PARM_DESC(irq, "IRQ");
 module_param(clock, int, 0);
 MODULE_PARM_DESC(clock, "Clock rate as described in table 1 of PCA9564 datasheet");
 
-module_param(own, int, 0); /* the driver can't do slave mode, so there's no real point in this */
-
 module_init(pca_isa_init);
 module_exit(pca_isa_exit);

+ 298 - 0
drivers/i2c/busses/i2c-pca-platform.c

@@ -0,0 +1,298 @@
+/*
+ *  i2c_pca_platform.c
+ *
+ *  Platform driver for the PCA9564 I2C controller.
+ *
+ *  Copyright (C) 2008 Pengutronix
+ *
+ *  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.
+
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/i2c-algo-pca.h>
+#include <linux/i2c-pca-platform.h>
+#include <linux/gpio.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#define res_len(r)		((r)->end - (r)->start + 1)
+
+struct i2c_pca_pf_data {
+	void __iomem			*reg_base;
+	int				irq;	/* if 0, use polling */
+	int				gpio;
+	wait_queue_head_t		wait;
+	struct i2c_adapter		adap;
+	struct i2c_algo_pca_data	algo_data;
+	unsigned long			io_base;
+	unsigned long			io_size;
+};
+
+/* Read/Write functions for different register alignments */
+
+static int i2c_pca_pf_readbyte8(void *pd, int reg)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	return ioread8(i2c->reg_base + reg);
+}
+
+static int i2c_pca_pf_readbyte16(void *pd, int reg)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	return ioread8(i2c->reg_base + reg * 2);
+}
+
+static int i2c_pca_pf_readbyte32(void *pd, int reg)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	return ioread8(i2c->reg_base + reg * 4);
+}
+
+static void i2c_pca_pf_writebyte8(void *pd, int reg, int val)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	iowrite8(val, i2c->reg_base + reg);
+}
+
+static void i2c_pca_pf_writebyte16(void *pd, int reg, int val)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	iowrite8(val, i2c->reg_base + reg * 2);
+}
+
+static void i2c_pca_pf_writebyte32(void *pd, int reg, int val)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	iowrite8(val, i2c->reg_base + reg * 4);
+}
+
+
+static int i2c_pca_pf_waitforcompletion(void *pd)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	int ret = 0;
+
+	if (i2c->irq) {
+		ret = wait_event_interruptible(i2c->wait,
+			i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
+			& I2C_PCA_CON_SI);
+	} else {
+		/*
+		 * Do polling...
+		 * XXX: Could get stuck in extreme cases!
+		 *      Maybe add timeout, but using irqs is preferred anyhow.
+		 */
+		while ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
+				& I2C_PCA_CON_SI) == 0)
+			udelay(100);
+	}
+
+	return ret;
+}
+
+static void i2c_pca_pf_dummyreset(void *pd)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+	printk(KERN_WARNING "%s: No reset-pin found. Chip may get stuck!\n",
+		i2c->adap.name);
+}
+
+static void i2c_pca_pf_resetchip(void *pd)
+{
+	struct i2c_pca_pf_data *i2c = pd;
+
+	gpio_set_value(i2c->gpio, 0);
+	ndelay(100);
+	gpio_set_value(i2c->gpio, 1);
+}
+
+static irqreturn_t i2c_pca_pf_handler(int this_irq, void *dev_id)
+{
+	struct i2c_pca_pf_data *i2c = dev_id;
+
+	if ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)
+		return IRQ_NONE;
+
+	wake_up_interruptible(&i2c->wait);
+
+	return IRQ_HANDLED;
+}
+
+
+static int __devinit i2c_pca_pf_probe(struct platform_device *pdev)
+{
+	struct i2c_pca_pf_data *i2c;
+	struct resource *res;
+	struct i2c_pca9564_pf_platform_data *platform_data =
+				pdev->dev.platform_data;
+	int ret = 0;
+	int irq;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(pdev, 0);
+	/* If irq is 0, we do polling. */
+
+	if (res == NULL) {
+		ret = -ENODEV;
+		goto e_print;
+	}
+
+	if (!request_mem_region(res->start, res_len(res), res->name)) {
+		ret = -ENOMEM;
+		goto e_print;
+	}
+
+	i2c = kzalloc(sizeof(struct i2c_pca_pf_data), GFP_KERNEL);
+	if (!i2c) {
+		ret = -ENOMEM;
+		goto e_alloc;
+	}
+
+	init_waitqueue_head(&i2c->wait);
+
+	i2c->reg_base = ioremap(res->start, res_len(res));
+	if (!i2c->reg_base) {
+		ret = -EIO;
+		goto e_remap;
+	}
+	i2c->io_base = res->start;
+	i2c->io_size = res_len(res);
+	i2c->irq = irq;
+
+	i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0;
+	i2c->adap.owner = THIS_MODULE;
+	snprintf(i2c->adap.name, sizeof(i2c->adap.name), "PCA9564 at 0x%08lx",
+		(unsigned long) res->start);
+	i2c->adap.algo_data = &i2c->algo_data;
+	i2c->adap.dev.parent = &pdev->dev;
+	i2c->adap.timeout = platform_data->timeout;
+
+	i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed;
+	i2c->algo_data.data = i2c;
+
+	switch (res->flags & IORESOURCE_MEM_TYPE_MASK) {
+	case IORESOURCE_MEM_32BIT:
+		i2c->algo_data.write_byte = i2c_pca_pf_writebyte32;
+		i2c->algo_data.read_byte = i2c_pca_pf_readbyte32;
+		break;
+	case IORESOURCE_MEM_16BIT:
+		i2c->algo_data.write_byte = i2c_pca_pf_writebyte16;
+		i2c->algo_data.read_byte = i2c_pca_pf_readbyte16;
+		break;
+	case IORESOURCE_MEM_8BIT:
+	default:
+		i2c->algo_data.write_byte = i2c_pca_pf_writebyte8;
+		i2c->algo_data.read_byte = i2c_pca_pf_readbyte8;
+		break;
+	}
+
+	i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion;
+
+	i2c->gpio = platform_data->gpio;
+	i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset;
+
+	/* Use gpio_is_valid() when in mainline */
+	if (i2c->gpio > -1) {
+		ret = gpio_request(i2c->gpio, i2c->adap.name);
+		if (ret == 0) {
+			gpio_direction_output(i2c->gpio, 1);
+			i2c->algo_data.reset_chip = i2c_pca_pf_resetchip;
+		} else {
+			printk(KERN_WARNING "%s: Registering gpio failed!\n",
+				i2c->adap.name);
+			i2c->gpio = ret;
+		}
+	}
+
+	if (irq) {
+		ret = request_irq(irq, i2c_pca_pf_handler,
+			IRQF_TRIGGER_FALLING, i2c->adap.name, i2c);
+		if (ret)
+			goto e_reqirq;
+	}
+
+	if (i2c_pca_add_numbered_bus(&i2c->adap) < 0) {
+		ret = -ENODEV;
+		goto e_adapt;
+	}
+
+	platform_set_drvdata(pdev, i2c);
+
+	printk(KERN_INFO "%s registered.\n", i2c->adap.name);
+
+	return 0;
+
+e_adapt:
+	if (irq)
+		free_irq(irq, i2c);
+e_reqirq:
+	if (i2c->gpio > -1)
+		gpio_free(i2c->gpio);
+
+	iounmap(i2c->reg_base);
+e_remap:
+	kfree(i2c);
+e_alloc:
+	release_mem_region(res->start, res_len(res));
+e_print:
+	printk(KERN_ERR "Registering PCA9564 FAILED! (%d)\n", ret);
+	return ret;
+}
+
+static int __devexit i2c_pca_pf_remove(struct platform_device *pdev)
+{
+	struct i2c_pca_pf_data *i2c = platform_get_drvdata(pdev);
+	platform_set_drvdata(pdev, NULL);
+
+	i2c_del_adapter(&i2c->adap);
+
+	if (i2c->irq)
+		free_irq(i2c->irq, i2c);
+
+	if (i2c->gpio > -1)
+		gpio_free(i2c->gpio);
+
+	iounmap(i2c->reg_base);
+	release_mem_region(i2c->io_base, i2c->io_size);
+	kfree(i2c);
+
+	return 0;
+}
+
+static struct platform_driver i2c_pca_pf_driver = {
+	.probe = i2c_pca_pf_probe,
+	.remove = __devexit_p(i2c_pca_pf_remove),
+	.driver = {
+		.name = "i2c-pca-platform",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init i2c_pca_pf_init(void)
+{
+	return platform_driver_register(&i2c_pca_pf_driver);
+}
+
+static void __exit i2c_pca_pf_exit(void)
+{
+	platform_driver_unregister(&i2c_pca_pf_driver);
+}
+
+MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
+MODULE_DESCRIPTION("I2C-PCA9564 platform driver");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_pca_pf_init);
+module_exit(i2c_pca_pf_exit);
+

+ 5 - 2
drivers/i2c/busses/i2c-pmcmsp.c

@@ -467,7 +467,7 @@ static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd(
 	    (cmd->read_len == 0 || cmd->write_len == 0))) {
 		dev_err(&pmcmsptwi_adapter.dev,
 			"%s: Cannot transfer less than 1 byte\n",
-			__FUNCTION__);
+			__func__);
 		return -EINVAL;
 	}
 
@@ -475,7 +475,7 @@ static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd(
 	    cmd->write_len > MSP_MAX_BYTES_PER_RW) {
 		dev_err(&pmcmsptwi_adapter.dev,
 			"%s: Cannot transfer more than %d bytes\n",
-			__FUNCTION__, MSP_MAX_BYTES_PER_RW);
+			__func__, MSP_MAX_BYTES_PER_RW);
 		return -EINVAL;
 	}
 
@@ -627,6 +627,9 @@ static struct i2c_adapter pmcmsptwi_adapter = {
 	.name		= DRV_NAME,
 };
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:" DRV_NAME);
+
 static struct platform_driver pmcmsptwi_driver = {
 	.probe  = pmcmsptwi_probe,
 	.remove	= __devexit_p(pmcmsptwi_remove),

+ 23 - 22
drivers/i2c/busses/i2c-pnx.c

@@ -76,7 +76,7 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap)
 {
 	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
 
-	dev_dbg(&adap->dev, "%s(): addr 0x%x mode %d\n", __FUNCTION__,
+	dev_dbg(&adap->dev, "%s(): addr 0x%x mode %d\n", __func__,
 		slave_addr, alg_data->mif.mode);
 
 	/* Check for 7 bit slave addresses only */
@@ -110,14 +110,14 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap)
 	iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi,
 		  I2C_REG_STS(alg_data));
 
-	dev_dbg(&adap->dev, "%s(): sending %#x\n", __FUNCTION__,
+	dev_dbg(&adap->dev, "%s(): sending %#x\n", __func__,
 		(slave_addr << 1) | start_bit | alg_data->mif.mode);
 
 	/* Write the slave address, START bit and R/W bit */
 	iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode,
 		  I2C_REG_TX(alg_data));
 
-	dev_dbg(&adap->dev, "%s(): exit\n", __FUNCTION__);
+	dev_dbg(&adap->dev, "%s(): exit\n", __func__);
 
 	return 0;
 }
@@ -135,7 +135,7 @@ static void i2c_pnx_stop(struct i2c_adapter *adap)
 	long timeout = 1000;
 
 	dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
-		__FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 	/* Write a STOP bit to TX FIFO */
 	iowrite32(0xff | stop_bit, I2C_REG_TX(alg_data));
@@ -149,7 +149,7 @@ static void i2c_pnx_stop(struct i2c_adapter *adap)
 	}
 
 	dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
-		__FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+		__func__, ioread32(I2C_REG_STS(alg_data)));
 }
 
 /**
@@ -164,7 +164,7 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
 	u32 val;
 
 	dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
-		__FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 	if (alg_data->mif.len > 0) {
 		/* We still have something to talk about... */
@@ -179,7 +179,7 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
 		alg_data->mif.len--;
 		iowrite32(val, I2C_REG_TX(alg_data));
 
-		dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __FUNCTION__,
+		dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __func__,
 			val, alg_data->mif.len + 1);
 
 		if (alg_data->mif.len == 0) {
@@ -197,7 +197,7 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
 			del_timer_sync(&alg_data->mif.timer);
 
 			dev_dbg(&adap->dev, "%s(): Waking up xfer routine.\n",
-				__FUNCTION__);
+				__func__);
 
 			complete(&alg_data->mif.complete);
 		}
@@ -213,13 +213,13 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
 		/* Stop timer. */
 		del_timer_sync(&alg_data->mif.timer);
 		dev_dbg(&adap->dev, "%s(): Waking up xfer routine after "
-			"zero-xfer.\n", __FUNCTION__);
+			"zero-xfer.\n", __func__);
 
 		complete(&alg_data->mif.complete);
 	}
 
 	dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
-		__FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 	return 0;
 }
@@ -237,14 +237,14 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
 	u32 ctl = 0;
 
 	dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
-		__FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 	/* Check, whether there is already data,
 	 * or we didn't 'ask' for it yet.
 	 */
 	if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) {
 		dev_dbg(&adap->dev, "%s(): Write dummy data to fill "
-			"Rx-fifo...\n", __FUNCTION__);
+			"Rx-fifo...\n", __func__);
 
 		if (alg_data->mif.len == 1) {
 			/* Last byte, do not acknowledge next rcv. */
@@ -276,7 +276,7 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
 	if (alg_data->mif.len > 0) {
 		val = ioread32(I2C_REG_RX(alg_data));
 		*alg_data->mif.buf++ = (u8) (val & 0xff);
-		dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __FUNCTION__, val,
+		dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __func__, val,
 			alg_data->mif.len);
 
 		alg_data->mif.len--;
@@ -300,7 +300,7 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
 	}
 
 	dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
-		__FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 	return 0;
 }
@@ -312,7 +312,7 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
 	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
 
 	dev_dbg(&adap->dev, "%s(): mstat = %x mctrl = %x, mode = %d\n",
-		__FUNCTION__,
+		__func__,
 		ioread32(I2C_REG_STS(alg_data)),
 		ioread32(I2C_REG_CTL(alg_data)),
 		alg_data->mif.mode);
@@ -336,7 +336,7 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
 		/* Slave did not acknowledge, generate a STOP */
 		dev_dbg(&adap->dev, "%s(): "
 			"Slave did not acknowledge, generating a STOP.\n",
-			__FUNCTION__);
+			__func__);
 		i2c_pnx_stop(adap);
 
 		/* Disable master interrupts. */
@@ -375,7 +375,7 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
 	iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data));
 
 	dev_dbg(&adap->dev, "%s(): exiting, stat = %x ctrl = %x.\n",
-		 __FUNCTION__, ioread32(I2C_REG_STS(alg_data)),
+		 __func__, ioread32(I2C_REG_STS(alg_data)),
 		 ioread32(I2C_REG_CTL(alg_data)));
 
 	return IRQ_HANDLED;
@@ -447,7 +447,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 	u32 stat = ioread32(I2C_REG_STS(alg_data));
 
 	dev_dbg(&adap->dev, "%s(): entering: %d messages, stat = %04x.\n",
-		__FUNCTION__, num, ioread32(I2C_REG_STS(alg_data)));
+		__func__, num, ioread32(I2C_REG_STS(alg_data)));
 
 	bus_reset_if_active(adap);
 
@@ -473,7 +473,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 		alg_data->mif.ret = 0;
 		alg_data->last = (i == num - 1);
 
-		dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __FUNCTION__,
+		dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __func__,
 			alg_data->mif.mode,
 			alg_data->mif.len);
 
@@ -498,7 +498,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 		if (!(rc = alg_data->mif.ret))
 			completed++;
 		dev_dbg(&adap->dev, "%s(): Complete, return code = %d.\n",
-			__FUNCTION__, rc);
+			__func__, rc);
 
 		/* Clear TDI and AFI bits in case they are set. */
 		if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) {
@@ -522,7 +522,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 	alg_data->mif.len = 0;
 
 	dev_dbg(&adap->dev, "%s(): exiting, stat = %x\n",
-		__FUNCTION__, ioread32(I2C_REG_STS(alg_data)));
+		__func__, ioread32(I2C_REG_STS(alg_data)));
 
 	if (completed != num)
 		return ((rc < 0) ? rc : -EREMOTEIO);
@@ -563,7 +563,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev)
 
 	if (!i2c_pnx || !i2c_pnx->adapter) {
 		dev_err(&pdev->dev, "%s: no platform data supplied\n",
-		       __FUNCTION__);
+		       __func__);
 		ret = -EINVAL;
 		goto out;
 	}
@@ -697,6 +697,7 @@ static void __exit i2c_adap_pnx_exit(void)
 MODULE_AUTHOR("Vitaly Wool, Dennis Kovalev <source@mvista.com>");
 MODULE_DESCRIPTION("I2C driver for Philips IP3204-based I2C busses");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pnx-i2c");
 
 /* We need to make sure I2C is initialized before USB */
 subsys_initcall(i2c_adap_pnx_init);

+ 3 - 0
drivers/i2c/busses/i2c-powermac.c

@@ -263,6 +263,9 @@ static int __devexit i2c_powermac_probe(struct platform_device *dev)
 }
 
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:i2c-powermac");
+
 static struct platform_driver i2c_powermac_driver = {
 	.probe = i2c_powermac_probe,
 	.remove = __devexit_p(i2c_powermac_remove),

+ 2 - 1
drivers/i2c/busses/i2c-pxa.c

@@ -155,7 +155,7 @@ static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname)
 		readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
 }
 
-#define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __FUNCTION__)
+#define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __func__)
 #else
 #define i2c_debug	0
 
@@ -1132,6 +1132,7 @@ static void __exit i2c_adap_pxa_exit(void)
 }
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pxa2xx-i2c");
 
 module_init(i2c_adap_pxa_init);
 module_exit(i2c_adap_pxa_exit);

+ 3 - 2
drivers/i2c/busses/i2c-s3c2410.c

@@ -276,12 +276,12 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
 	switch (i2c->state) {
 
 	case STATE_IDLE:
-		dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __FUNCTION__);
+		dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__);
 		goto out;
 		break;
 
 	case STATE_STOP:
-		dev_err(i2c->dev, "%s: called in STATE_STOP\n", __FUNCTION__);
+		dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__);
 		s3c24xx_i2c_disable_irq(i2c);		
 		goto out_ack;
 
@@ -948,3 +948,4 @@ module_exit(i2c_adap_s3c_exit);
 MODULE_DESCRIPTION("S3C24XX I2C Bus driver");
 MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:s3c2410-i2c");

+ 577 - 0
drivers/i2c/busses/i2c-sh7760.c

@@ -0,0 +1,577 @@
+/*
+ * I2C bus driver for the SH7760 I2C Interfaces.
+ *
+ * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss <mlau@msc-ge.com>
+ *
+ * licensed under the terms outlined in the file COPYING.
+ *
+ */
+
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <asm/clock.h>
+#include <asm/i2c-sh7760.h>
+#include <asm/io.h>
+
+/* register offsets */
+#define I2CSCR		0x0		/* slave ctrl		*/
+#define I2CMCR		0x4		/* master ctrl		*/
+#define I2CSSR		0x8		/* slave status		*/
+#define I2CMSR		0xC		/* master status	*/
+#define I2CSIER		0x10		/* slave irq enable	*/
+#define I2CMIER		0x14		/* master irq enable	*/
+#define I2CCCR		0x18		/* clock dividers	*/
+#define I2CSAR		0x1c		/* slave address	*/
+#define I2CMAR		0x20		/* master address	*/
+#define I2CRXTX		0x24		/* data port		*/
+#define I2CFCR		0x28		/* fifo control		*/
+#define I2CFSR		0x2C		/* fifo status		*/
+#define I2CFIER		0x30		/* fifo irq enable	*/
+#define I2CRFDR		0x34		/* rx fifo count	*/
+#define I2CTFDR		0x38		/* tx fifo count	*/
+
+#define REGSIZE		0x3C
+
+#define MCR_MDBS	0x80		/* non-fifo mode switch	*/
+#define MCR_FSCL	0x40		/* override SCL pin	*/
+#define MCR_FSDA	0x20		/* override SDA pin	*/
+#define MCR_OBPC	0x10		/* override pins	*/
+#define MCR_MIE		0x08		/* master if enable	*/
+#define MCR_TSBE	0x04
+#define MCR_FSB		0x02		/* force stop bit	*/
+#define MCR_ESG		0x01		/* en startbit gen.	*/
+
+#define MSR_MNR		0x40		/* nack received	*/
+#define MSR_MAL		0x20		/* arbitration lost	*/
+#define MSR_MST		0x10		/* sent a stop		*/
+#define MSR_MDE		0x08
+#define MSR_MDT		0x04
+#define MSR_MDR		0x02
+#define MSR_MAT		0x01		/* slave addr xfer done	*/
+
+#define MIE_MNRE	0x40		/* nack irq en		*/
+#define MIE_MALE	0x20		/* arblos irq en	*/
+#define MIE_MSTE	0x10		/* stop irq en		*/
+#define MIE_MDEE	0x08
+#define MIE_MDTE	0x04
+#define MIE_MDRE	0x02
+#define MIE_MATE	0x01		/* address sent irq en	*/
+
+#define FCR_RFRST	0x02		/* reset rx fifo	*/
+#define FCR_TFRST	0x01		/* reset tx fifo	*/
+
+#define FSR_TEND	0x04		/* last byte sent	*/
+#define FSR_RDF		0x02		/* rx fifo trigger	*/
+#define FSR_TDFE	0x01		/* tx fifo empty	*/
+
+#define FIER_TEIE	0x04		/* tx fifo empty irq en	*/
+#define FIER_RXIE	0x02		/* rx fifo trig irq en	*/
+#define FIER_TXIE	0x01		/* tx fifo trig irq en	*/
+
+#define FIFO_SIZE	16
+
+struct cami2c {
+	void __iomem *iobase;
+	struct i2c_adapter adap;
+
+	/* message processing */
+	struct i2c_msg	*msg;
+#define IDF_SEND	1
+#define IDF_RECV	2
+#define IDF_STOP	4
+	int		flags;
+
+#define IDS_DONE	1
+#define IDS_ARBLOST	2
+#define IDS_NACK	4
+	int		status;
+	struct completion xfer_done;
+
+	int irq;
+	struct resource *ioarea;
+};
+
+static inline void OUT32(struct cami2c *cam, int reg, unsigned long val)
+{
+	ctrl_outl(val, (unsigned long)cam->iobase + reg);
+}
+
+static inline unsigned long IN32(struct cami2c *cam, int reg)
+{
+	return ctrl_inl((unsigned long)cam->iobase + reg);
+}
+
+static irqreturn_t sh7760_i2c_irq(int irq, void *ptr)
+{
+	struct cami2c *id = ptr;
+	struct i2c_msg *msg = id->msg;
+	char *data = msg->buf;
+	unsigned long msr, fsr, fier, len;
+
+	msr = IN32(id, I2CMSR);
+	fsr = IN32(id, I2CFSR);
+
+	/* arbitration lost */
+	if (msr & MSR_MAL) {
+		OUT32(id, I2CMCR, 0);
+		OUT32(id, I2CSCR, 0);
+		OUT32(id, I2CSAR, 0);
+		id->status |= IDS_DONE | IDS_ARBLOST;
+		goto out;
+	}
+
+	if (msr & MSR_MNR) {
+		/* NACK handling is very screwed up.  After receiving a
+		 * NAK IRQ one has to wait a bit  before writing to any
+		 * registers, or the ctl will lock up. After that delay
+		 * do a normal i2c stop. Then wait at least 1 ms before
+		 * attempting another transfer or ctl will stop working
+		 */
+		udelay(100);	/* wait or risk ctl hang */
+		OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
+		OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
+		OUT32(id, I2CFIER, 0);
+		OUT32(id, I2CMIER, MIE_MSTE);
+		OUT32(id, I2CSCR, 0);
+		OUT32(id, I2CSAR, 0);
+		id->status |= IDS_NACK;
+		msr &= ~MSR_MAT;
+		fsr = 0;
+		/* In some cases the MST bit is also set. */
+	}
+
+	/* i2c-stop was sent */
+	if (msr & MSR_MST) {
+		id->status |= IDS_DONE;
+		goto out;
+	}
+
+	/* i2c slave addr was sent; set to "normal" operation */
+	if (msr & MSR_MAT)
+		OUT32(id, I2CMCR, MCR_MIE);
+
+	fier = IN32(id, I2CFIER);
+
+	if (fsr & FSR_RDF) {
+		len = IN32(id, I2CRFDR);
+		if (msg->len <= len) {
+			if (id->flags & IDF_STOP) {
+				OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
+				OUT32(id, I2CFIER, 0);
+				/* manual says: wait >= 0.5 SCL times */
+				udelay(5);
+				/* next int should be MST */
+			} else {
+				id->status |= IDS_DONE;
+				/* keep the RDF bit: ctrl holds SCL low
+				 * until the setup for the next i2c_msg
+				 * clears this bit.
+				 */
+				fsr &= ~FSR_RDF;
+			}
+		}
+		while (msg->len && len) {
+			*data++ = IN32(id, I2CRXTX);
+			msg->len--;
+			len--;
+		}
+
+		if (msg->len) {
+			len = (msg->len >= FIFO_SIZE) ? FIFO_SIZE - 1
+						      : msg->len - 1;
+
+			OUT32(id, I2CFCR, FCR_TFRST | ((len & 0xf) << 4));
+		}
+
+	} else if (id->flags & IDF_SEND) {
+		if ((fsr & FSR_TEND) && (msg->len < 1)) {
+			if (id->flags & IDF_STOP) {
+				OUT32(id, I2CMCR, MCR_MIE | MCR_FSB);
+			} else {
+				id->status |= IDS_DONE;
+				/* keep the TEND bit: ctl holds SCL low
+				 * until the setup for the next i2c_msg
+				 * clears this bit.
+				 */
+				fsr &= ~FSR_TEND;
+			}
+		}
+		if (fsr & FSR_TDFE) {
+			while (msg->len && (IN32(id, I2CTFDR) < FIFO_SIZE)) {
+				OUT32(id, I2CRXTX, *data++);
+				msg->len--;
+			}
+
+			if (msg->len < 1) {
+				fier &= ~FIER_TXIE;
+				OUT32(id, I2CFIER, fier);
+			} else {
+				len = (msg->len >= FIFO_SIZE) ? 2 : 0;
+				OUT32(id, I2CFCR,
+					  FCR_RFRST | ((len & 3) << 2));
+			}
+		}
+	}
+out:
+	if (id->status & IDS_DONE) {
+		OUT32(id, I2CMIER, 0);
+		OUT32(id, I2CFIER, 0);
+		id->msg = NULL;
+		complete(&id->xfer_done);
+	}
+	/* clear status flags and ctrl resumes work */
+	OUT32(id, I2CMSR, ~msr);
+	OUT32(id, I2CFSR, ~fsr);
+	OUT32(id, I2CSSR, 0);
+
+	return IRQ_HANDLED;
+}
+
+
+/* prepare and start a master receive operation */
+static void sh7760_i2c_mrecv(struct cami2c *id)
+{
+	int len;
+
+	id->flags |= IDF_RECV;
+
+	/* set the slave addr reg; otherwise rcv wont work! */
+	OUT32(id, I2CSAR, 0xfe);
+	OUT32(id, I2CMAR, (id->msg->addr << 1) | 1);
+
+	/* adjust rx fifo trigger */
+	if (id->msg->len >= FIFO_SIZE)
+		len = FIFO_SIZE - 1;	/* trigger at fifo full */
+	else
+		len = id->msg->len - 1;	/* trigger before all received */
+
+	OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
+	OUT32(id, I2CFCR, FCR_TFRST | ((len & 0xF) << 4));
+
+	OUT32(id, I2CMSR, 0);
+	OUT32(id, I2CMCR, MCR_MIE | MCR_ESG);
+	OUT32(id, I2CMIER, MIE_MNRE | MIE_MALE | MIE_MSTE | MIE_MATE);
+	OUT32(id, I2CFIER, FIER_RXIE);
+}
+
+/* prepare and start a master send operation */
+static void sh7760_i2c_msend(struct cami2c *id)
+{
+	int len;
+
+	id->flags |= IDF_SEND;
+
+	/* set the slave addr reg; otherwise xmit wont work! */
+	OUT32(id, I2CSAR, 0xfe);
+	OUT32(id, I2CMAR, (id->msg->addr << 1) | 0);
+
+	/* adjust tx fifo trigger */
+	if (id->msg->len >= FIFO_SIZE)
+		len = 2;	/* trig: 2 bytes left in TX fifo */
+	else
+		len = 0;	/* trig: 8 bytes left in TX fifo */
+
+	OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
+	OUT32(id, I2CFCR, FCR_RFRST | ((len & 3) << 2));
+
+	while (id->msg->len && IN32(id, I2CTFDR) < FIFO_SIZE) {
+		OUT32(id, I2CRXTX, *(id->msg->buf));
+		(id->msg->len)--;
+		(id->msg->buf)++;
+	}
+
+	OUT32(id, I2CMSR, 0);
+	OUT32(id, I2CMCR, MCR_MIE | MCR_ESG);
+	OUT32(id, I2CFSR, 0);
+	OUT32(id, I2CMIER, MIE_MNRE | MIE_MALE | MIE_MSTE | MIE_MATE);
+	OUT32(id, I2CFIER, FIER_TEIE | (id->msg->len ? FIER_TXIE : 0));
+}
+
+static inline int sh7760_i2c_busy_check(struct cami2c *id)
+{
+	return (IN32(id, I2CMCR) & MCR_FSDA);
+}
+
+static int sh7760_i2c_master_xfer(struct i2c_adapter *adap,
+				  struct i2c_msg *msgs,
+				  int num)
+{
+	struct cami2c *id = adap->algo_data;
+	int i, retr;
+
+	if (sh7760_i2c_busy_check(id)) {
+		dev_err(&adap->dev, "sh7760-i2c%d: bus busy!\n", adap->nr);
+		return -EBUSY;
+	}
+
+	i = 0;
+	while (i < num) {
+		retr = adap->retries;
+retry:
+		id->flags = ((i == (num-1)) ? IDF_STOP : 0);
+		id->status = 0;
+		id->msg = msgs;
+		init_completion(&id->xfer_done);
+
+		if (msgs->flags & I2C_M_RD)
+			sh7760_i2c_mrecv(id);
+		else
+			sh7760_i2c_msend(id);
+
+		wait_for_completion(&id->xfer_done);
+
+		if (id->status == 0) {
+			num = -EIO;
+			break;
+		}
+
+		if (id->status & IDS_NACK) {
+			/* wait a bit or i2c module stops working */
+			mdelay(1);
+			num = -EREMOTEIO;
+			break;
+		}
+
+		if (id->status & IDS_ARBLOST) {
+			if (retr--) {
+				mdelay(2);
+				goto retry;
+			}
+			num = -EREMOTEIO;
+			break;
+		}
+
+		msgs++;
+		i++;
+	}
+
+	id->msg = NULL;
+	id->flags = 0;
+	id->status = 0;
+
+	OUT32(id, I2CMCR, 0);
+	OUT32(id, I2CMSR, 0);
+	OUT32(id, I2CMIER, 0);
+	OUT32(id, I2CFIER, 0);
+
+	/* reset slave module registers too: master mode enables slave
+	 * module for receive ops (ack, data). Without this reset,
+	 * eternal bus activity might be reported after NACK / ARBLOST.
+	 */
+	OUT32(id, I2CSCR, 0);
+	OUT32(id, I2CSAR, 0);
+	OUT32(id, I2CSSR, 0);
+
+	return num;
+}
+
+static u32 sh7760_i2c_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
+}
+
+static const struct i2c_algorithm sh7760_i2c_algo = {
+	.master_xfer	= sh7760_i2c_master_xfer,
+	.functionality	= sh7760_i2c_func,
+};
+
+/* calculate CCR register setting for a desired scl clock.  SCL clock is
+ * derived from I2C module clock  (iclk)  which in turn is derived from
+ * peripheral module clock (mclk, usually around 33MHz):
+ * iclk = mclk/(CDF + 1).  iclk must be < 20MHz.
+ * scl = iclk/(SCGD*8 + 20).
+ */
+static int __devinit calc_CCR(unsigned long scl_hz)
+{
+	struct clk *mclk;
+	unsigned long mck, m1, dff, odff, iclk;
+	signed char cdf, cdfm;
+	int scgd, scgdm, scgds;
+
+	mclk = clk_get(NULL, "module_clk");
+	if (IS_ERR(mclk)) {
+		return PTR_ERR(mclk);
+	} else {
+		mck = mclk->rate;
+		clk_put(mclk);
+	}
+
+	odff = scl_hz;
+	scgdm = cdfm = m1 = 0;
+	for (cdf = 3; cdf >= 0; cdf--) {
+		iclk = mck / (1 + cdf);
+		if (iclk >= 20000000)
+			continue;
+		scgds = ((iclk / scl_hz) - 20) >> 3;
+		for (scgd = scgds; (scgd < 63) && scgd <= scgds + 1; scgd++) {
+			m1 = iclk / (20 + (scgd << 3));
+			dff = abs(scl_hz - m1);
+			if (dff < odff) {
+				odff = dff;
+				cdfm = cdf;
+				scgdm = scgd;
+			}
+		}
+	}
+	/* fail if more than 25% off of requested SCL */
+	if (odff > (scl_hz >> 2))
+		return -EINVAL;
+
+	/* create a CCR register value */
+	return ((scgdm << 2) | cdfm);
+}
+
+static int __devinit sh7760_i2c_probe(struct platform_device *pdev)
+{
+	struct sh7760_i2c_platdata *pd;
+	struct resource *res;
+	struct cami2c *id;
+	int ret;
+
+	pd = pdev->dev.platform_data;
+	if (!pd) {
+		dev_err(&pdev->dev, "no platform_data!\n");
+		ret = -ENODEV;
+		goto out0;
+	}
+
+	id = kzalloc(sizeof(struct cami2c), GFP_KERNEL);
+	if (!id) {
+		dev_err(&pdev->dev, "no mem for private data\n");
+		ret = -ENOMEM;
+		goto out0;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "no mmio resources\n");
+		ret = -ENODEV;
+		goto out1;
+	}
+
+	id->ioarea = request_mem_region(res->start, REGSIZE, pdev->name);
+	if (!id->ioarea) {
+		dev_err(&pdev->dev, "mmio already reserved\n");
+		ret = -EBUSY;
+		goto out1;
+	}
+
+	id->iobase = ioremap(res->start, REGSIZE);
+	if (!id->iobase) {
+		dev_err(&pdev->dev, "cannot ioremap\n");
+		ret = -ENODEV;
+		goto out2;
+	}
+
+	id->irq = platform_get_irq(pdev, 0);
+
+	id->adap.nr = pdev->id;
+	id->adap.algo = &sh7760_i2c_algo;
+	id->adap.class = I2C_CLASS_ALL;
+	id->adap.retries = 3;
+	id->adap.algo_data = id;
+	id->adap.dev.parent = &pdev->dev;
+	snprintf(id->adap.name, sizeof(id->adap.name),
+		"SH7760 I2C at %08lx", (unsigned long)res->start);
+
+	OUT32(id, I2CMCR, 0);
+	OUT32(id, I2CMSR, 0);
+	OUT32(id, I2CMIER, 0);
+	OUT32(id, I2CMAR, 0);
+	OUT32(id, I2CSIER, 0);
+	OUT32(id, I2CSAR, 0);
+	OUT32(id, I2CSCR, 0);
+	OUT32(id, I2CSSR, 0);
+	OUT32(id, I2CFIER, 0);
+	OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST);
+	OUT32(id, I2CFSR, 0);
+
+	ret = calc_CCR(pd->speed_khz * 1000);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "invalid SCL clock: %dkHz\n",
+			pd->speed_khz);
+		goto out3;
+	}
+	OUT32(id, I2CCCR, ret);
+
+	if (request_irq(id->irq, sh7760_i2c_irq, IRQF_DISABLED,
+			SH7760_I2C_DEVNAME, id)) {
+		dev_err(&pdev->dev, "cannot get irq %d\n", id->irq);
+		ret = -EBUSY;
+		goto out3;
+	}
+
+	ret = i2c_add_numbered_adapter(&id->adap);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "reg adap failed: %d\n", ret);
+		goto out4;
+	}
+
+	platform_set_drvdata(pdev, id);
+
+	dev_info(&pdev->dev, "%d kHz mmio %08x irq %d\n",
+		 pd->speed_khz, res->start, id->irq);
+
+	return 0;
+
+out4:
+	free_irq(id->irq, id);
+out3:
+	iounmap(id->iobase);
+out2:
+	release_resource(id->ioarea);
+	kfree(id->ioarea);
+out1:
+	kfree(id);
+out0:
+	return ret;
+}
+
+static int __devexit sh7760_i2c_remove(struct platform_device *pdev)
+{
+	struct cami2c *id = platform_get_drvdata(pdev);
+
+	i2c_del_adapter(&id->adap);
+	free_irq(id->irq, id);
+	iounmap(id->iobase);
+	release_resource(id->ioarea);
+	kfree(id->ioarea);
+	kfree(id);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver sh7760_i2c_drv = {
+	.driver	= {
+		.name	= SH7760_I2C_DEVNAME,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= sh7760_i2c_probe,
+	.remove		= __devexit_p(sh7760_i2c_remove),
+};
+
+static int __init sh7760_i2c_init(void)
+{
+	return platform_driver_register(&sh7760_i2c_drv);
+}
+
+static void __exit sh7760_i2c_exit(void)
+{
+	platform_driver_unregister(&sh7760_i2c_drv);
+}
+
+module_init(sh7760_i2c_init);
+module_exit(sh7760_i2c_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SH7760 I2C bus driver");
+MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");

+ 500 - 0
drivers/i2c/busses/i2c-sh_mobile.c

@@ -0,0 +1,500 @@
+/*
+ * SuperH Mobile I2C Controller
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * Portions of the code based on out-of-tree driver i2c-sh7343.c
+ * Copyright (c) 2006 Carlos Munoz <carlos@kenati.com>
+ *
+ * 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
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+enum sh_mobile_i2c_op {
+	OP_START = 0,
+	OP_TX_ONLY,
+	OP_TX_STOP,
+	OP_TX_TO_RX,
+	OP_RX_ONLY,
+	OP_RX_STOP,
+};
+
+struct sh_mobile_i2c_data {
+	struct device *dev;
+	void __iomem *reg;
+	struct i2c_adapter adap;
+
+	struct clk *clk;
+	u_int8_t iccl;
+	u_int8_t icch;
+
+	spinlock_t lock;
+	wait_queue_head_t wait;
+	struct i2c_msg *msg;
+	int pos;
+	int sr;
+};
+
+#define NORMAL_SPEED		100000 /* FAST_SPEED 400000 */
+
+/* Register offsets */
+#define ICDR(pd)		(pd->reg + 0x00)
+#define ICCR(pd)		(pd->reg + 0x04)
+#define ICSR(pd)		(pd->reg + 0x08)
+#define ICIC(pd)		(pd->reg + 0x0c)
+#define ICCL(pd)		(pd->reg + 0x10)
+#define ICCH(pd)		(pd->reg + 0x14)
+
+/* Register bits */
+#define ICCR_ICE		0x80
+#define ICCR_RACK		0x40
+#define ICCR_TRS		0x10
+#define ICCR_BBSY		0x04
+#define ICCR_SCP		0x01
+
+#define ICSR_SCLM		0x80
+#define ICSR_SDAM		0x40
+#define SW_DONE			0x20
+#define ICSR_BUSY		0x10
+#define ICSR_AL			0x08
+#define ICSR_TACK		0x04
+#define ICSR_WAIT		0x02
+#define ICSR_DTE		0x01
+
+#define ICIC_ALE		0x08
+#define ICIC_TACKE		0x04
+#define ICIC_WAITE		0x02
+#define ICIC_DTEE		0x01
+
+static void activate_ch(struct sh_mobile_i2c_data *pd)
+{
+	/* Make sure the clock is enabled */
+	clk_enable(pd->clk);
+
+	/* Enable channel and configure rx ack */
+	iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd));
+
+	/* Mask all interrupts */
+	iowrite8(0, ICIC(pd));
+
+	/* Set the clock */
+	iowrite8(pd->iccl, ICCL(pd));
+	iowrite8(pd->icch, ICCH(pd));
+}
+
+static void deactivate_ch(struct sh_mobile_i2c_data *pd)
+{
+	/* Clear/disable interrupts */
+	iowrite8(0, ICSR(pd));
+	iowrite8(0, ICIC(pd));
+
+	/* Disable channel */
+	iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd));
+
+	/* Disable clock */
+	clk_disable(pd->clk);
+}
+
+static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
+			    enum sh_mobile_i2c_op op, unsigned char data)
+{
+	unsigned char ret = 0;
+	unsigned long flags;
+
+	dev_dbg(pd->dev, "op %d, data in 0x%02x\n", op, data);
+
+	spin_lock_irqsave(&pd->lock, flags);
+
+	switch (op) {
+	case OP_START:
+		iowrite8(0x94, ICCR(pd));
+		break;
+	case OP_TX_ONLY:
+		iowrite8(data, ICDR(pd));
+		break;
+	case OP_TX_STOP:
+		iowrite8(data, ICDR(pd));
+		iowrite8(0x90, ICCR(pd));
+		iowrite8(ICIC_ALE | ICIC_TACKE, ICIC(pd));
+		break;
+	case OP_TX_TO_RX:
+		iowrite8(data, ICDR(pd));
+		iowrite8(0x81, ICCR(pd));
+		break;
+	case OP_RX_ONLY:
+		ret = ioread8(ICDR(pd));
+		break;
+	case OP_RX_STOP:
+		ret = ioread8(ICDR(pd));
+		iowrite8(0xc0, ICCR(pd));
+		break;
+	}
+
+	spin_unlock_irqrestore(&pd->lock, flags);
+
+	dev_dbg(pd->dev, "op %d, data out 0x%02x\n", op, ret);
+	return ret;
+}
+
+static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
+{
+	struct platform_device *dev = dev_id;
+	struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);
+	struct i2c_msg *msg = pd->msg;
+	unsigned char data, sr;
+	int wakeup = 0;
+
+	sr = ioread8(ICSR(pd));
+	pd->sr |= sr;
+
+	dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr,
+	       (msg->flags & I2C_M_RD) ? "read" : "write",
+	       pd->pos, msg->len);
+
+	if (sr & (ICSR_AL | ICSR_TACK)) {
+		iowrite8(0, ICIC(pd)); /* disable interrupts */
+		wakeup = 1;
+		goto do_wakeup;
+	}
+
+	if (pd->pos == msg->len) {
+		i2c_op(pd, OP_RX_ONLY, 0);
+		wakeup = 1;
+		goto do_wakeup;
+	}
+
+	if (pd->pos == -1) {
+		data = (msg->addr & 0x7f) << 1;
+		data |= (msg->flags & I2C_M_RD) ? 1 : 0;
+	} else
+		data = msg->buf[pd->pos];
+
+	if ((pd->pos == -1) || !(msg->flags & I2C_M_RD)) {
+		if (msg->flags & I2C_M_RD)
+			i2c_op(pd, OP_TX_TO_RX, data);
+		else if (pd->pos == (msg->len - 1)) {
+			i2c_op(pd, OP_TX_STOP, data);
+			wakeup = 1;
+		} else
+			i2c_op(pd, OP_TX_ONLY, data);
+	} else {
+		if (pd->pos == (msg->len - 1))
+			data = i2c_op(pd, OP_RX_STOP, 0);
+		else
+			data = i2c_op(pd, OP_RX_ONLY, 0);
+
+		msg->buf[pd->pos] = data;
+	}
+	pd->pos++;
+
+ do_wakeup:
+	if (wakeup) {
+		pd->sr |= SW_DONE;
+		wake_up(&pd->wait);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg)
+{
+	/* Initialize channel registers */
+	iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd));
+
+	/* Enable channel and configure rx ack */
+	iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd));
+
+	/* Set the clock */
+	iowrite8(pd->iccl, ICCL(pd));
+	iowrite8(pd->icch, ICCH(pd));
+
+	pd->msg = usr_msg;
+	pd->pos = -1;
+	pd->sr = 0;
+
+	/* Enable all interrupts except wait */
+	iowrite8(ioread8(ICIC(pd)) | ICIC_ALE | ICIC_TACKE | ICIC_DTEE,
+		 ICIC(pd));
+	return 0;
+}
+
+static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
+			      struct i2c_msg *msgs,
+			      int num)
+{
+	struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter);
+	struct i2c_msg	*msg;
+	int err = 0;
+	u_int8_t val;
+	int i, k, retry_count;
+
+	activate_ch(pd);
+
+	/* Process all messages */
+	for (i = 0; i < num; i++) {
+		msg = &msgs[i];
+
+		err = start_ch(pd, msg);
+		if (err)
+			break;
+
+		i2c_op(pd, OP_START, 0);
+
+		/* The interrupt handler takes care of the rest... */
+		k = wait_event_timeout(pd->wait,
+				       pd->sr & (ICSR_TACK | SW_DONE),
+				       5 * HZ);
+		if (!k)
+			dev_err(pd->dev, "Transfer request timed out\n");
+
+		retry_count = 10;
+again:
+		val = ioread8(ICSR(pd));
+
+		dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr);
+
+		if ((val | pd->sr) & (ICSR_TACK | ICSR_AL)) {
+			err = -EIO;
+			break;
+		}
+
+		/* the interrupt handler may wake us up before the
+		 * transfer is finished, so poll the hardware
+		 * until we're done.
+		 */
+
+		if (!(!(val & ICSR_BUSY) && (val & ICSR_SCLM) &&
+		      (val & ICSR_SDAM))) {
+			msleep(1);
+			if (retry_count--)
+				goto again;
+
+			err = -EIO;
+			dev_err(pd->dev, "Polling timed out\n");
+			break;
+		}
+	}
+
+	deactivate_ch(pd);
+
+	if (!err)
+		err = num;
+	return err;
+}
+
+static u32 sh_mobile_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm sh_mobile_i2c_algorithm = {
+	.functionality	= sh_mobile_i2c_func,
+	.master_xfer	= sh_mobile_i2c_xfer,
+};
+
+static void sh_mobile_i2c_setup_channel(struct platform_device *dev)
+{
+	struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);
+	unsigned long peripheral_clk = clk_get_rate(pd->clk);
+	u_int32_t num;
+	u_int32_t denom;
+	u_int32_t tmp;
+
+	spin_lock_init(&pd->lock);
+	init_waitqueue_head(&pd->wait);
+
+	/* Calculate the value for iccl. From the data sheet:
+	 * iccl = (p clock / transfer rate) * (L / (L + H))
+	 * where L and H are the SCL low/high ratio (5/4 in this case).
+	 * We also round off the result.
+	 */
+	num = peripheral_clk * 5;
+	denom = NORMAL_SPEED * 9;
+	tmp = num * 10 / denom;
+	if (tmp % 10 >= 5)
+		pd->iccl = (u_int8_t)((num/denom) + 1);
+	else
+		pd->iccl = (u_int8_t)(num/denom);
+
+	/* Calculate the value for icch. From the data sheet:
+	   icch = (p clock / transfer rate) * (H / (L + H)) */
+	num = peripheral_clk * 4;
+	tmp = num * 10 / denom;
+	if (tmp % 10 >= 5)
+		pd->icch = (u_int8_t)((num/denom) + 1);
+	else
+		pd->icch = (u_int8_t)(num/denom);
+}
+
+static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook)
+{
+	struct resource *res;
+	int ret = -ENXIO;
+	int q, m;
+	int k = 0;
+	int n = 0;
+
+	while ((res = platform_get_resource(dev, IORESOURCE_IRQ, k))) {
+		for (n = res->start; hook && n <= res->end; n++) {
+			if (request_irq(n, sh_mobile_i2c_isr, IRQF_DISABLED,
+					dev->dev.bus_id, dev))
+				goto rollback;
+		}
+		k++;
+	}
+
+	if (hook)
+		return k > 0 ? 0 : -ENOENT;
+
+	k--;
+	ret = 0;
+
+ rollback:
+	for (q = k; k >= 0; k--) {
+		for (m = n; m >= res->start; m--)
+			free_irq(m, dev);
+
+		res = platform_get_resource(dev, IORESOURCE_IRQ, k - 1);
+		m = res->end;
+	}
+
+	return ret;
+}
+
+static int sh_mobile_i2c_probe(struct platform_device *dev)
+{
+	struct sh_mobile_i2c_data *pd;
+	struct i2c_adapter *adap;
+	struct resource *res;
+	int size;
+	int ret;
+
+	pd = kzalloc(sizeof(struct sh_mobile_i2c_data), GFP_KERNEL);
+	if (pd == NULL) {
+		dev_err(&dev->dev, "cannot allocate private data\n");
+		return -ENOMEM;
+	}
+
+	pd->clk = clk_get(&dev->dev, "peripheral_clk");
+	if (IS_ERR(pd->clk)) {
+		dev_err(&dev->dev, "cannot get peripheral clock\n");
+		ret = PTR_ERR(pd->clk);
+		goto err;
+	}
+
+	ret = sh_mobile_i2c_hook_irqs(dev, 1);
+	if (ret) {
+		dev_err(&dev->dev, "cannot request IRQ\n");
+		goto err_clk;
+	}
+
+	pd->dev = &dev->dev;
+	platform_set_drvdata(dev, pd);
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&dev->dev, "cannot find IO resource\n");
+		ret = -ENOENT;
+		goto err_irq;
+	}
+
+	size = (res->end - res->start) + 1;
+
+	pd->reg = ioremap(res->start, size);
+	if (pd->reg == NULL) {
+		dev_err(&dev->dev, "cannot map IO\n");
+		ret = -ENXIO;
+		goto err_irq;
+	}
+
+	/* setup the private data */
+	adap = &pd->adap;
+	i2c_set_adapdata(adap, pd);
+
+	adap->owner = THIS_MODULE;
+	adap->algo = &sh_mobile_i2c_algorithm;
+	adap->dev.parent = &dev->dev;
+	adap->retries = 5;
+	adap->nr = dev->id;
+
+	strlcpy(adap->name, dev->name, sizeof(adap->name));
+
+	sh_mobile_i2c_setup_channel(dev);
+
+	ret = i2c_add_numbered_adapter(adap);
+	if (ret < 0) {
+		dev_err(&dev->dev, "cannot add numbered adapter\n");
+		goto err_all;
+	}
+
+	return 0;
+
+ err_all:
+	iounmap(pd->reg);
+ err_irq:
+	sh_mobile_i2c_hook_irqs(dev, 0);
+ err_clk:
+	clk_put(pd->clk);
+ err:
+	kfree(pd);
+	return ret;
+}
+
+static int sh_mobile_i2c_remove(struct platform_device *dev)
+{
+	struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev);
+
+	i2c_del_adapter(&pd->adap);
+	iounmap(pd->reg);
+	sh_mobile_i2c_hook_irqs(dev, 0);
+	clk_put(pd->clk);
+	kfree(pd);
+	return 0;
+}
+
+static struct platform_driver sh_mobile_i2c_driver = {
+	.driver		= {
+		.name		= "i2c-sh_mobile",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= sh_mobile_i2c_probe,
+	.remove		= sh_mobile_i2c_remove,
+};
+
+static int __init sh_mobile_i2c_adap_init(void)
+{
+	return platform_driver_register(&sh_mobile_i2c_driver);
+}
+
+static void __exit sh_mobile_i2c_adap_exit(void)
+{
+	platform_driver_unregister(&sh_mobile_i2c_driver);
+}
+
+module_init(sh_mobile_i2c_adap_init);
+module_exit(sh_mobile_i2c_adap_exit);
+
+MODULE_DESCRIPTION("SuperH Mobile I2C Bus Controller driver");
+MODULE_AUTHOR("Magnus Damm");
+MODULE_LICENSE("GPL v2");

+ 3 - 0
drivers/i2c/busses/i2c-simtec.c

@@ -159,6 +159,9 @@ static int simtec_i2c_remove(struct platform_device *dev)
 
 /* device driver */
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:simtec-i2c");
+
 static struct platform_driver simtec_i2c_driver = {
 	.driver		= {
 		.name		= "simtec-i2c",

+ 1 - 0
drivers/i2c/busses/i2c-versatile.c

@@ -151,3 +151,4 @@ module_exit(i2c_versatile_exit);
 
 MODULE_DESCRIPTION("ARM Versatile I2C bus driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:versatile-i2c");

+ 1 - 1
drivers/i2c/busses/scx200_acb.c

@@ -527,7 +527,7 @@ static int __init scx200_create_isa(const char *text, unsigned long base,
 	if (iface == NULL)
 		return -ENOMEM;
 
-	if (request_region(base, 8, iface->adapter.name) == 0) {
+	if (!request_region(base, 8, iface->adapter.name)) {
 		printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n",
 		       base, base + 8 - 1);
 		rc = -EBUSY;

+ 14 - 14
drivers/i2c/chips/isp1301_omap.c

@@ -658,7 +658,7 @@ pulldown:
 		OTG_CTRL_REG |= OTG_PULLUP;
 	}
 
-	check_state(isp, __FUNCTION__);
+	check_state(isp, __func__);
 	dump_regs(isp, "otg->isp1301");
 }
 
@@ -782,7 +782,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp)
 		if (otg_ctrl & OTG_DRIVER_SEL) {
 			switch (isp->otg.state) {
 			case OTG_STATE_A_IDLE:
-				b_idle(isp, __FUNCTION__);
+				b_idle(isp, __func__);
 				break;
 			default:
 				break;
@@ -826,7 +826,7 @@ static irqreturn_t omap_otg_irq(int irq, void *_isp)
 						isp->otg.host->otg_port);
 	}
 
-	check_state(isp, __FUNCTION__);
+	check_state(isp, __func__);
 	return ret;
 }
 
@@ -837,7 +837,7 @@ static int otg_init(struct isp1301 *isp)
 	if (!otg_dev)
 		return -ENODEV;
 
-	dump_regs(isp, __FUNCTION__);
+	dump_regs(isp, __func__);
 	/* some of these values are board-specific... */
 	OTG_SYSCON_2_REG |= OTG_EN
 		/* for B-device: */
@@ -853,9 +853,9 @@ static int otg_init(struct isp1301 *isp)
 	update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE));
 	update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS));
 
-	check_state(isp, __FUNCTION__);
+	check_state(isp, __func__);
 	pr_debug("otg: %s, %s %06x\n",
-			state_name(isp), __FUNCTION__, OTG_CTRL_REG);
+			state_name(isp), __func__, OTG_CTRL_REG);
 
 	OTG_IRQ_EN_REG = DRIVER_SWITCH | OPRT_CHG
 			| B_SRP_TMROUT | B_HNP_FAIL
@@ -1041,11 +1041,11 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat)
 						OTG1_DP_PULLDOWN);
 			isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1,
 						OTG1_DP_PULLUP);
-			dump_regs(isp, __FUNCTION__);
+			dump_regs(isp, __func__);
 #endif
 			/* FALLTHROUGH */
 		case OTG_STATE_B_SRP_INIT:
-			b_idle(isp, __FUNCTION__);
+			b_idle(isp, __func__);
 			OTG_CTRL_REG &= OTG_CTRL_REG & OTG_XCEIV_OUTPUTS;
 			/* FALLTHROUGH */
 		case OTG_STATE_B_IDLE:
@@ -1077,7 +1077,7 @@ static void isp_update_otg(struct isp1301 *isp, u8 stat)
 	 */
 	update_otg1(isp, isp_stat);
 	update_otg2(isp, isp_bstat);
-	check_state(isp, __FUNCTION__);
+	check_state(isp, __func__);
 #endif
 
 	dump_regs(isp, "isp1301->otg");
@@ -1310,7 +1310,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host)
 	 */
 	isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_VBUS_DRV);
 
-	dump_regs(isp, __FUNCTION__);
+	dump_regs(isp, __func__);
 
 	return 0;
 
@@ -1365,7 +1365,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
 	isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING,
 		INTR_VBUS_VLD);
 	dev_info(&isp->client.dev, "B-Peripheral sessions ok\n");
-	dump_regs(isp, __FUNCTION__);
+	dump_regs(isp, __func__);
 
 	/* If this has a Mini-AB connector, this mode is highly
 	 * nonstandard ... but can be handy for testing, so long
@@ -1416,7 +1416,7 @@ isp1301_start_srp(struct otg_transceiver *dev)
 
 	pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), OTG_CTRL_REG);
 #ifdef	CONFIG_USB_OTG
-	check_state(isp, __FUNCTION__);
+	check_state(isp, __func__);
 #endif
 	return 0;
 }
@@ -1463,7 +1463,7 @@ isp1301_start_hnp(struct otg_transceiver *dev)
 	}
 	pr_debug("otg: HNP %s, %06x ...\n",
 		state_name(isp), OTG_CTRL_REG);
-	check_state(isp, __FUNCTION__);
+	check_state(isp, __func__);
 	return 0;
 #else
 	/* srp-only */
@@ -1601,7 +1601,7 @@ fail2:
 	update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS));
 #endif
 
-	dump_regs(isp, __FUNCTION__);
+	dump_regs(isp, __func__);
 
 #ifdef	VERBOSE
 	mod_timer(&isp->timer, jiffies + TIMER_JIFFIES);

+ 1 - 1
drivers/i2c/i2c-core.c

@@ -1506,7 +1506,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
 		read_write = I2C_SMBUS_READ;
 		if (data->block[0] > I2C_SMBUS_BLOCK_MAX) {
 			dev_err(&adapter->dev, "%s called with invalid "
-				"block proc call size (%d)\n", __FUNCTION__,
+				"block proc call size (%d)\n", __func__,
 				data->block[0]);
 			return -1;
 		}

+ 168 - 161
drivers/i2c/i2c-dev.c

@@ -200,16 +200,176 @@ static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
 	return device_for_each_child(&adapter->dev, &addr, i2cdev_check);
 }
 
-static int i2cdev_ioctl(struct inode *inode, struct file *file,
-		unsigned int cmd, unsigned long arg)
+static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
+		unsigned long arg)
 {
-	struct i2c_client *client = (struct i2c_client *)file->private_data;
 	struct i2c_rdwr_ioctl_data rdwr_arg;
-	struct i2c_smbus_ioctl_data data_arg;
-	union i2c_smbus_data temp;
 	struct i2c_msg *rdwr_pa;
 	u8 __user **data_ptrs;
-	int i,datasize,res;
+	int i, res;
+
+	if (copy_from_user(&rdwr_arg,
+			   (struct i2c_rdwr_ioctl_data __user *)arg,
+			   sizeof(rdwr_arg)))
+		return -EFAULT;
+
+	/* Put an arbitrary limit on the number of messages that can
+	 * be sent at once */
+	if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
+		return -EINVAL;
+
+	rdwr_pa = (struct i2c_msg *)
+		kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
+		GFP_KERNEL);
+	if (!rdwr_pa)
+		return -ENOMEM;
+
+	if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
+			   rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {
+		kfree(rdwr_pa);
+		return -EFAULT;
+	}
+
+	data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
+	if (data_ptrs == NULL) {
+		kfree(rdwr_pa);
+		return -ENOMEM;
+	}
+
+	res = 0;
+	for (i = 0; i < rdwr_arg.nmsgs; i++) {
+		/* Limit the size of the message to a sane amount;
+		 * and don't let length change either. */
+		if ((rdwr_pa[i].len > 8192) ||
+		    (rdwr_pa[i].flags & I2C_M_RECV_LEN)) {
+			res = -EINVAL;
+			break;
+		}
+		data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
+		rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
+		if (rdwr_pa[i].buf == NULL) {
+			res = -ENOMEM;
+			break;
+		}
+		if (copy_from_user(rdwr_pa[i].buf, data_ptrs[i],
+				   rdwr_pa[i].len)) {
+				++i; /* Needs to be kfreed too */
+				res = -EFAULT;
+			break;
+		}
+	}
+	if (res < 0) {
+		int j;
+		for (j = 0; j < i; ++j)
+			kfree(rdwr_pa[j].buf);
+		kfree(data_ptrs);
+		kfree(rdwr_pa);
+		return res;
+	}
+
+	res = i2c_transfer(client->adapter, rdwr_pa, rdwr_arg.nmsgs);
+	while (i-- > 0) {
+		if (res >= 0 && (rdwr_pa[i].flags & I2C_M_RD)) {
+			if (copy_to_user(data_ptrs[i], rdwr_pa[i].buf,
+					 rdwr_pa[i].len))
+				res = -EFAULT;
+		}
+		kfree(rdwr_pa[i].buf);
+	}
+	kfree(data_ptrs);
+	kfree(rdwr_pa);
+	return res;
+}
+
+static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
+		unsigned long arg)
+{
+	struct i2c_smbus_ioctl_data data_arg;
+	union i2c_smbus_data temp;
+	int datasize, res;
+
+	if (copy_from_user(&data_arg,
+			   (struct i2c_smbus_ioctl_data __user *) arg,
+			   sizeof(struct i2c_smbus_ioctl_data)))
+		return -EFAULT;
+	if ((data_arg.size != I2C_SMBUS_BYTE) &&
+	    (data_arg.size != I2C_SMBUS_QUICK) &&
+	    (data_arg.size != I2C_SMBUS_BYTE_DATA) &&
+	    (data_arg.size != I2C_SMBUS_WORD_DATA) &&
+	    (data_arg.size != I2C_SMBUS_PROC_CALL) &&
+	    (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
+	    (data_arg.size != I2C_SMBUS_I2C_BLOCK_BROKEN) &&
+	    (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
+	    (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
+		dev_dbg(&client->adapter->dev,
+			"size out of range (%x) in ioctl I2C_SMBUS.\n",
+			data_arg.size);
+		return -EINVAL;
+	}
+	/* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1,
+	   so the check is valid if size==I2C_SMBUS_QUICK too. */
+	if ((data_arg.read_write != I2C_SMBUS_READ) &&
+	    (data_arg.read_write != I2C_SMBUS_WRITE)) {
+		dev_dbg(&client->adapter->dev,
+			"read_write out of range (%x) in ioctl I2C_SMBUS.\n",
+			data_arg.read_write);
+		return -EINVAL;
+	}
+
+	/* Note that command values are always valid! */
+
+	if ((data_arg.size == I2C_SMBUS_QUICK) ||
+	    ((data_arg.size == I2C_SMBUS_BYTE) &&
+	    (data_arg.read_write == I2C_SMBUS_WRITE)))
+		/* These are special: we do not use data */
+		return i2c_smbus_xfer(client->adapter, client->addr,
+				      client->flags, data_arg.read_write,
+				      data_arg.command, data_arg.size, NULL);
+
+	if (data_arg.data == NULL) {
+		dev_dbg(&client->adapter->dev,
+			"data is NULL pointer in ioctl I2C_SMBUS.\n");
+		return -EINVAL;
+	}
+
+	if ((data_arg.size == I2C_SMBUS_BYTE_DATA) ||
+	    (data_arg.size == I2C_SMBUS_BYTE))
+		datasize = sizeof(data_arg.data->byte);
+	else if ((data_arg.size == I2C_SMBUS_WORD_DATA) ||
+		 (data_arg.size == I2C_SMBUS_PROC_CALL))
+		datasize = sizeof(data_arg.data->word);
+	else /* size == smbus block, i2c block, or block proc. call */
+		datasize = sizeof(data_arg.data->block);
+
+	if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
+	    (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
+	    (data_arg.size == I2C_SMBUS_I2C_BLOCK_DATA) ||
+	    (data_arg.read_write == I2C_SMBUS_WRITE)) {
+		if (copy_from_user(&temp, data_arg.data, datasize))
+			return -EFAULT;
+	}
+	if (data_arg.size == I2C_SMBUS_I2C_BLOCK_BROKEN) {
+		/* Convert old I2C block commands to the new
+		   convention. This preserves binary compatibility. */
+		data_arg.size = I2C_SMBUS_I2C_BLOCK_DATA;
+		if (data_arg.read_write == I2C_SMBUS_READ)
+			temp.block[0] = I2C_SMBUS_BLOCK_MAX;
+	}
+	res = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
+	      data_arg.read_write, data_arg.command, data_arg.size, &temp);
+	if (!res && ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
+		     (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
+		     (data_arg.read_write == I2C_SMBUS_READ))) {
+		if (copy_to_user(data_arg.data, &temp, datasize))
+			return -EFAULT;
+	}
+	return res;
+}
+
+static int i2cdev_ioctl(struct inode *inode, struct file *file,
+		unsigned int cmd, unsigned long arg)
+{
+	struct i2c_client *client = (struct i2c_client *)file->private_data;
 	unsigned long funcs;
 
 	dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n",
@@ -253,164 +413,11 @@ static int i2cdev_ioctl(struct inode *inode, struct file *file,
 		return put_user(funcs, (unsigned long __user *)arg);
 
 	case I2C_RDWR:
-		if (copy_from_user(&rdwr_arg,
-				   (struct i2c_rdwr_ioctl_data __user *)arg,
-				   sizeof(rdwr_arg)))
-			return -EFAULT;
-
-		/* Put an arbitrary limit on the number of messages that can
-		 * be sent at once */
-		if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
-			return -EINVAL;
-
-		rdwr_pa = (struct i2c_msg *)
-			kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
-			GFP_KERNEL);
-
-		if (rdwr_pa == NULL) return -ENOMEM;
-
-		if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
-				   rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {
-			kfree(rdwr_pa);
-			return -EFAULT;
-		}
-
-		data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
-		if (data_ptrs == NULL) {
-			kfree(rdwr_pa);
-			return -ENOMEM;
-		}
-
-		res = 0;
-		for( i=0; i<rdwr_arg.nmsgs; i++ ) {
-			/* Limit the size of the message to a sane amount;
-			 * and don't let length change either. */
-			if ((rdwr_pa[i].len > 8192) ||
-			    (rdwr_pa[i].flags & I2C_M_RECV_LEN)) {
-				res = -EINVAL;
-				break;
-			}
-			data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
-			rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
-			if(rdwr_pa[i].buf == NULL) {
-				res = -ENOMEM;
-				break;
-			}
-			if(copy_from_user(rdwr_pa[i].buf,
-				data_ptrs[i],
-				rdwr_pa[i].len)) {
-					++i; /* Needs to be kfreed too */
-					res = -EFAULT;
-				break;
-			}
-		}
-		if (res < 0) {
-			int j;
-			for (j = 0; j < i; ++j)
-				kfree(rdwr_pa[j].buf);
-			kfree(data_ptrs);
-			kfree(rdwr_pa);
-			return res;
-		}
-
-		res = i2c_transfer(client->adapter,
-			rdwr_pa,
-			rdwr_arg.nmsgs);
-		while(i-- > 0) {
-			if( res>=0 && (rdwr_pa[i].flags & I2C_M_RD)) {
-				if(copy_to_user(
-					data_ptrs[i],
-					rdwr_pa[i].buf,
-					rdwr_pa[i].len)) {
-					res = -EFAULT;
-				}
-			}
-			kfree(rdwr_pa[i].buf);
-		}
-		kfree(data_ptrs);
-		kfree(rdwr_pa);
-		return res;
+		return i2cdev_ioctl_rdrw(client, arg);
 
 	case I2C_SMBUS:
-		if (copy_from_user(&data_arg,
-		                   (struct i2c_smbus_ioctl_data __user *) arg,
-		                   sizeof(struct i2c_smbus_ioctl_data)))
-			return -EFAULT;
-		if ((data_arg.size != I2C_SMBUS_BYTE) &&
-		    (data_arg.size != I2C_SMBUS_QUICK) &&
-		    (data_arg.size != I2C_SMBUS_BYTE_DATA) &&
-		    (data_arg.size != I2C_SMBUS_WORD_DATA) &&
-		    (data_arg.size != I2C_SMBUS_PROC_CALL) &&
-		    (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
-		    (data_arg.size != I2C_SMBUS_I2C_BLOCK_BROKEN) &&
-		    (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
-		    (data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
-			dev_dbg(&client->adapter->dev,
-				"size out of range (%x) in ioctl I2C_SMBUS.\n",
-				data_arg.size);
-			return -EINVAL;
-		}
-		/* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1,
-		   so the check is valid if size==I2C_SMBUS_QUICK too. */
-		if ((data_arg.read_write != I2C_SMBUS_READ) &&
-		    (data_arg.read_write != I2C_SMBUS_WRITE)) {
-			dev_dbg(&client->adapter->dev,
-				"read_write out of range (%x) in ioctl I2C_SMBUS.\n",
-				data_arg.read_write);
-			return -EINVAL;
-		}
-
-		/* Note that command values are always valid! */
-
-		if ((data_arg.size == I2C_SMBUS_QUICK) ||
-		    ((data_arg.size == I2C_SMBUS_BYTE) &&
-		    (data_arg.read_write == I2C_SMBUS_WRITE)))
-			/* These are special: we do not use data */
-			return i2c_smbus_xfer(client->adapter, client->addr,
-					      client->flags,
-					      data_arg.read_write,
-					      data_arg.command,
-					      data_arg.size, NULL);
-
-		if (data_arg.data == NULL) {
-			dev_dbg(&client->adapter->dev,
-				"data is NULL pointer in ioctl I2C_SMBUS.\n");
-			return -EINVAL;
-		}
+		return i2cdev_ioctl_smbus(client, arg);
 
-		if ((data_arg.size == I2C_SMBUS_BYTE_DATA) ||
-		    (data_arg.size == I2C_SMBUS_BYTE))
-			datasize = sizeof(data_arg.data->byte);
-		else if ((data_arg.size == I2C_SMBUS_WORD_DATA) ||
-		         (data_arg.size == I2C_SMBUS_PROC_CALL))
-			datasize = sizeof(data_arg.data->word);
-		else /* size == smbus block, i2c block, or block proc. call */
-			datasize = sizeof(data_arg.data->block);
-
-		if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
-		    (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
-		    (data_arg.size == I2C_SMBUS_I2C_BLOCK_DATA) ||
-		    (data_arg.read_write == I2C_SMBUS_WRITE)) {
-			if (copy_from_user(&temp, data_arg.data, datasize))
-				return -EFAULT;
-		}
-		if (data_arg.size == I2C_SMBUS_I2C_BLOCK_BROKEN) {
-			/* Convert old I2C block commands to the new
-			   convention. This preserves binary compatibility. */
-			data_arg.size = I2C_SMBUS_I2C_BLOCK_DATA;
-			if (data_arg.read_write == I2C_SMBUS_READ)
-				temp.block[0] = I2C_SMBUS_BLOCK_MAX;
-		}
-		res = i2c_smbus_xfer(client->adapter,client->addr,client->flags,
-		      data_arg.read_write,
-		      data_arg.command,data_arg.size,&temp);
-		if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
-		              (data_arg.size == I2C_SMBUS_BLOCK_PROC_CALL) ||
-			      (data_arg.read_write == I2C_SMBUS_READ))) {
-			if (copy_to_user(data_arg.data, &temp, datasize))
-				return -EFAULT;
-		}
-		return res;
 	case I2C_RETRIES:
 		client->adapter->retries = arg;
 		break;

+ 22 - 0
include/asm-sh/i2c-sh7760.h

@@ -0,0 +1,22 @@
+/*
+ * MMIO/IRQ and platform data for SH7760 I2C channels
+ */
+
+#ifndef _I2C_SH7760_H_
+#define _I2C_SH7760_H_
+
+#define SH7760_I2C_DEVNAME	"sh7760-i2c"
+
+#define SH7760_I2C0_MMIO	0xFE140000
+#define SH7760_I2C0_MMIOEND	0xFE14003B
+#define SH7760_I2C0_IRQ		62
+
+#define SH7760_I2C1_MMIO	0xFE150000
+#define SH7760_I2C1_MMIOEND	0xFE15003B
+#define SH7760_I2C1_IRQ		63
+
+struct sh7760_i2c_platdata {
+	unsigned int speed_khz;
+};
+
+#endif

+ 32 - 5
include/linux/i2c-algo-pca.h

@@ -1,14 +1,41 @@
 #ifndef _LINUX_I2C_ALGO_PCA_H
 #define _LINUX_I2C_ALGO_PCA_H
 
+/* Clock speeds for the bus */
+#define I2C_PCA_CON_330kHz	0x00
+#define I2C_PCA_CON_288kHz	0x01
+#define I2C_PCA_CON_217kHz	0x02
+#define I2C_PCA_CON_146kHz	0x03
+#define I2C_PCA_CON_88kHz	0x04
+#define I2C_PCA_CON_59kHz	0x05
+#define I2C_PCA_CON_44kHz	0x06
+#define I2C_PCA_CON_36kHz	0x07
+
+/* PCA9564 registers */
+#define I2C_PCA_STA		0x00 /* STATUS  Read Only  */
+#define I2C_PCA_TO		0x00 /* TIMEOUT Write Only */
+#define I2C_PCA_DAT		0x01 /* DATA    Read/Write */
+#define I2C_PCA_ADR		0x02 /* OWN ADR Read/Write */
+#define I2C_PCA_CON		0x03 /* CONTROL Read/Write */
+
+#define I2C_PCA_CON_AA		0x80 /* Assert Acknowledge */
+#define I2C_PCA_CON_ENSIO	0x40 /* Enable */
+#define I2C_PCA_CON_STA		0x20 /* Start */
+#define I2C_PCA_CON_STO		0x10 /* Stop */
+#define I2C_PCA_CON_SI		0x08 /* Serial Interrupt */
+#define I2C_PCA_CON_CR		0x07 /* Clock Rate (MASK) */
+
 struct i2c_algo_pca_data {
-	int  (*get_own)			(struct i2c_algo_pca_data *adap); /* Obtain own address */
-	int  (*get_clock)		(struct i2c_algo_pca_data *adap);
-	void (*write_byte)		(struct i2c_algo_pca_data *adap, int reg, int val);
-	int  (*read_byte)		(struct i2c_algo_pca_data *adap, int reg);
-	int  (*wait_for_interrupt)	(struct i2c_algo_pca_data *adap);
+	void 				*data;	/* private low level data */
+	void (*write_byte)		(void *data, int reg, int val);
+	int  (*read_byte)		(void *data, int reg);
+	int  (*wait_for_completion)	(void *data);
+	void (*reset_chip)		(void *data);
+	/* i2c_clock values are defined in linux/i2c-algo-pca.h */
+	unsigned int			i2c_clock;
 };
 
 int i2c_pca_add_bus(struct i2c_adapter *);
+int i2c_pca_add_numbered_bus(struct i2c_adapter *);
 
 #endif /* _LINUX_I2C_ALGO_PCA_H */

+ 12 - 0
include/linux/i2c-pca-platform.h

@@ -0,0 +1,12 @@
+#ifndef I2C_PCA9564_PLATFORM_H
+#define I2C_PCA9564_PLATFORM_H
+
+struct i2c_pca9564_pf_platform_data {
+	int gpio;		/* pin to reset chip. driver will work when
+				 * not supplied (negative value), but it
+				 * cannot exit some error conditions then */
+	int i2c_clock_speed;	/* values are defined in linux/i2c-algo-pca.h */
+	int timeout;		/* timeout = this value * 10us */
+};
+
+#endif /* I2C_PCA9564_PLATFORM_H */