Merge branch 'next' of git://git.denx.de/u-boot-sh
diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c
index 291ad94..aa159f8 100644
--- a/drivers/i2c/fsl_i2c.c
+++ b/drivers/i2c/fsl_i2c.c
@@ -423,18 +423,45 @@
 	struct fsl_i2c *device = (struct fsl_i2c *)i2c_dev[adap->hwadapnr];
 	int i = -1; /* signal error */
 	u8 *a = (u8*)&addr;
+	int len = alen * -1;
 
 	if (i2c_wait4bus(adap) < 0)
 		return -1;
 
-	if ((!length || alen > 0)
-	    && i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0
-	    && __i2c_write(adap, &a[4 - alen], alen) == alen)
-		i = 0; /* No error so far */
+	/* To handle the need of I2C devices that require to write few bytes
+	 * (more than 4 bytes of address as in the case of else part)
+	 * of data before reading, Negative equivalent of length(bytes to write)
+	 * is passed, but used the +ve part of len for writing data
+	 */
+	if (alen < 0) {
+		/* Generate a START and send the Address and
+		 * the Tx Bytes to the slave.
+		 * "START: Address: Write bytes data[len]"
+		 * IF part supports writing any number of bytes in contrast
+		 * to the else part, which supports writing address offset
+		 * of upto 4 bytes only.
+		 * bytes that need to be written are passed in
+		 * "data", which will eventually keep the data READ,
+		 * after writing the len bytes out of it
+		 */
+		if (i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0)
+			i = __i2c_write(adap, data, len);
+
+		if (i != len)
+			return -1;
+
+		if (length && i2c_write_addr(adap, dev, I2C_READ_BIT, 1) != 0)
+			i = __i2c_read(adap, data, length);
+	} else {
+		if ((!length || alen > 0) &&
+		    i2c_write_addr(adap, dev, I2C_WRITE_BIT, 0) != 0  &&
+		    __i2c_write(adap, &a[4 - alen], alen) == alen)
+			i = 0; /* No error so far */
 
-	if (length &&
-	    i2c_write_addr(adap, dev, I2C_READ_BIT, alen ? 1 : 0) != 0)
-		i = __i2c_read(adap, data, length);
+		if (length &&
+		    i2c_write_addr(adap, dev, I2C_READ_BIT, alen ? 1 : 0) != 0)
+			i = __i2c_read(adap, data, length);
+	}
 
 	writeb(I2C_CR_MEN, &device->cr);
 
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index 595019b..48468d7 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -22,6 +22,8 @@
 #include <i2c.h>
 #include <watchdog.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #ifdef I2C_QUIRK_REG
 struct mxc_i2c_regs {
 	uint8_t		iadr;
@@ -411,12 +413,6 @@
 	struct i2c_parms i2c_data[3];
 };
 
-/*
- * For SPL boot some boards need i2c before SDRAM is initialized so force
- * variables to live in SRAM
- */
-static struct sram_data __attribute__((section(".data"))) srdata;
-
 static void * const i2c_bases[] = {
 #if defined(CONFIG_MX25)
 	(void *)IMX_I2C_BASE,
@@ -445,9 +441,10 @@
 
 static struct i2c_parms *i2c_get_parms(void *base)
 {
+	struct sram_data *srdata = (void *)gd->srdata;
 	int i = 0;
-	struct i2c_parms *p = srdata.i2c_data;
-	while (i < ARRAY_SIZE(srdata.i2c_data)) {
+	struct i2c_parms *p = srdata->i2c_data;
+	while (i < ARRAY_SIZE(srdata->i2c_data)) {
 		if (p->base == base)
 			return p;
 		p++;
@@ -490,8 +487,9 @@
 void bus_i2c_init(void *base, int speed, int unused,
 		int (*idle_bus_fn)(void *p), void *idle_bus_data)
 {
+	struct sram_data *srdata = (void *)gd->srdata;
 	int i = 0;
-	struct i2c_parms *p = srdata.i2c_data;
+	struct i2c_parms *p = srdata->i2c_data;
 	if (!base)
 		return;
 	for (;;) {
@@ -505,7 +503,7 @@
 		}
 		p++;
 		i++;
-		if (i >= ARRAY_SIZE(srdata.i2c_data))
+		if (i >= ARRAY_SIZE(srdata->i2c_data))
 			return;
 	}
 	bus_i2c_set_bus_speed(base, speed);
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 707400e..e98b661 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -80,6 +80,9 @@
 #if defined(CONFIG_SYS_I2C)
 	int		cur_i2c_bus;	/* current used i2c bus */
 #endif
+#ifdef CONFIG_SYS_I2C_MXC
+	void *srdata[10];
+#endif
 	unsigned long timebase_h;
 	unsigned long timebase_l;
 	struct arch_global_data arch;	/* architecture-specific data */