diff --git a/arch/powerpc/include/asm/ppc4xx-i2c.h b/arch/powerpc/include/asm/ppc4xx-i2c.h
index 09189cf19bc8f7470ee6f70dbfb764018886b4c9..df97f175b3637856da0f91ef8ee8e7da159af7dd 100644
--- a/arch/powerpc/include/asm/ppc4xx-i2c.h
+++ b/arch/powerpc/include/asm/ppc4xx-i2c.h
@@ -72,6 +72,8 @@ struct ppc4xx_i2c {
 #define IIC_EXTSTS_XFRA		0x01
 #define IIC_EXTSTS_ICT		0x02
 #define IIC_EXTSTS_LA		0x04
+#define IIC_EXTSTS_BCS_MASK	0x70
+#define IIC_EXTSTS_BCS_FREE	0x40
 
 /* XTCNTLSS Register Bit definition */
 #define IIC_XTCNTLSS_SRST	0x01
diff --git a/drivers/i2c/ppc4xx_i2c.c b/drivers/i2c/ppc4xx_i2c.c
index d2ff86c99abac6a5ca14c5386bf1ad446c5e100e..df8888550bb0e2010db25362ca9695b4ac7a293e 100644
--- a/drivers/i2c/ppc4xx_i2c.c
+++ b/drivers/i2c/ppc4xx_i2c.c
@@ -289,6 +289,27 @@ static int _i2c_transfer(struct i2c_adapter *adap,
 			/* Transfer aborted? */
 			if (status & IIC_EXTSTS_XFRA)
 				result = IIC_NOK_XFRA;
+			/* Is bus free?
+			 * If error happened during combined xfer
+			 * IIC interface is usually stuck in some strange
+			 * state without a valid stop condition.
+			 * Brute, but working: generate stop, then soft reset.
+			 */
+			if ((status & IIC_EXTSTS_BCS_MASK)
+			    != IIC_EXTSTS_BCS_FREE){
+				u8 mdcntl = in_8(&i2c->mdcntl);
+
+				/* Generate valid stop condition */
+				out_8(&i2c->xtcntlss, IIC_XTCNTLSS_SRST);
+				out_8(&i2c->directcntl, IIC_DIRCNTL_SCC);
+				udelay(10);
+				out_8(&i2c->directcntl,
+				      IIC_DIRCNTL_SCC | IIC_DIRCNTL_SDAC);
+				out_8(&i2c->xtcntlss, 0);
+
+				ppc4xx_i2c_init(adap, (mdcntl & IIC_MDCNTL_FSM)
+						? 400000 : 100000, 0);
+			}
 		} else if ( status & IIC_STS_PT) {
 			result = IIC_NOK_TOUT;
 		}