[linux-yocto] [PATCH 39/87] drivers/i2c/ai2c: add more dtb support

Paul Butler butler.paul at gmail.com
Mon May 27 09:56:10 PDT 2013


From: Michael Bringmann <michael.bringmann at lsi.com>

Accept more data extracted from DTB block to configure an I2C bus,
instead of using hard-coded addresses in code.  Revise module to
configure only those busses actually configured.  Remove unneeded
code, and compress header files.

Signed-off-by: Michael Bringmann <michael.bringmann at lsi.com>
---
 drivers/i2c/busses/ai2c/ai2c_bus.h           |  93 +------
 drivers/i2c/busses/ai2c/ai2c_bus_axm5500.c   |  24 +-
 drivers/i2c/busses/ai2c/ai2c_dev.h           | 165 ++++++++++--
 drivers/i2c/busses/ai2c/ai2c_dev_clock.c     |   4 +-
 drivers/i2c/busses/ai2c/ai2c_dev_clock_ext.h |   2 +-
 drivers/i2c/busses/ai2c/ai2c_mod.c           | 149 ++++++-----
 drivers/i2c/busses/ai2c/ai2c_plat.c          | 379 +++++++++++----------------
 drivers/i2c/busses/ai2c/ai2c_plat.h          |  75 +++++-
 drivers/i2c/busses/ai2c/ai2c_sal.c           |  15 +-
 drivers/i2c/busses/ai2c/ai2c_sal.h           | 351 ++++++++++++++++++++++++-
 drivers/i2c/busses/ai2c/ai2c_types.h         |  54 +++-
 11 files changed, 850 insertions(+), 461 deletions(-)

diff --git a/drivers/i2c/busses/ai2c/ai2c_bus.h b/drivers/i2c/busses/ai2c/ai2c_bus.h
index 97c9fe5..8861ae5 100644
--- a/drivers/i2c/busses/ai2c/ai2c_bus.h
+++ b/drivers/i2c/busses/ai2c/ai2c_bus.h
@@ -52,8 +52,8 @@
 */
 #define AI2C_I2CPROT_MAX_BUF_SIZE           8
 
-#define AI2C_I2C_CHECK_COUNT				0xFFFFF
 /* Max number of tries at looking for an I/O success */
+#define AI2C_I2C_CHECK_COUNT				0xFFFFF
 
 	/*****************************
 	* ACP3400                    *
@@ -92,61 +92,6 @@
 #define DEV_10BIT_AUTO(ioc)          TENBIT_SETENABLED(ioc)
 
 
-/*
- * Application-specific (BUS) timing constants, types, etc.
- */
-
-#define CFG_CLK_CONFIG_SCL_LOW   (1000) /* (MCC-0x143.0x0.0x1c)
-					   bits 9:0 (MCC LPD) */
-#define CFG_CLK_CONFIG_SCL_HIGH  (1000) /* (MCC-0x143.0x0.0x1c)
-					   bits 25:16 (MCC HPD) */
-#define CFG_START_SETUP_PERIOD   (940)  /* (MSTSHC-0x143.0x0.0x20)
-					   bits 9:0 (MSTSHC SETDU) */
-#define CFG_START_HOLD_PERIOD    (800)  /* (MSTSHC-0x143.0x0.0x20)
-					   bits 25:16 (MSTSHC HLDDU) */
-#define CFG_STOP_SETUP_PERIOD    (800)  /* (MSPSHC-0x143.0x0.0x24)
-					   bits 9:0 (MSPSHC SETDU) */
-#define CFG_STOP_HOLD_PERIOD     (0)    /* (MSPSHC-0x143.0x0.0x24)
-					   bits 25:16 (MSPSHC HLDDU) */
-#define CFG_DATA_SETUP_PERIOD    (50)   /* (MDSHC-0x143.0x0.0x28)
-					   bits 9:0 (MDSHC SETDU) */
-#define CFG_DATA_HOLD_PERIOD     (0)    /* (MSPSHC-0x143.0x0.0x28)
-					   bits 25:16 (MDSHC HLDDU) */
-
-/*! @def AI2C_I2C_IOCONFIG_READ_DEFAULT
- *  @brief Easy default initialization for ai2c_i2c_config_acp3400_t.readTiming.
- */
-#define AI2C_I2C_IOCONFIG_READ_DEFAULT \
-{ \
-	CFG_CLK_CONFIG_SCL_HIGH, \
-	CFG_CLK_CONFIG_SCL_LOW, \
-	CFG_START_SETUP_PERIOD, \
-	CFG_START_HOLD_PERIOD, \
-	CFG_STOP_SETUP_PERIOD, \
-	CFG_STOP_HOLD_PERIOD, \
-	CFG_DATA_SETUP_PERIOD, \
-	CFG_DATA_HOLD_PERIOD, \
-}
-
-/*! @def AI2C_I2C_IOCONFIG_WRITE_DEFAULT
- *  @brief Easy default initialization for ai2c_i2c_config_acp3400_t.writeTiming.
- */
-#define AI2C_I2C_IOCONFIG_WRITE_DEFAULT \
-{ \
-	CFG_CLK_CONFIG_SCL_HIGH, \
-	CFG_CLK_CONFIG_SCL_LOW, \
-	CFG_START_SETUP_PERIOD, \
-	CFG_START_HOLD_PERIOD, \
-	CFG_STOP_SETUP_PERIOD, \
-	CFG_STOP_HOLD_PERIOD, \
-	CFG_DATA_SETUP_PERIOD, \
-	CFG_DATA_HOLD_PERIOD, \
-}
-
-#define AI2C_I2C_IOCONFIG_WAITPOSTWRITE_DEFAULT    (5000) /* 5ms for each */
-#define AI2C_I2C_IOCONFIG_WAITPOSTREAD_DEFAULT     (0)    /* 0ms for each */
-
-
 /*****************************************************************************
 * Type definitions                                                           *
 *****************************************************************************/
@@ -216,42 +161,6 @@ struct ai2c_i2c_access {
 	void                    *extra;
 };
 
-    /*********************************************
-     * ACP3400-like I2C Devices Definitions, etc.
-     ********************************************/
-
-/*! @struct ai2c_i2c_ioconfig
-    @brief  Timing Control Configuration for I2C registers
-*/
-struct ai2c_i2c_ioconfig {
-	u32 clkPulseWidthHigh:10;
-	/*!< Number of pclk durations that equal
-	* high period of SCL*/
-	u32 clkPulseWidthLow:10;
-	/*!< Number of pclk durations that equal
-	* low period of SCL */
-	u32 startSetupTime:10;
-	/*!< Number of pclk durations that equal
-	* setup condition on SDA */
-	u32 startHoldTime:10;
-	/*!< Number of pclk durations that equal
-	* hold condition on SDA */
-	u32 stopSetupTime:10;
-	/*!< Number of pclk durations that equal
-	* stop condition on SDA */
-	u32 stopHoldTime:10;
-	/*!< Number of pclk durations that equal
-	* setup condition on SDA */
-	u32 dataSetupTime:10;
-	/*!< Number of pclk durations that equal
-	* setup condition on SDA for data changing*/
-	u32 dataHoldTime:10;
-	/*!< Number of pclk durations that equal
-	* hold condition on SDA for data changing*/
-};
-
-
-extern struct ai2c_i2c_access       ai2c_acp3400_cfg;
 
     /*********************************************
      * AXM5500-like I2C Devices Definitions, etc.
diff --git a/drivers/i2c/busses/ai2c/ai2c_bus_axm5500.c b/drivers/i2c/busses/ai2c/ai2c_bus_axm5500.c
index 4066125..01c1a38 100644
--- a/drivers/i2c/busses/ai2c/ai2c_bus_axm5500.c
+++ b/drivers/i2c/busses/ai2c/ai2c_bus_axm5500.c
@@ -22,7 +22,8 @@
 
 /* #define EXTRA_DEBUG */
 
-#include "ai2c_plat_pvt.h"
+#include "ai2c_bus.h"
+#include "ai2c_plat.h"
 #include "ai2c_dev_clock_ext.h"
 #include "regs/ai2c_i2c_regs.h"
 #include "regs/ai2c_axi_timer_regs.h"
@@ -75,12 +76,14 @@ static int ai2c_bus_init_axm5500(struct ai2c_priv *priv,
 
 
 		AI2C_LOG(AI2C_MSG_DEBUG,
-			"bus_init_axm5500: 0x%04x.0x%04x.0x%x = 0x%08x (0x%08x)\n",
+			"bus_init_axm5500: 0x%04x.0x%04x.0x%x = 0x%08x "
+			"(0x%08x)\n",
 			AI2C_NODE_ID(inRegionId), AI2C_TARGET_ID(inRegionId),
 			AI2C_REG_I2C_X7_UDID_W7,
 			v0, AI2C_REG_I2C_X7_UDID_W7_DEFAULT);
 		AI2C_LOG(AI2C_MSG_DEBUG,
-			"bus_init_axm5500: 0x%04x.0x%04x.0x%x = 0x%08x (0x%08x)\n",
+			"bus_init_axm5500: 0x%04x.0x%04x.0x%x = 0x%08x "
+			"(0x%08x)\n",
 			AI2C_NODE_ID(inRegionId), AI2C_TARGET_ID(inRegionId),
 			AI2C_REG_I2C_X7_UDID_W4,
 			v1, AI2C_REG_I2C_X7_UDID_W4_DEFAULT);
@@ -140,7 +143,7 @@ static int ai2c_bus_init_axm5500(struct ai2c_priv *priv,
 	AI2C_CALL(ai2c_dev_write32(priv, inRegionId,
 		AI2C_REG_I2C_X7_WAIT_TIMER_CONTROL, 0x00008989));
 
-AI2C_RETURN_LABEL
+ai2c_return:
 
 	AI2C_LOG(AI2C_MSG_EXIT,
 		"bus_init_axm5500: exit (%d)\n", ai2cStatus);
@@ -315,7 +318,7 @@ static int ai2c_bus_block_read8_axm5500_internal(
 		buffer[0], buffer[1], buffer[2], buffer[3],
 		buffer[4], buffer[5], buffer[6], buffer[7]);
 
-AI2C_RETURN_LABEL
+ai2c_return:
 
 	AI2C_LOG(AI2C_MSG_EXIT,
 		"read8_i: exit; st=%d; rcvd=%d\n", ai2cStatus, (*actCount));
@@ -323,7 +326,7 @@ AI2C_RETURN_LABEL
 	return ai2cStatus;
 }
 
-static int ai2c_bus_block_read8_axm5500(
+int ai2c_bus_block_read8_axm5500(
 	struct ai2c_priv	       *priv,
 	u32    regionId,
 	struct i2c_adapter *adap,
@@ -367,7 +370,7 @@ static int ai2c_bus_block_read8_axm5500(
 		bytesRead += actCount;
 	}
 
-AI2C_RETURN_LABEL
+ai2c_return:
 
 	AI2C_LOG(AI2C_MSG_EXIT,
 		"read8: exit; st=%d l=%d\n", ai2cStatus, actCount);
@@ -542,7 +545,7 @@ static int ai2c_bus_block_write8_axm5500_internal(
 
 	(*actCount) = (numInFifo & 0xFF);
 
-AI2C_RETURN_LABEL
+ai2c_return:
 
 	AI2C_LOG(AI2C_MSG_EXIT,
 		"write8_i: exit; st=%d; num of bytes sent is %d (%d)\n",
@@ -605,7 +608,8 @@ static int ai2c_bus_block_write8_axm5500(
 			goto ai2c_return;
 
 		AI2C_LOG(AI2C_MSG_DEBUG,
-			"write8: tbm %d l %d aw %d c %d cu %d[%x,%x,%x,%x,%x,%x,%x,%x]\n",
+			"write8: tbm %d l %d aw %d c %d cu %d"
+			"[%x,%x,%x,%x,%x,%x,%x,%x]\n",
 			lTenBitMode, thisXfr, actWid, count, countUsed,
 			inOutTxd[0], inOutTxd[1], inOutTxd[2], inOutTxd[3],
 			 inOutTxd[4], inOutTxd[5], inOutTxd[6], inOutTxd[7]);
@@ -614,7 +618,7 @@ static int ai2c_bus_block_write8_axm5500(
 		countRem -= actWid;
 	}
 
-AI2C_RETURN_LABEL
+ai2c_return:
 
 	AI2C_LOG(AI2C_MSG_EXIT,
 		"write8: exit; st=%d\n", ai2cStatus);
diff --git a/drivers/i2c/busses/ai2c/ai2c_dev.h b/drivers/i2c/busses/ai2c/ai2c_dev.h
index fe9493b..8cbc03b 100644
--- a/drivers/i2c/busses/ai2c/ai2c_dev.h
+++ b/drivers/i2c/busses/ai2c/ai2c_dev.h
@@ -20,34 +20,27 @@
  * MA 02111-1307 USA
  */
 
-/*! @file      AI2C_dev.h
- *  @brief     Exported Device-level APIs.
- *  @addtogroup _device_APIs Device Level APIs
- *  Device-level APIs work with flat memory in each device, specifying
- *  addresses or ranges of addresses.  The object-level APIs call these
- *  device-level APIs, and the host program can also call the device-level
- *  APIs directly.
- *
- *  @{
- */
-
 #ifndef __AI2C_DEV_H__
 #define __AI2C_DEV_H__
 
-/*
- * AI2C_dev.h
- *
- * This is the external header file for the AI2C device driver.
- * This provides the function prototypes and associated definitions
- * needed for the user application to access the device APIs.
- *
- */
-
-/*
- * Includes
- */
 
 #include "ai2c_types.h"
+#include "ai2c_sal.h"
+#include "regs/ai2c_regions.h"
+
+
+/* BEGIN: Important forward type references */
+
+struct ai2c_region_io;
+struct ai2c_priv;
+
+/* END:   Important forward type references */
+
+
+/* --- Linux References --- */
+#ifndef AI2C_MOD_NAME
+#define AI2C_MOD_NAME        "ai2c"
+#endif
 
 
 /* --- Maximum version string length --- */
@@ -106,4 +99,130 @@ struct ai2c_access_map {
 	{          0,          0, AI2C_DEV_ACCESS_NONE }      \
 	}
 
+
+/* --- Internal Types & Definitions --- */
+
+#define AI2C_DEV_ACCESS_NONE            (0x00)
+#define AI2C_DEV_ACCESS_READ            (0x01)
+#define AI2C_DEV_ACCESS_WRITE           (0x02)
+#define AI2C_DEV_ACCESS_RW              (0x03)
+#define AI2C_DEV_ACCESS_BIG_ENDIAN      (0x04)
+#define AI2C_DEV_ACCESS_LITTLE_ENDIAN   (0x08)
+
+
+#define AI2C_DEV_SIZE_1KB                (1024*1)
+#define AI2C_DEV_SIZE_4KB                (1024*4)
+#define AI2C_DEV_SIZE_128KB              (1024*128)
+#define AI2C_DEV_SIZE_256KB              (1024*256)
+#define AI2C_DEV_SIZE_2MB                (1024*1024*2)
+#define AI2C_DEV_SIZE_16MB               (1024*1024*16)
+#define AI2C_DEV_SIZE_128MB              (1024*1024*128)
+#define AI2C_DEV_SIZE_1GB                (1024*1024*1024)
+#define AI2C_DEV_SIZE_NO_SIZE            (0)
+
+
+/* read/write fn prototypes for region map function pointers */
+
+typedef int (*_ai2c_dev_read_fn_t) (
+		   struct ai2c_priv          *priv,
+		   struct ai2c_region_io     *region,
+		   u64	 offset,
+		   u32	*buffer,
+		   u32	 count,
+		   u32	 flags,
+		   u32	 cmdType,
+		   u32	 xferWidth);
+
+typedef int (*_ai2c_dev_write_fn_t) (
+		   struct ai2c_priv          *priv,
+		   struct ai2c_region_io     *region,
+		   u64	 offset,
+		   u32	*buffer,
+		   u32	 count,
+		   u32	 flags,
+		   u32	 cmdType,
+		   u32	 xferWidth);
+
+/*
+ * Structure definition(s) for the region map.
+ * See above for typedef ai2c_region_io_t.
+ */
+struct ai2c_region_io {
+	u32 regionId;
+	struct ai2c_access_map     *accessMap;
+	_ai2c_dev_read_fn_t    readFn;
+	_ai2c_dev_write_fn_t   writeFn;
+	u32          pageId;
+};
+
+/*
+ * Sometimes it would be better to define a range of similar regions
+ * with a single entry in the region map, especially, for regions
+ * that are logical or virtual entities that involve interpretation,
+ * calculated addresses based upon the regionId, or some other
+ * transformation.  The alternate region map such definitions.
+ */
+struct ai2c_region_iorng {
+	u32 startRegionId;
+	u32 endRegionId;
+	struct ai2c_access_map     *accessMap;
+	_ai2c_dev_read_fn_t    readFn;
+	_ai2c_dev_write_fn_t   writeFn;
+	u32 pageId;
+};
+
+
+/*
+ * Basic i/o methods
+ */
+
+#ifdef DEBUG_EDEV_IO
+#define AI2C_WRITE_LOG(ctx, dev, pageId, offset, value) \
+	AI2C_MSG(AI2C_MSG_DEBUG_IO, \
+	    "%s: pageId=0x%x offset=0x%x addr=0x%x value=0x%02x\n", \
+	    ctx, pageId, offset, AI2C_DEV_BUS_ADDR(dev, pageId, offset), value)
+#else
+#define AI2C_WRITE_LOG(ctx, dev, pageId, offset, value)
+#endif
+
+#define AI2C_DEV_BUS_READ8(dev, pageId, offset) \
+	AI2C_BUS_READ8(AI2C_DEV_BUS_ADDR(dev, pageId, offset),\
+		AI2C_DEV_PAGE_ENDIANNESS(pageId))
+
+#define AI2C_DEV_BUS_READ16(dev, pageId, offset) \
+	AI2C_BUS_READ16(AI2C_DEV_BUS_ADDR(dev, pageId, offset),\
+		AI2C_DEV_PAGE_ENDIANNESS(pageId))
+
+#define AI2C_DEV_BUS_READ32(dev, pageId, offset) \
+	AI2C_BUS_READ32(AI2C_DEV_BUS_ADDR(dev, pageId, offset),\
+		AI2C_DEV_PAGE_ENDIANNESS(pageId))
+
+#define AI2C_DEV_BUS_WRITE8(dev, pageId, offset, value) \
+	do { \
+		AI2C_WRITE_LOG("edev_bus_write8", dev, pageId, offset, value); \
+		AI2C_BUS_WRITE8( \
+		AI2C_DEV_BUS_ADDR(dev, pageId, offset), value); \
+		if (AI2C_DEV_PAGE_FLAGS(pageId) == AI2C_IO_SYNC) { \
+			u32 ___val___; \
+			___val___ = AI2C_BUS_READ32(AI2C_DEV_BUS_ADDR(dev, \
+			AI2C_DEV_PAGE_PCIE0_PEI, AI2C_PEI_CONFIG), \
+			AI2C_DEV_ACCESS_LITTLE_ENDIAN); \
+		} \
+	} while (0);
+
+#define AI2C_DEV_BUS_WRITE16(dev, pageId, offset, value) \
+	do { \
+		AI2C_WRITE_LOG("edev_bus_write16", \
+			dev, pageId, offset, value); \
+		AI2C_BUS_WRITE16( \
+			AI2C_DEV_BUS_ADDR(dev, pageId, offset), value); \
+		if (AI2C_DEV_PAGE_FLAGS(pageId) == AI2C_IO_SYNC) { \
+			u32 ___val___; \
+			___val___ = AI2C_BUS_READ32(AI2C_DEV_BUS_ADDR(dev, \
+			AI2C_DEV_PAGE_PCIE0_PEI, AI2C_PEI_CONFIG), \
+			AI2C_DEV_ACCESS_LITTLE_ENDIAN); \
+		} \
+	} while (0);
+
+
 #endif /* __AI2C_DEV_H__ */
diff --git a/drivers/i2c/busses/ai2c/ai2c_dev_clock.c b/drivers/i2c/busses/ai2c/ai2c_dev_clock.c
index 8530231..a84774a 100644
--- a/drivers/i2c/busses/ai2c/ai2c_dev_clock.c
+++ b/drivers/i2c/busses/ai2c/ai2c_dev_clock.c
@@ -20,7 +20,7 @@
  * MA 02111-1307 USA
  */
 
-#include "ai2c_plat_pvt.h"
+#include "ai2c_plat.h"
 #include "ai2c_dev_clock_ext.h"
 
 /*
@@ -488,7 +488,7 @@ int ai2c_dev_clock_mhz(
 
 	(*clockMhz) = SYSCLK;
 
-AI2C_RETURN_LABEL
+ai2c_return:
 	return ai2cStatus;
 }
 
diff --git a/drivers/i2c/busses/ai2c/ai2c_dev_clock_ext.h b/drivers/i2c/busses/ai2c/ai2c_dev_clock_ext.h
index 6e50aa5..d036eb2 100644
--- a/drivers/i2c/busses/ai2c/ai2c_dev_clock_ext.h
+++ b/drivers/i2c/busses/ai2c/ai2c_dev_clock_ext.h
@@ -27,7 +27,7 @@
 #ifndef _AI2C_DEV_CLOCK_EXT_H_
 #define _AI2C_DEV_CLOCK_EXT_H_
 
-#include "ai2c_dev_pvt.h"
+#include "ai2c_dev.h"
 
 /**************************************************************************
 * Support Functions APIs                                                  *
diff --git a/drivers/i2c/busses/ai2c/ai2c_mod.c b/drivers/i2c/busses/ai2c/ai2c_mod.c
index de2167a..2882668 100644
--- a/drivers/i2c/busses/ai2c/ai2c_mod.c
+++ b/drivers/i2c/busses/ai2c/ai2c_mod.c
@@ -52,7 +52,7 @@
 #define CONFIG_I2C
 */
 
-#include "ai2c_plat_pvt.h"
+#include "ai2c_bus.h"
 #include "regs/ai2c_cfg_node_reg_defines.h"
 #include "regs/ai2c_cfg_node_regs.h"
 #include "asm/lsi/acp_ncr.h"
@@ -102,7 +102,7 @@ static struct ai2c_priv *ai2cState;
 
 struct local_state {
 	struct i2c_adapter	  adapter;
-	struct i2c_client	   *client;
+	struct i2c_client	  *client;
 };
 
 static  struct local_state *ai2cModState;
@@ -114,7 +114,7 @@ static  struct local_state *ai2cModState;
 static int ai2c_master_xfer(
 	struct i2c_adapter  *adap,
 	struct i2c_msg       msgs[],
-	int		  num)
+	int		     num)
 {
 	u32  regionId = (u32) i2c_get_adapdata(adap);
 	struct ai2c_priv	 *priv = ai2cState;
@@ -135,8 +135,8 @@ static int ai2c_master_xfer(
 			strcat(buf, "mstRead:");
 #endif /* DATA_STREAM_DEBUG */
 
-			err = priv->pages[i].api->rdFn(priv, regionId,
-			adap, &msgs[i], stop);
+			err = priv->busCfg->api->rdFn(priv, regionId,
+						      adap, &msgs[i], stop);
 
 #ifdef DATA_STREAM_DEBUG
 			for (j = 0; j < msgs[i].len; j++) {
@@ -162,12 +162,12 @@ static int ai2c_master_xfer(
 			printk(KERN_INFO "%s\n", buf);
 #endif /* DATA_STREAM_DEBUG */
 
-			err = priv->pages[i].api->wrFn(priv, regionId,
-				adap, &msgs[i], stop);
+			err = priv->busCfg->api->wrFn(priv, regionId,
+						      adap, &msgs[i], stop);
 		}
 	}
 
-AI2C_RETURN_LABEL
+ai2c_return:
 	AI2C_LOG(AI2C_MSG_EXIT, ">>>Exit ai2c_master_xfer %d\n", err);
 	return err;
 }
@@ -189,82 +189,99 @@ static const struct i2c_algorithm ai2c_algorithm = {
  * Device Probe/Setup
  *****************************************************************************/
 
-#ifdef AI2C_PLATFORM_BUILD
 static int __devinit ai2c_probe(struct platform_device *pdev)
-#else
-static int __devinit ai2c_init(void)
-#endif
 {
-	int  ai2cStatus = AI2C_ST_SUCCESS;
-	struct ai2c_priv	 *priv = NULL;
-	int			  i;
+	int                     ai2cStatus = AI2C_ST_SUCCESS;
+	struct ai2c_priv	*priv = NULL;
+	struct axxia_i2c_bus_platform_data  *pdata;
+	u32                     busNdx;
+	u32                     rid;
 
 	/* Initialization of externals, initial state */
 	AI2C_MSG_TRACE_LEVEL = (AI2C_MSG_INFO | AI2C_MSG_ERROR);
 	ai2c_chip_ver = -1;
-	ai2cState = NULL;
 
 	AI2C_LOG(AI2C_MSG_ENTRY, ">>>Enter ai2c_probe/init\n");
 
-	AI2C_CALL(ai2c_memSetup(&priv));
-	ai2cState = priv;
+	/* Global state across all of the same kind of platforms */
+	if (ai2cState == NULL) {
+		AI2C_CALL(ai2c_stateSetup(&priv));
+		ai2cState = priv;
+	} else {
+		priv = ai2cState;
+	}
 
-	/* Hook up bus driver(s) and devices to tree */
-	ai2cModState =
-		ai2c_malloc(priv->numActiveBusses * sizeof(struct local_state));
-	if (!ai2cModState) {
-		ai2cStatus = -ENOMEM;
-		goto exit_release;
+	/* State memory for each instance of the platform */
+	if (ai2cModState == NULL) {
+		ai2cModState =
+			ai2c_malloc(priv->numActiveBusses *
+				    sizeof(struct local_state));
+		if (!ai2cModState) {
+			ai2cStatus = -ENOMEM;
+			goto exit_release;
+		}
+		memset(ai2cModState, 0,
+			priv->numActiveBusses * sizeof(struct local_state));
 	}
-	memset(ai2cModState, 0,
-		priv->numActiveBusses * sizeof(struct local_state));
 
-	for (i = 0; i < priv->numActiveBusses; i++) {
-		u32 rid;
+	/* Associate this platform with the correct bus entry */
+	AI2C_CALL(ai2c_memSetup(pdev, priv));
+	pdata = (struct axxia_i2c_bus_platform_data *) pdev->dev.platform_data;
+	busNdx = pdata->index;
 
-		if (priv->pages[i].busName == NULL)
-			continue;
+	/* Hook up bus driver(s) and devices to tree */
+	if ((busNdx > (priv->numActiveBusses-1)) ||
+	    (priv->pages[busNdx].busName == NULL)) {
+		printk(KERN_ERR
+			"Invalid description for adding I2C adapter [%d]\n",
+			busNdx);
+		goto exit_release;
+	}
+	if (ai2cModState[busNdx].adapter.algo != NULL) {
+		printk(KERN_ERR
+			"Duplicate I2C bus %d description found\n", busNdx);
+		goto exit_release;
+	}
 
-		rid = ai2c_page_to_region(priv, priv->pages[i].pageId);
-		i2c_set_adapdata(&ai2cModState[i].adapter, (void *)rid);
+	rid = ai2c_page_to_region(priv, priv->pages[busNdx].pageId);
+	i2c_set_adapdata(&ai2cModState[busNdx].adapter, (void *)rid);
 
-		snprintf(ai2cModState[i].adapter.name,
-			sizeof(ai2cModState[i].adapter.name),
-			"%s", ai2cState->pages[i].busName);
-		ai2cModState[i].adapter.algo = &ai2c_algorithm;
-		ai2cModState[i].adapter.owner = THIS_MODULE;
-		ai2cModState[i].adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
-		ai2cModState[i].adapter.retries = 3;
+	snprintf(ai2cModState[busNdx].adapter.name,
+		sizeof(ai2cModState[busNdx].adapter.name),
+		"%s", ai2cState->pages[busNdx].busName);
+	ai2cModState[busNdx].adapter.algo = &ai2c_algorithm;
+	ai2cModState[busNdx].adapter.owner = THIS_MODULE;
+	ai2cModState[busNdx].adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+	ai2cModState[busNdx].adapter.retries = 3;
 		/* Retry up to 3 times on lost
 		 * arbitration */
-#ifdef AI2C_PLATFORM_BUILD
-		ai2cModState[i].adapter.dev.parent = &pdev->dev;
-#else
-		ai2cModState[i].adapter.dev.parent  = NULL;
-#endif
-		ai2cModState[i].adapter.dev.of_node = NULL;
-
-		/* Add I2C adapter to I2C tree */
-		ai2cStatus = i2c_add_adapter(&ai2cModState[i].adapter);
-		if (ai2cStatus) {
-			printk(KERN_ERR "Failed to add I2C adapter [%d]\n", i);
-			goto exit_release;
-		}
-
-		/* Any detailed bus-specific initialization */
-		ai2cStatus = priv->pages[i].api->initFn(priv, rid);
-		if (ai2cStatus)
-			goto exit_release;
+	ai2cModState[busNdx].adapter.dev.parent = &pdev->dev;
+	ai2cModState[busNdx].adapter.dev.of_node = NULL;
+
+	/* Add I2C adapter to I2C tree */
+	if (priv->pages[busNdx].bus_nr != (~0)) {
+		ai2cModState[busNdx].adapter.nr = priv->pages[busNdx].bus_nr;
+		ai2cStatus =
+			i2c_add_numbered_adapter(&ai2cModState[busNdx].adapter);
+	} else {
+		ai2cStatus = i2c_add_adapter(&ai2cModState[busNdx].adapter);
+	}
+	if (ai2cStatus) {
+		printk(KERN_ERR "Failed to add I2C adapter [%d]\n", busNdx);
+		goto exit_release;
 	}
 
-#ifdef AI2C_PLATFORM_BUILD
+	/* Any detailed bus-specific initialization */
+	ai2cStatus = priv->busCfg->api->initFn(priv, rid);
+	if (ai2cStatus)
+		goto exit_release;
+
 	platform_set_drvdata(pdev, priv);
-#endif
 
 	AI2C_LOG(AI2C_MSG_EXIT, ">>>Exit ai2c_probe/init %d\n", 0);
 	return 0;
 
-AI2C_RETURN_LABEL
+ai2c_return:
 	if (ai2cStatus != -ENOMEM)
 		ai2cStatus = -ENOSYS;
 
@@ -275,11 +292,7 @@ exit_release:
 	return ai2cStatus;
 }
 
-#ifdef AI2C_PLATFORM_BUILD
 static int __devexit ai2c_remove(struct platform_device *dev)
-#else
-static void __devexit ai2c_exit(void)
-#endif
 {
 	int	 i;
 
@@ -302,21 +315,15 @@ static void __devexit ai2c_exit(void)
 		ai2c_memDestroy(ai2cState);
 	}
 
-#ifdef AI2C_PLATFORM_BUILD
 	platform_set_drvdata(dev, NULL);
-#endif
 
 	AI2C_LOG(AI2C_MSG_EXIT, ">>>Exit ai2c_remove/exit %d\n", 0);
 
-#ifdef AI2C_PLATFORM_BUILD
 	return 0;
-#endif
 }
 
 /* ------------------------------------------------------------------------- */
 
-#ifdef AI2C_PLATFORM_BUILD
-
 #define ai2c_suspend	NULL
 #define ai2c_resume	NULL
 
@@ -344,8 +351,6 @@ static void __exit ai2c_exit(void)
 	platform_driver_unregister(&ai2c_driver);
 }
 
-#endif  /* AI2C_PLATFORM_BUILD */
-
 module_init(ai2c_init);
 module_exit(ai2c_exit);
 
diff --git a/drivers/i2c/busses/ai2c/ai2c_plat.c b/drivers/i2c/busses/ai2c/ai2c_plat.c
index c1f5837..b9c2bf4 100644
--- a/drivers/i2c/busses/ai2c/ai2c_plat.c
+++ b/drivers/i2c/busses/ai2c/ai2c_plat.c
@@ -50,7 +50,7 @@
 #define AI2C_CHIP_VER=<verNum>
 */
 
-#include "ai2c_plat_pvt.h"
+#include "ai2c_bus.h"
 #include "regs/ai2c_cfg_node_reg_defines.h"
 #include "regs/ai2c_cfg_node_regs.h"
 #include "asm/lsi/acp_ncr.h"
@@ -64,199 +64,56 @@
  *
  * IMPORTANT: ALL BUS GROUPINGS MUST BE MAINTAINED
  */
-/* Note: This table now contains the length of the block for wrap checking
- *       and such (when implemented).  Note that each table is arranged in
- *       order of the "AI2C_DEV_PAGE_xxx" enumeration.
- */
-static struct ai2c_dev_page ai2c_dev_page_34xx[AI2C_DEV_PAGE_END_MARKER] = {
-	/* Begin: I2C_0 */
-	{
-		AI2C_DEV_PAGE_I2C_0, "AXXIA_I2C", 0x02000403000ULL,
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_I2CBUS, &ai2c_acp3400_cfg
-	},
-	{
-		AI2C_DEV_PAGE_END_MARKER, NULL, 0x00000000000ULL, 0, 0,
-		AI2C_PAGE_FLAGS_NONE, NULL
-	},
-	{
-		AI2C_DEV_PAGE_END_MARKER, NULL, 0x00000000000ULL, 0, 0,
-		AI2C_PAGE_FLAGS_NONE, NULL
-	},
-	{
-		AI2C_DEV_PAGE_END_MARKER, NULL, 0x00000000000ULL, 0, 0,
-		AI2C_PAGE_FLAGS_NONE, NULL
-	},
-	{
-		AI2C_DEV_PAGE_GPIO_0, NULL, 0x02000400000ULL, /*aka APB1/GPIO0*/
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
-	},
-	{
-		AI2C_DEV_PAGE_RESET_CTRL, NULL, 0x02000003800ULL,
-		AI2C_DEV_SIZE_1KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
-	},
+static struct ai2c_dev_page_s ai2c_dev_page[AI2C_DEV_PAGE_END_MARKER] = {
 	{
-		AI2C_DEV_PAGE_TIMER, NULL, 0x02000408000ULL,
+		AI2C_DEV_PAGE_I2C_0, "AXXIA_I2C0", 0, 0x00000000000ULL,
 		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
+		AI2C_PAGE_FLAGS_I2CBUS, NULL,
 	},
 	{
-		AI2C_DEV_PAGE_GPREG, NULL, 0x0200040C000ULL,
+		AI2C_DEV_PAGE_I2C_1, "AXXIA_I2C1", 0, 0x00000000000ULL,
 		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
+		AI2C_PAGE_FLAGS_I2CBUS, NULL,
 	},
-	/* End: I2C_0 */
-};
-
-static struct ai2c_dev_page ai2c_dev_page_25xx[AI2C_DEV_PAGE_END_MARKER] = {
-	/* Begin: I2C_0, I2C_1 */
 	{
-		AI2C_DEV_PAGE_I2C_0, "AXXIA_I2C0", 0x02000427000ULL,
+		AI2C_DEV_PAGE_I2C_2, "AXXIA_I2C2", 0, 0x00000000000ULL,
 		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_I2CBUS, &ai2c_acp3400_cfg
+		AI2C_PAGE_FLAGS_I2CBUS, NULL,
 	},
 	{
-		AI2C_DEV_PAGE_I2C_1, "AXXIA_I2C1", 0x02000428000ULL,
+		AI2C_DEV_PAGE_I2C_3, "AXXIA_SMB", 0, 0x00000000000ULL,
 		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_I2CBUS, &ai2c_acp3400_cfg},
-	{
-		AI2C_DEV_PAGE_END_MARKER, NULL, 0x00000000000ULL, 0, 0,
-		AI2C_PAGE_FLAGS_NONE, NULL
+		AI2C_PAGE_FLAGS_I2CBUS, NULL,
 	},
 	{
-		AI2C_DEV_PAGE_END_MARKER, NULL, 0x00000000000ULL, 0, 0,
-		AI2C_PAGE_FLAGS_NONE, NULL
-	},
-	{
-		AI2C_DEV_PAGE_GPIO_0, NULL, 0x02000420000ULL,/*aka APB1/GPIO0*/
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
+		AI2C_DEV_PAGE_END_MARKER, NULL, 0, 0x00000000000ULL, 0, 0,
+		AI2C_PAGE_FLAGS_NONE, NULL,
 	},
 	{
-		AI2C_DEV_PAGE_RESET_CTRL, NULL, 0x02000005c00ULL,
-		AI2C_DEV_SIZE_1KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
+		AI2C_DEV_PAGE_END_MARKER, NULL, 0, 0x00000000000ULL, 0, 0,
+		AI2C_PAGE_FLAGS_NONE, NULL,
 	},
 	{
-		AI2C_DEV_PAGE_TIMER, NULL, 0x02000429000ULL,
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
+		AI2C_DEV_PAGE_END_MARKER, NULL, 0, 0x00000000000ULL, 0, 0,
+		AI2C_PAGE_FLAGS_NONE, NULL,
 	},
 	{
-		AI2C_DEV_PAGE_GPREG, NULL, 0x02000400000ULL,
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
+		AI2C_DEV_PAGE_END_MARKER, NULL, 0, 0x00000000000ULL, 0, 0,
+		AI2C_PAGE_FLAGS_NONE, NULL,
 	},
-	/* End: I2C_0, I2C_1 */
 };
 
-static struct ai2c_dev_page ai2c_dev_page_55xx[AI2C_DEV_PAGE_END_MARKER] = {
-	/* Begin: I2C_0, I2C_1, I2C_2, I2C_3 (SMB) */
-	{
-		AI2C_DEV_PAGE_I2C_0, "AXXIA_I2C0", 0x02010084000ULL,
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_I2CBUS, &ai2c_axm5500_cfg
-	},
-	{
-		AI2C_DEV_PAGE_I2C_1, "AXXIA_I2C1", 0x02010085000ULL,
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_I2CBUS, &ai2c_axm5500_cfg
-	},
-	{
-		AI2C_DEV_PAGE_I2C_2, "AXXIA_I2C2", 0x02010086000ULL,
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_I2CBUS, &ai2c_axm5500_cfg
-	},
-	{
-		AI2C_DEV_PAGE_I2C_3, "AXXIA_SMB", 0x02010087000ULL,
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_I2CBUS, &ai2c_axm5500_cfg
-	},
-	{
-		AI2C_DEV_PAGE_GPIO_0, NULL, 0x02010092000ULL, /*aka APB1/GPIO1*/
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
-	},
-	{
-		AI2C_DEV_PAGE_RESET_CTRL, NULL, 0x02022060000ULL,
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
-	},
-	{
-		AI2C_DEV_PAGE_TIMER, NULL, 0x02010091000ULL,
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
-	},
-	{
-		AI2C_DEV_PAGE_GPREG, NULL, 0x02010094000ULL,
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
-	},
-	/* End: I2C_1 */
+static struct ai2c_dev_chip_entry_s ai2c_chip_id[] = {
+	{ AI2C_CHIP_ACP55xx, "AXM55xx", 4, &ai2c_axm5500_cfg, },
+	{ AI2C_CHIP_ACP35xx, "AXM35xx", 3, &ai2c_axm5500_cfg, },
 };
 
-static struct ai2c_dev_page ai2c_dev_page_35xx[AI2C_DEV_PAGE_END_MARKER] = {
-	/* Begin: I2C_0 */
-	{
-		AI2C_DEV_PAGE_I2C_0, "AXXIA_I2C0", 0x02000426000ULL,
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_I2CBUS, &ai2c_axm5500_cfg
-	},
-	{
-		AI2C_DEV_PAGE_I2C_1, "AXXIA_I2C1", 0x02000427000ULL,
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_I2CBUS, &ai2c_axm5500_cfg
-	},
-	{
-		AI2C_DEV_PAGE_I2C_2, "AXXIA_I2C2", 0x02000428000ULL,
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_I2CBUS, &ai2c_axm5500_cfg
-	},
-	{
-		AI2C_DEV_PAGE_END_MARKER, NULL, 0x00000000000ULL, 0, 0,
-		AI2C_PAGE_FLAGS_NONE, NULL
-	},
-	{
-		AI2C_DEV_PAGE_GPIO_0, NULL, 0x02000420000ULL, /*aka APB1/GPIO0*/
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
-	},
-	{
-		AI2C_DEV_PAGE_RESET_CTRL, NULL, 0x02000003800ULL,
-		AI2C_DEV_SIZE_1KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
-	},
-	{
-		AI2C_DEV_PAGE_TIMER, NULL, 0x02000429000ULL,
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
-	},
-	{
-		AI2C_DEV_PAGE_GPREG, NULL, 0x02000400000ULL,
-		AI2C_DEV_SIZE_4KB, AI2C_DEV_ACCESS_LITTLE_ENDIAN,
-		AI2C_PAGE_FLAGS_NONE, NULL
-	},
-	/* End: I2C_0 */
-};
-
-static struct ai2c_dev_page_entry ai2c_dev_page_index[] = {
-	{ AI2C_CHIP_ACP34xx, "ACP34xx", FALSE, ai2c_dev_page_34xx, 2, },
-	{ AI2C_CHIP_ACP32xx, "ACP32xx", FALSE, ai2c_dev_page_34xx, 2, },
-	{ AI2C_CHIP_ACP25xx, "ACP25xx", FALSE, ai2c_dev_page_25xx, 2, },
-	{ AI2C_CHIP_ACP55xx, "AXM55xx", TRUE, ai2c_dev_page_55xx, 4, },
-	{ AI2C_CHIP_ACP35xx, "AXM35xx", TRUE, ai2c_dev_page_35xx, 3, },
-};
-
-static int ai2c_dev_page_index_cnt = sizeof(ai2c_dev_page_index) /
-				     sizeof(struct ai2c_dev_page_entry);
+static u32 ai2c_chip_id_count = sizeof(ai2c_chip_id)/
+				sizeof(struct ai2c_dev_chip_entry_s);
 
 	/* Region Map
-	 *   Note: Must be same number of entries (and in same order) in the
-	 *	 arrays of type 'ai2c_dev_page_entry_t' above.  Note that
-	 *	 each table is arranged in order of the "AI2C_DEV_PAGE_xxx"
-	 *	 enumeration.
+	 *   Note: Must be same number of entries (and in same order) as
+	 *	 the "AI2C_DEV_PAGE_xxx" enumeration.
 	 */
 
 static struct ai2c_access_map ai2cDummyRegionMap[] = AI2C_DUMMY_REGION_MAP_INIT;
@@ -385,7 +242,8 @@ int ai2c_dev_direct_read(
 		for (i = 0; i < count; i++, busAddr += 4, offset += 4) {
 			buffer[i] = AI2C_BUS_READ32(busAddr, endianness);
 			AI2C_MSG(AI2C_MSG_IOR,
-				"direct_read: region=%x offset = %llx busAddr=%lx v=%x\n",
+				"direct_read: region=%x offset = %llx "
+				"busAddr=%lx v=%x\n",
 				region->regionId, offset, busAddr, buffer[i]);
 		}
 		break;
@@ -457,7 +315,8 @@ int ai2c_dev_direct_write(
 		for (i = 0; i < count; i++, busAddr += 4, offset += 4) {
 			AI2C_BUS_WRITE32(busAddr, buffer[i], endianness);
 			AI2C_MSG(AI2C_MSG_IOW,
-				"direct_write: region=%x offset=%llx busAddr=%lx v=%x\n",
+				"direct_write: region=%x offset=%llx "
+				"busAddr=%lx v=%x\n",
 				region->regionId, offset, busAddr, buffer[i]);
 		}
 		break;
@@ -468,7 +327,8 @@ int ai2c_dev_direct_write(
 			for (i = 0; i < count; i++, busAddr += 2) {
 				AI2C_BUS_WRITE16(busAddr, buf16[i], endianness);
 				AI2C_MSG(AI2C_MSG_IOW,
-					"direct_write: region=%x offset=%llx busAddr=%lx v=%x\n",
+					"direct_write: region=%x offset=%llx "
+					"busAddr=%lx v=%x\n",
 					region->regionId,
 					offset, busAddr, buf16[i]);
 			}
@@ -480,7 +340,8 @@ int ai2c_dev_direct_write(
 			for (i = 0; i < count; i++, busAddr++) {
 				AI2C_BUS_WRITE8(busAddr, buf8[i]);
 				AI2C_MSG(AI2C_MSG_IOW,
-					"direct_write: region=%x offset=%llx busAddr=%lx v=%x\n",
+					"direct_write: region=%x offset=%llx "
+					"busAddr=%lx v=%x\n",
 					region->regionId,
 					offset, busAddr, buf8[i]);
 			}
@@ -622,9 +483,10 @@ int ai2c_dev_dcr_write(
 
 static int ai2c_getChipType(struct ai2c_priv *priv)
 {
-	int                  ai2cStatus = AI2C_ST_SUCCESS;
+	int            ai2cStatus = AI2C_ST_SUCCESS;
+	u32	       i;
 #ifdef CONFIG_LSI_UBOOTENV
-	ai2c_bool_t                has_ECID = TRUE;
+	ai2c_bool_t    has_ECID = TRUE;
 	u32	       rev_reg;
 	u32	       pt_reg;
 	ai2c_cfg_node_node_cfg_r_t  node_cfg;
@@ -707,20 +569,32 @@ static int ai2c_getChipType(struct ai2c_priv *priv)
 	}
 #endif
 
-	AI2C_LOG(AI2C_MSG_INFO, "AI2C %d.%d.%d %s\n",
+	for (i = 0; i < ai2c_chip_id_count; i++) {
+		if (ai2c_chip_id[i].chipType == priv->hw_rev.chipType) {
+			priv->busCfg = &ai2c_chip_id[i];
+			priv->numActiveBusses = ai2c_chip_id[i].numActiveBusses;
+		}
+	}
+	if (priv->busCfg == NULL) {
+		ai2cStatus = -ENXIO;
+		goto ai2c_return;
+	}
+
+	AI2C_LOG(AI2C_MSG_INFO, "%s %d.%d.%d %s\n",
+		priv->busCfg->chipName,
 		priv->hw_rev.chipType, priv->hw_rev.chipVersion,
 		priv->hw_rev.packageType,
 		(priv->hw_rev.isFpga) ? "FPGA" : "ASIC");
 
-AI2C_RETURN_LABEL
+ai2c_return:
 	return ai2cStatus;
 }
 
-int ai2c_memSetup(struct ai2c_priv **outPriv)
+int ai2c_stateSetup(
+    struct ai2c_priv           **outPriv)
 {
-	int           ai2cStatus = AI2C_ST_SUCCESS;
+	int                     ai2cStatus = AI2C_ST_SUCCESS;
 	struct ai2c_priv        *priv = NULL;
-	int                 i;
 
 	/* Now for the private memory for this module. */
 	priv = ai2c_malloc(sizeof(struct ai2c_priv));
@@ -737,71 +611,115 @@ int ai2c_memSetup(struct ai2c_priv **outPriv)
 	if (ai2cStatus != AI2C_ST_SUCCESS)
 		goto ai2c_return;
 
-	/* What is the page mapping scheme for this platform? */
-	for (i = 0; i < ai2c_dev_page_index_cnt; i++) {
+ai2c_return:
+	if (ai2cStatus != AI2C_ST_SUCCESS)
+		(*outPriv) = NULL;
+	else
+		(*outPriv) = priv;
+
+	return ai2cStatus;
+}
 
-		if (ai2c_dev_page_index[i].chipType == priv->hw_rev.chipType) {
-			priv->pages = ai2c_dev_page_index[i].pages;
-			priv->busCfg = &ai2c_dev_page_index[i];
-			priv->numActiveBusses =
-				ai2c_dev_page_index[i].numActiveBusses;
-		}
-	}
-	if (priv->pages == NULL) {
+int ai2c_memSetup(
+    struct platform_device      *pdev,
+    struct ai2c_priv            *priv)
+{
+	int                     ai2cStatus = AI2C_ST_SUCCESS;
+	struct axxia_i2c_bus_platform_data  *pdata;
+	u32                     busNdx;
+	int                     i;
+
+	/* Where is the current I2C device found on this platform? */
+	pdata = (struct axxia_i2c_bus_platform_data *) pdev->dev.platform_data;
+	if (pdata == NULL) {
 		AI2C_LOG(AI2C_MSG_ERROR,
-			"Can't select memory cfg for chip ver %d\n",
-			priv->hw_rev.chipType);
+			"Can't find platform-specific data!\n");
+		ai2cStatus = -ENXIO;
+		goto ai2c_return;
+	}
+	busNdx = pdata->index;
+
+	priv->pages = ai2c_dev_page;
+
+	if (busNdx > (priv->numActiveBusses-1)) {
+		AI2C_LOG(AI2C_MSG_ERROR, "Invalid I2C bus index (%d)\n",
+			busNdx);
 		ai2cStatus = -ENXIO;
 		goto ai2c_return;
 	}
 
+	priv->pages[busNdx].busName = &pdata->name[0];
+	priv->pages[busNdx].bus_nr  = pdata->bus_nr;
+	priv->pages[busNdx].busAddr = pdata->dev_space.start;
+	priv->pages[busNdx].size    =
+		pdata->dev_space.end - pdata->dev_space.start + 1;
+	priv->pages[busNdx].pdata   = pdata;
+
+	AI2C_LOG(AI2C_MSG_DEBUG,
+		"[%d] ba=0x%010llx (%llx, %llx) sz=0x%x\n",
+		busNdx,
+		priv->pages[busNdx].busAddr,
+		pdata->dev_space.start, pdata->dev_space.end,
+		priv->pages[busNdx].size);
+
+	/*
+	* Interrupt for this bus is in priv->pdata[i].int_space.start
+	*/
+
+
 	/*
 	* Program Address Map driver tables
-	*   Set up the base offsets for SRIO RAB and GRIO access via paged
-	*   PLB access.
 	*/
-	priv->pageAddr =
-		ai2c_malloc(AI2C_DEV_PAGE_END_MARKER * sizeof(u32));
 	if (priv->pageAddr == NULL) {
-		AI2C_LOG(AI2C_MSG_ERROR,
-			"Could not allocate AI2C pageAddr memory!\n");
-		ai2cStatus = -ENOMEM;
-		goto ai2c_return;
+		priv->pageAddr =
+			ai2c_malloc(AI2C_DEV_PAGE_END_MARKER * sizeof(u32));
+		if (priv->pageAddr == NULL) {
+			AI2C_LOG(AI2C_MSG_ERROR,
+				"Could not allocate AI2C pageAddr memory!\n");
+			ai2cStatus = -ENOMEM;
+			goto ai2c_return;
+		}
+		memset(priv->pageAddr, 0,
+			AI2C_DEV_PAGE_END_MARKER * sizeof(u32));
 	}
-	memset(priv->pageAddr, 0,
-		AI2C_DEV_PAGE_END_MARKER * sizeof(u32));
+
 	for (i = 0; i < AI2C_DEV_PAGE_END_MARKER; i++) {
 
-		if (priv->pages[i].pageId != AI2C_DEV_PAGE_END_MARKER) {
-			priv->pageAddr[i] =
-				(u32) ioremap(priv->pages[i].busAddr,
-			priv->pages[i].size);
-			if (priv->pageAddr[i] == 0) {
-				AI2C_LOG(AI2C_MSG_ERROR,
-					"Could not ioremap AI2C pageAddr memory %d!\n",
-					i);
-				ai2cStatus = -ENOMEM;
-				goto ai2c_return;
-
-			} else {
-
-				AI2C_LOG(AI2C_MSG_DEBUG,
-					"Map page %d (%08x) / %llx for %x => %x\n",
-					priv->pages[i].pageId,
-					ai2c_page_to_region(priv,
-					priv->pages[i].pageId),
-					(unsigned long long)
-						priv->pages[i].busAddr,
-					priv->pages[i].size,
-					priv->pageAddr[i]);
-			}
+		if (priv->pageAddr[i] ||
+		    (priv->pages[i].busAddr == 0) ||
+		    (priv->pages[i].size == 0) ||
+		    (priv->pages[i].pageId == AI2C_DEV_PAGE_END_MARKER))
+			continue;
+
+		priv->pageAddr[i] =
+			(u32) ioremap(priv->pages[i].busAddr,
+					priv->pages[i].size);
+		if (priv->pageAddr[i] == 0) {
+			AI2C_LOG(AI2C_MSG_ERROR,
+				"Could not ioremap AI2C pageAddr memory %d!\n",
+				i);
+			AI2C_LOG(AI2C_MSG_DEBUG,
+				"ba=0x%010llx sz=0x%x\n",
+				priv->pages[i].busAddr,
+				priv->pages[i].size);
+			ai2cStatus = -ENOMEM;
+			goto ai2c_return;
+		} else {
+			AI2C_LOG(AI2C_MSG_DEBUG,
+				"Map page %d (%08x) / %llx for %x => %x\n",
+				priv->pages[i].pageId,
+				ai2c_page_to_region(priv,
+						priv->pages[i].pageId),
+				(unsigned long long) priv->pages[i].busAddr,
+				priv->pages[i].size,
+				priv->pageAddr[i]);
 		}
 	}
 
 	AI2C_SPINLOCK_INIT(&priv->regLock);
 	AI2C_SPINLOCK_INIT(&priv->ioLock);
 
-AI2C_RETURN_LABEL
+ai2c_return:
 
 	if (ai2cStatus != AI2C_ST_SUCCESS) {
 		if (priv) {
@@ -809,14 +727,13 @@ AI2C_RETURN_LABEL
 				for (i = 0; i < AI2C_DEV_PAGE_END_MARKER; i++)
 					if (priv->pageAddr[i] != 0)
 						iounmap(
-						    (void __iomem *)priv->pageAddr[i]);
+						    (void __iomem *)
+						    priv->pageAddr[i]);
 				ai2c_free(priv->pageAddr);
 			}
 			ai2c_free(priv);
 		}
-		(*outPriv) = NULL;
-	} else
-		(*outPriv) = priv;
+	}
 
 	return ai2cStatus;
 }
@@ -824,13 +741,13 @@ AI2C_RETURN_LABEL
 int ai2c_memDestroy(struct ai2c_priv *inPriv)
 {
 	int	    ai2cStatus = AI2C_ST_SUCCESS;
-	int             i;
+	int         i;
 
 	if (inPriv) {
 		if (inPriv->pageAddr) {
 			for (i = 0; i < AI2C_DEV_PAGE_END_MARKER; i++)
 				if (inPriv->pageAddr[i] != 0)
-					iounmap((void __iomem *)inPriv->pageAddr[i]);
+					iounmap((void *)inPriv->pageAddr[i]);
 
 			ai2c_free(inPriv->pageAddr);
 		}
diff --git a/drivers/i2c/busses/ai2c/ai2c_plat.h b/drivers/i2c/busses/ai2c/ai2c_plat.h
index faad41b..54e6c5b 100644
--- a/drivers/i2c/busses/ai2c/ai2c_plat.h
+++ b/drivers/i2c/busses/ai2c/ai2c_plat.h
@@ -24,10 +24,12 @@
 #define _AI2C_LINUX_H_
 
 #include <linux/i2c.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/i2c-axxia.h>
 
 #include "ai2c_sal.h"
-#include "ai2c_dev_pvt.h"
+#include "ai2c_dev.h"
 
 /**************************************************************************
 * Constants                                                               *
@@ -170,22 +172,22 @@ enum {
 #define AI2C_PAGE_FLAGS_NONE            (0x00000000)
 #define AI2C_PAGE_FLAGS_I2CBUS          (0x00000001)
 
-struct ai2c_dev_page {
+struct ai2c_dev_page_s {
 	int    pageId;
 	char   *busName;
+	u32    bus_nr;
 	u64    busAddr; /* 38-bit PCI address */
 	u32    size;
 	u32    endianness;
 	u32    flags;
-	struct ai2c_i2c_access *api;
+	struct axxia_i2c_bus_platform_data  *pdata;
 };
 
-struct ai2c_dev_page_entry {
+struct ai2c_dev_chip_entry_s {
 	u32	chipType;
 	char	*chipName;
-	bool	supportDsFns;
-	struct ai2c_dev_page *pages;
 	u32	numActiveBusses;
+	struct ai2c_i2c_access *api;
 };
 
 
@@ -200,12 +202,11 @@ struct ai2c_priv {
 	struct ai2c_rev_id hw_rev;
 
 	/* Static configuration describing selected ACP I2C bus region */
-	struct ai2c_dev_page_entry *busCfg;
-	/* Per module default config */
-	u32 numActiveBusses;
+	struct ai2c_dev_chip_entry_s *busCfg;
 
 	/* Memory Mapping/Management constructs */
-	struct ai2c_dev_page *pages;
+	u32 numActiveBusses;
+	struct ai2c_dev_page_s *pages;
 	/* Per module memory pages */
 
 	/* Memory indexing support to reach selected ACP regions */
@@ -279,5 +280,57 @@ int ai2c_dev_dcr_write(
 	u32     cmdType,
 	u32     xferWidth);
 
+/*****************************************************************************
+* Externally Visible Function Prototypes				     *
+*****************************************************************************/
+
+/*! @fn u32 ai2c_page_to_region(struct ai2c_priv *priv,
+ *                                           u32 pageId);
+ *  @brief Map a memory page handle to a regionId handle.
+    @param[in] inPriv Created device state structure
+    @param[in] inPageId Original page id to be mapped
+    @Returns mapped value
+ */
+extern u32 ai2c_page_to_region(struct ai2c_priv *priv, u32 pageId);
+
+/*! @fn u32 *ai2c_region_lookup(struct ai2c_priv *priv,
+ *                                           u32 regionId);
+ *  @brief Map a memory region handle to a region description structure.
+    @param[in] inPriv Created device state structure
+    @param[in] inRegionId Original region id to be mapped
+    @Returns mapped value
+ */
+extern struct ai2c_region_io *ai2c_region_lookup(
+	struct ai2c_priv *priv,
+	u32 regionId);
+
+/*! @fn int ai2c_stateSetup(struct ai2c_priv **outPriv);
+    @brief This is a one time initialization for the state linking all
+	   of the I2C protocol layers to be called by the device
+	   initialization step.
+    @param[out] outPriv Created device state structure
+    @Returns success/failure status of the operation
+*/
+extern int ai2c_stateSetup(struct ai2c_priv       **outPriv);
+
+/*! @fn int ai2c_memSetup(struct platform_device *pdev,
+			  struct ai2c_priv *priv);
+    @brief This is a per-device to-be-mapped setup for the I2C protocol
+	   layers to be called by the device initialization step.
+    @param[in] inPDev Source platform device data strucure
+    @param[in] inPriv Created device state structure
+    @Returns success/failure status of the operation
+*/
+extern int ai2c_memSetup(struct platform_device *pdev,
+			 struct ai2c_priv       *priv);
+
+/*! @fn int ai2c_memDestroy(struct ai2c_priv  *inPriv);
+    @brief This function will release resources acquired for the specified
+	   I2C device driver.
+    @param[in] inPriv Created device state structure
+    @Returns success/failure status of the operation
+*/
+extern int ai2c_memDestroy(struct ai2c_priv *inPriv);
+
 
 #endif /* _AI2C_PLAT_H_ */
diff --git a/drivers/i2c/busses/ai2c/ai2c_sal.c b/drivers/i2c/busses/ai2c/ai2c_sal.c
index 9b1ea7a..ceda0fa 100644
--- a/drivers/i2c/busses/ai2c/ai2c_sal.c
+++ b/drivers/i2c/busses/ai2c/ai2c_sal.c
@@ -37,10 +37,11 @@ void *ai2c_malloc(size_t size)
 	if (size <= 0) {
 #ifdef AI2C_DEBUG
 		AI2C_MSG(AI2C_MSG_DEBUG,
-			"WARNING: ai2c_malloc(%d) passed a zero or less size.\n",
+			"WARNING: ai2c_malloc(%d) passed a zero or "
+			"less size.\n",
 			size);
 #endif
-	return NULL;
+	return 0;
 	}
 
 	p = __ai2c_malloc(size);
@@ -57,10 +58,11 @@ void *ai2c_calloc(size_t no, size_t size)
 	if (size <= 0 || no <= 0) {
 #ifdef AI2C_DEBUG
 		AI2C_MSG(AI2C_MSG_DEBUG,
-			"WARNING: ai2c_calloc(no=%d, size=%d) passed a zero or less size.\n",
+			"WARNING: ai2c_calloc(no=%d, size=%d) "
+			"passed a zero or less size.\n",
 			no, size);
 #endif
-		return NULL;
+		return 0;
 	}
 
 	p = __ai2c_calloc(no, size);
@@ -76,10 +78,11 @@ void *ai2c_realloc(void *ptr, size_t size)
 	if (size <= 0) {
 #ifdef AI2C_DEBUG
 		AI2C_MSG(AI2C_MSG_DEBUG,
-			"WARNING: ai2c_realloc(%d) passed a zero or less size.\n",
+			"WARNING: ai2c_realloc(%d) passed a zero or "
+			"less size.\n",
 			size);
 #endif
-		return NULL;
+		return 0;
 	}
 
 	ptr = __ai2c_realloc(ptr, size);
diff --git a/drivers/i2c/busses/ai2c/ai2c_sal.h b/drivers/i2c/busses/ai2c/ai2c_sal.h
index 4a39867..bbfd2f9 100644
--- a/drivers/i2c/busses/ai2c/ai2c_sal.h
+++ b/drivers/i2c/busses/ai2c/ai2c_sal.h
@@ -27,11 +27,352 @@
 #ifndef __AI2C_SAL_H__
 #define __AI2C_SAL_H__
 
-#include "ai2c_sal_types.h"
+#include <generated/autoconf.h>
+
+#ifdef __KERNEL__
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/cdev.h>
+#include <linux/of_platform.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/wait.h>
+#include <asm/pgtable.h>
+
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/spinlock.h>
+#include <linux/signal.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+
+#include <linux/version.h>
+
+#include <linux/time.h>
+#include <linux/fcntl.h>
+#include <linux/unistd.h>
+#include <linux/errno.h>
+#include <linux/mman.h>
+
+#include <asm/byteorder.h>
+
+#else
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#endif
+
+#include "ai2c_types.h"
 #include "ai2c_dev.h"
-#include "ai2c_sal_linux.h"
 
-/* should not be in sal */
+
+/**************************************************************************
+* Some Constants
+**************************************************************************/
+
+#ifdef __BIG_ENDIAN
+#undef  AI2C_BIG_ENDIAN
+#define AI2C_BIG_ENDIAN	  9999
+#undef  AI2C_LITTLE_ENDIAN
+#endif
+
+#ifdef __LITTLE_ENDIAN
+#undef  AI2C_BIG_ENDIAN
+#undef  AI2C_LITTLE_ENDIAN
+#define AI2C_LITTLE_ENDIAN      9998
+#endif
+
+/**************************************************************************
+* Macros
+**************************************************************************/
+
+/*
+* AI2C_MSG
+*
+*   Print a message to the system console.
+*/
+#ifdef __KERNEL__
+
+#define AI2C_MSG(type, fmt, args...)				         \
+	do {							         \
+		if ((type) & AI2C_MSG_TRACE_LEVEL) {			 \
+			if ((type) == AI2C_MSG_ERROR)			 \
+				printk(KERN_ERR AI2C_MOD_NAME ": ERROR: "); \
+			else						 \
+				printk(KERN_WARNING AI2C_MOD_NAME ": "); \
+			printk(fmt, ## args);				 \
+		}							 \
+	} while (0)
+
+#else
+
+#define AI2C_MSG(type, fmt, args...)				         \
+	do {							         \
+		if ((type) & AI2C_MSG_TRACE_LEVEL) {			 \
+			if ((type) == AI2C_MSG_ERROR)			 \
+				printf("[Error] " AI2C_MOD_NAME ": ERROR: "); \
+			else						 \
+				printf("[Warning] " AI2C_MOD_NAME ": "); \
+			printf(fmt, ## args);				 \
+		}							 \
+	} while (0)
+
+#endif
+
+    /*
+     * AI2C_LOG
+     *
+     *   Print a message to the system log device and/or console. This
+     *   interface is callable from interrupt level.
+     */
+#define AI2C_LOG \
+	AI2C_MSG
+
+#ifndef AI2C_MSG_TRACE_LEVEL
+#define AI2C_MSG_TRACE_LEVEL     ai2c_trace_level
+#endif
+
+extern int AI2C_MSG_TRACE_LEVEL;
+
+
+/*
+* Endian-ness Conversion
+*/
+
+#define AI2C_SWAP16m(n) \
+	((((u16)(n) >>  8) & 0x00ff) |  \
+	(((u16)(n) <<  8) & 0xff00))
+
+#define AI2C_SWAP32m(n) \
+	((((u32)(n) >> 24) & 0x000000ff) |  \
+	(((u32)(n) >>  8) & 0x0000ff00) |  \
+	(((u32)(n) <<  8) & 0x00ff0000) |  \
+	(((u32)(n) << 24) & 0xff000000))
+
+#define SWAP16(x)	\
+	{ { \
+		u16 val = x; \
+		AI2C_SWAP16m(val); \
+	} }
+
+#define SWAP32(x)	\
+	{ { \
+		u32 val = x; \
+		AI2C_SWAP32m(val); \
+	} }
+
+
+/*
+* Endian-ness I/O
+*/
+
+#ifdef CONFIG_ARM
+
+#define in_be8(x)		(*x)
+#define in_be16(x)		AI2C_SWAP16m(*x)
+#define in_be32(x)		AI2C_SWAP32m(*x)
+
+#define in_le8(x)		(*x)
+#define in_le16(x)		(*x)
+#define in_le32(x)		(*x)
+
+#define out_be8(a, v)	        (*a) = (v)
+#define out_be16(a, v)	        (*a) = AI2C_SWAP16m(v)
+#define out_be32(a, v)	        (*a) = AI2C_SWAP32m(v)
+
+#define out_le8(a, v)	        (*a) = (v)
+#define out_le16(a, v)	        (*a) = (v)
+#define out_le32(a, v)	        (*a) = (v)
+
+#endif  /* CONFIG_ARM */
+
+
+#define AI2C_EDEV_BUS_ENFORCE_ORDERING()
+
+#define AI2C_BUS_READ8(addr) \
+	readb((u8 *) (addr))
+
+#define AI2C_BUS_READ16_ENDIAN(endian, addr) \
+	in_##endian##16((u16 __iomem *) (addr))
+
+
+#define AI2C_BUS_READ16_LE(addr) AI2C_BUS_READ16_ENDIAN(le, addr)
+
+#define AI2C_BUS_READ16_BE(addr) AI2C_BUS_READ16_ENDIAN(be, addr)
+
+#define AI2C_BUS_READ16(addr, endian) \
+	(endian == AI2C_DEV_ACCESS_BIG_ENDIAN) ?   \
+		AI2C_BUS_READ16_BE(addr) : AI2C_BUS_READ16_LE(addr)
+
+#define AI2C_BUS_READ32_ENDIAN(endian, addr) \
+	in_##endian##32((u32 __iomem *) (addr))
+
+
+#define AI2C_BUS_READ32_LE(addr) AI2C_BUS_READ32_ENDIAN(le, addr)
+
+#define AI2C_BUS_READ32_BE(addr) AI2C_BUS_READ32_ENDIAN(be, addr)
+
+#define AI2C_BUS_READ32(addr, endian) \
+	(endian == AI2C_DEV_ACCESS_BIG_ENDIAN) ?   \
+	AI2C_BUS_READ32_BE(addr) : AI2C_BUS_READ32_LE(addr)
+
+
+#define AI2C_BUS_WRITE8(addr, data) \
+	writeb((data), (u8 *) (addr))
+
+#define AI2C_BUS_WRITE16_ENDIAN(endian, addr, data) \
+	do { \
+		u16 *__a__ = (u16 *) addr; \
+		u16 __d__ = data; \
+		out_##endian##16((u16 __iomem *) __a__, __d__); \
+		AI2C_EDEV_BUS_ENFORCE_ORDERING(); \
+	} while (0);
+
+#define AI2C_BUS_WRITE16_LE(addr, data) \
+	AI2C_BUS_WRITE16_ENDIAN(le, addr, data)
+
+#define AI2C_BUS_WRITE16_BE(addr, data) \
+	AI2C_BUS_WRITE16_ENDIAN(be, addr, data)
+
+#define AI2C_BUS_WRITE16(addr, data, endian) \
+	do { \
+		if (endian == AI2C_DEV_ACCESS_BIG_ENDIAN) {  \
+			AI2C_BUS_WRITE16_BE(addr, data);    \
+		} else { \
+			AI2C_BUS_WRITE16_LE(addr, data);    \
+		} \
+	} while (0);
+
+#define AI2C_BUS_WRITE32_ENDIAN(endian, addr, data) \
+	do { \
+		u32 *__a__ = (u32 *) addr; \
+		u32 __d__ = data; \
+		out_##endian##32((u32 __iomem *) __a__, __d__); \
+		AI2C_EDEV_BUS_ENFORCE_ORDERING(); \
+	} while (0);
+
+#define AI2C_BUS_WRITE32_LE(addr, data) \
+	AI2C_BUS_WRITE32_ENDIAN(le, addr, data)
+
+#define AI2C_BUS_WRITE32_BE(addr, data) \
+	AI2C_BUS_WRITE32_ENDIAN(be, addr, data)
+
+#define AI2C_BUS_WRITE32(addr, data, endian) \
+	do { \
+		if (endian == AI2C_DEV_ACCESS_BIG_ENDIAN) {  \
+			AI2C_BUS_WRITE32_BE(addr, data);    \
+		} else {			            \
+			AI2C_BUS_WRITE32_LE(addr, data);    \
+		} \
+	} while (0);
+
+    /*
+    * Spinlock mutex stuff
+    */
+
+#define AI2C_SPINLOCK_INIT(pSpinlock) \
+	spin_lock_init(pSpinlock)
+
+#define AI2C_SPINLOCK_LOCK(pSpinlock) \
+	spin_lock(pSpinlock)
+
+#define AI2C_SPINLOCK_TRYLOCK(pSpinlock) \
+	spin_trylock(pSpinlock)
+
+#define AI2C_SPINLOCK_UNLOCK(pSpinlock) \
+	spin_unlock(pSpinlock)
+
+#define AI2C_SPINLOCK_INTERRUPT_DISABLE(pSem, flags) \
+	spin_lock_irqsave(pSem, flags)
+
+#define AI2C_SPINLOCK_INTERRUPT_ENABLE(pSem, flags) \
+	spin_unlock_irqrestore(pSem, flags)
+
+#define AI2C_SPINLOCK_SW_INTERRUPT_DISABLE(pSem, flags) \
+	spin_lock_bh(pSem)
+
+#define AI2C_SPINLOCK_SW_INTERRUPT_ENABLE(pSem, flags) \
+	spin_unlock_bh(pSem)
+
+
+#ifdef __KERNEL__
+    /*
+    * Kernel memory allocation
+    */
+
+#define __ai2c_malloc(size)		kmalloc(size, GFP_KERNEL)
+#define __ai2c_free(ptr)		   kfree(ptr)
+#define __ai2c_realloc(ptr, size)	 (NULL)
+#define __ai2c_calloc(no, size)	   kcalloc(no, size, GFP_KERNEL)
+
+#else
+
+    /*
+    * User space memory allocation
+    */
+
+#define __ai2c_malloc(size)		malloc(size)
+#define __ai2c_free(ptr)		free(ptr)
+#define __ai2c_realloc(ptr, size)	(NULL)
+#define __ai2c_calloc(no, size)	        calloc(no, size)
+
+#endif
+
+
+    /*
+    * Miscellaneous externs not provided by other headers reliably
+    */
+
+extern int snprintf(char *s, size_t n, const char *format, ...);
+
+struct ai2c_rev_id {
+
+#ifdef NCP_BIG_ENDIAN
+	unsigned isAsic:1;
+	unsigned isFpga:1;
+	unsigned isSim:1;
+	unsigned:2;
+	unsigned secDisable:1;
+	unsigned sppDisable:1;
+	unsigned cpuDisable:4;
+	unsigned ecidChipType:5;
+	unsigned:1;
+	unsigned packageType:4;
+	unsigned chipVersion:6;
+	unsigned chipTyp:5;
+#else
+	unsigned chipType:5;
+	unsigned chipVersion:6;
+	unsigned packageType:4;
+	unsigned:1;
+	unsigned ecidChipType:5;
+	unsigned cpuDisable:4;
+	unsigned sppDisable:1;
+	unsigned secDisable:1;
+	unsigned:2;
+	unsigned isSim:1;
+	unsigned isFpga:1;
+	unsigned isAsic:1;
+#endif
+};
+
+
+/**************************************************************************
+* More Macros
+**************************************************************************/
+
+/* Should this be in sal? */
 #ifndef MIN
 #define MIN(a, b)	((a) < (b) ? (a) : (b))
 #endif
@@ -40,6 +381,10 @@
 #define MAX(a, b)	((a) > (b) ? (a) : (b))
 #endif
 
+/**************************************************************************
+* Function Prototypes
+**************************************************************************/
+
 extern void *ai2c_malloc(size_t size);
 extern void *ai2c_realloc(void *ptr, size_t size);
 extern void *ai2c_calloc(size_t no, size_t size);
diff --git a/drivers/i2c/busses/ai2c/ai2c_types.h b/drivers/i2c/busses/ai2c/ai2c_types.h
index c748823..a0c04da 100644
--- a/drivers/i2c/busses/ai2c/ai2c_types.h
+++ b/drivers/i2c/busses/ai2c/ai2c_types.h
@@ -23,6 +23,48 @@
 #ifndef AI2C_TYPES_H
 #define AI2C_TYPES_H
 
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+
+#else
+
+#define u64     unsigned long long
+#define u32     unsigned long
+#define s32     signed long
+#define size_t  int
+
+#define AI2C_U32        unsigned long
+
+#define ai2c_uint8_t    unsigned char
+#define ai2c_uint16_t   unsigned short
+#define ai2c_uint32_t   unsigned long
+#define ai2c_uint64_t   unsigned long long
+#define ai2c_int8_t     signed char
+#define ai2c_int16_t    signed short
+#define ai2c_int32_t    signed long
+#define ai2c_int64_t    signed long long
+#define ai2c_bool_t     unsigned short
+#define ai2c_size_t     signed long
+
+#endif
+
+/**************************************************************************
+* Constants, #Defines, etc.
+**************************************************************************/
+
+#ifndef NULL
+#define NULL    0
+#endif
+
+#ifndef TRUE
+#define TRUE    1
+#endif
+
+#ifndef FALSE
+#define FALSE   0
+#endif
+
 /**************************************************************************
  * ACP chip types
  *
@@ -36,9 +78,9 @@
 #define AI2C_CHIP_ACP34xx	1
 #define AI2C_CHIP_ACP32xx	2
 #define AI2C_CHIP_ACP25xx	6
-#define AI2C_CHIP_ACP25xx_V2     7
+#define AI2C_CHIP_ACP25xx_V2    7
 
-#define AI2C_CHIP_X3X7_HYBRID    7       /* TEMP HACK */
+#define AI2C_CHIP_X3X7_HYBRID   7       /* TEMP HACK */
 
 #define AI2C_CHIP_ACP55xx	9       /* AXM55xx, aka X7 */
 #define AI2C_CHIP_ACP35xx       16       /* AXM35xx, aka X3 */
@@ -73,12 +115,4 @@
 	} while (0);
 
 
-/*
- * A general purpose way to eliminate warnings due the the label
- * not being referenced.
- */
-#define AI2C_RETURN_LABEL \
-	goto ai2c_return; \
-ai2c_return:
-
 #endif  /* AI2C_TYPES_H */
-- 
1.8.3




More information about the linux-yocto mailing list