Merge pull request #131 from causten/dropbear

Upgrade to Dropbear 71
diff --git a/README.md b/README.md
index 0df0ad4..7f9a2a7 100644
--- a/README.md
+++ b/README.md
@@ -4,19 +4,21 @@
 
 ## Building ##
 
-OpenBMC uses Yocto/Open-Embedded for a build system, which supports an 
+OpenBMC uses Yocto/Open-Embedded for a build system, which supports an
 out-of-tree build.  It is recommended that you create an empty directory
 somewhere to hold the build.  This directory will get big.
 
 On Ubuntu 14.04 the following packages are required to build the default target
-```
-sudo apt-get install -y git build-essential libsdl1.2-dev texinfo gawk chrpath diffstat
-```
+
+    sudo apt-get install -y git build-essential libsdl1.2-dev texinfo gawk chrpath diffstat
+
+On Fedora 23 the following packages are required to build the default target:
+
+    sudo dnf install -y git patch diffstat texinfo chrpath SDL-devel bitbake
+    sudo dnf groupinstall "C Development Tools and Libraries"
 
 To start a build:
 
-```
     cd <builddir>
     . <repodir>/openbmc-env
     bitbake obmc-phosphor-image
-```
diff --git a/meta-openbmc-bsp/meta-aspeed/meta-ast2400/recipes-bsp/u-boot/u-boot_2013.07%.bbappend b/meta-openbmc-bsp/meta-aspeed/meta-ast2400/recipes-bsp/u-boot/u-boot_2013.07%.bbappend
index 6d4a18f..12fddbf 100644
--- a/meta-openbmc-bsp/meta-aspeed/meta-ast2400/recipes-bsp/u-boot/u-boot_2013.07%.bbappend
+++ b/meta-openbmc-bsp/meta-aspeed/meta-ast2400/recipes-bsp/u-boot/u-boot_2013.07%.bbappend
@@ -1,10 +1,6 @@
 FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
 
-#SRC_URI += "file://fw_env.config
-SRC_URI += "file://patch-2013.07/0000-u-boot-aspeed-064.patch \
-           file://patch-2013.07/0001-u-boot-openbmc.patch \
-           file://config.patch \
-           "
+SRC_URI += "file://config.patch"
 
 # Do not install u-boot in rootfs
 #do_install[postfuncs] += "remove_uboot_from_rootfs"
diff --git a/meta-openbmc-machines/meta-openpower/meta-rackspace/meta-barreleye/recipes-kernel/linux/linux-obmc/barreleye.cfg b/meta-openbmc-machines/meta-openpower/meta-rackspace/meta-barreleye/recipes-kernel/linux/linux-obmc/barreleye.cfg
deleted file mode 100644
index 0f96507..0000000
--- a/meta-openbmc-machines/meta-openpower/meta-rackspace/meta-barreleye/recipes-kernel/linux/linux-obmc/barreleye.cfg
+++ /dev/null
@@ -1 +0,0 @@
-CONFIG_SENSORS_OCC=y
diff --git a/meta-openbmc-machines/meta-openpower/meta-rackspace/meta-barreleye/recipes-kernel/linux/linux-obmc/barreleye.dts b/meta-openbmc-machines/meta-openpower/meta-rackspace/meta-barreleye/recipes-kernel/linux/linux-obmc/barreleye.dts
deleted file mode 100644
index 3b5e0f1..0000000
--- a/meta-openbmc-machines/meta-openpower/meta-rackspace/meta-barreleye/recipes-kernel/linux/linux-obmc/barreleye.dts
+++ /dev/null
@@ -1 +0,0 @@
-# use in-tree devtree
diff --git a/meta-openbmc-machines/meta-openpower/meta-rackspace/meta-barreleye/recipes-kernel/linux/linux-obmc/occ_hwmon.patch b/meta-openbmc-machines/meta-openpower/meta-rackspace/meta-barreleye/recipes-kernel/linux/linux-obmc/occ_hwmon.patch
deleted file mode 100644
index 612214d..0000000
--- a/meta-openbmc-machines/meta-openpower/meta-rackspace/meta-barreleye/recipes-kernel/linux/linux-obmc/occ_hwmon.patch
+++ /dev/null
@@ -1,1565 +0,0 @@
-diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
-index e13c902..38aff0c 100644
---- a/drivers/hwmon/Kconfig
-+++ b/drivers/hwmon/Kconfig
-@@ -1167,6 +1167,13 @@ config SENSORS_NCT7904
- 	  This driver can also be built as a module.  If so, the module
- 	  will be called nct7904.
- 
-+config SENSORS_OCC
-+	tristate "OCC sensor driver for IBM Power CPU"
-+	depends on I2C
-+	help
-+	  If you say yes here you get support for driver to read sensors in 
-+	  IBM Power CPU On-Chip-Controller. module will be called occ.
-+
- config SENSORS_PCF8591
- 	tristate "Philips PCF8591 ADC/DAC"
- 	depends on I2C
-diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
-index 9e0f3dd..53dc3b3 100644
---- a/drivers/hwmon/Makefile
-+++ b/drivers/hwmon/Makefile
-@@ -123,6 +123,7 @@ obj-$(CONFIG_SENSORS_NCT6775)	+= nct6775.o
- obj-$(CONFIG_SENSORS_NCT7802)	+= nct7802.o
- obj-$(CONFIG_SENSORS_NCT7904)	+= nct7904.o
- obj-$(CONFIG_SENSORS_NTC_THERMISTOR)	+= ntc_thermistor.o
-+obj-$(CONFIG_SENSORS_OCC)	+= occ.o
- obj-$(CONFIG_SENSORS_PC87360)	+= pc87360.o
- obj-$(CONFIG_SENSORS_PC87427)	+= pc87427.o
- obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
-diff --git a/drivers/hwmon/occ.c b/drivers/hwmon/occ.c
-new file mode 100644
-index 0000000..f265ff3
---- /dev/null
-+++ b/drivers/hwmon/occ.c
-@@ -0,0 +1,1529 @@
-+/*
-+ * Open BMC OCC HWMON driver - read Power8 OCC (On Chip Controller) sensor data via i2c.
-+ *
-+ * Copyright (c) 2015 IBM (Alvin Wang, Li Yi)
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/jiffies.h>
-+#include <linux/i2c.h>
-+#include <linux/hwmon.h>
-+#include <linux/hwmon-sysfs.h>
-+#include <linux/err.h>
-+#include <linux/mutex.h>
-+#include <linux/of.h>
-+#include <linux/delay.h>
-+
-+//#define DEBUG    1
-+
-+/* ------------------------------------------------------------*/
-+/* OCC sensor data format */
-+typedef struct {
-+	uint16_t sensor_id;
-+	uint16_t value;
-+} occ_sensor;
-+
-+typedef struct {
-+	uint16_t sensor_id;
-+	uint32_t update_tag;
-+	uint32_t accumulator;
-+	uint16_t value;
-+} powr_sensor;
-+
-+typedef struct {
-+	uint16_t curr_powercap;
-+	uint16_t curr_powerreading;
-+	uint16_t norm_powercap;
-+	uint16_t max_powercap;
-+	uint16_t min_powercap;
-+	uint16_t user_powerlimit;
-+} caps_sensor;
-+
-+typedef struct {
-+	char sensor_type[5];
-+	uint8_t reserved0;
-+	uint8_t sensor_format;
-+	uint8_t sensor_length;
-+	uint8_t num_of_sensors;
-+	occ_sensor *sensor;
-+	powr_sensor *powr;
-+	caps_sensor *caps;
-+} sensor_data_block;
-+
-+typedef struct {
-+	uint8_t status;
-+	uint8_t ext_status;
-+	uint8_t occs_present;
-+	uint8_t config;
-+	uint8_t occ_state;
-+	uint8_t reserved0;
-+	uint8_t reserved1;
-+	uint8_t error_log_id;
-+	uint32_t error_log_addr_start;
-+	uint16_t error_log_length;
-+	uint8_t reserved2;
-+	uint8_t reserved3;
-+	char occ_code_level[17];
-+	char sensor_eye_catcher[7];
-+	uint8_t num_of_sensor_blocks;
-+	uint8_t sensor_data_version;
-+	sensor_data_block* blocks;
-+} occ_poll_data;
-+
-+typedef struct {
-+	uint8_t sequence_num;
-+	uint8_t cmd_type;
-+	uint8_t rtn_status;
-+	uint16_t data_length;
-+	occ_poll_data data;
-+	uint16_t chk_sum;
-+	int temp_block_id;
-+	int freq_block_id;
-+	int power_block_id;
-+	int caps_block_id;
-+} occ_response_t;
-+
-+//static occ_response_t occ_resp;
-+
-+/* Each client has this additional data */
-+struct occ_drv_data {
-+	struct i2c_client	*client;
-+	struct device		*hwmon_dev;
-+	struct mutex		update_lock;
-+	char			valid;		/* !=0 if sensor data are valid */
-+	unsigned long		last_updated;	/* In jiffies */
-+	unsigned long		sample_time;	/* Mininum timer interval for sampling In jiffies */
-+	occ_response_t		occ_resp;
-+};
-+
-+/*-----------------------------------------------------------------------*/
-+/* i2c read and write occ sensors */
-+
-+#define OCC_DATA_MAX 4096 /* 4KB at most */
-+#define I2C_STATUS_REG 0x000d0001
-+#define I2C_ERROR_REG  0x000d0002
-+#define I2C_READ_ERROR 1
-+#define I2C_WRITE_ERROR 2
-+#define I2C_DATABUFFER_SIZE_ERROR 3
-+
-+/*
-+#define SCOM_OCC_SRAM_WOX  0x0006B013
-+#define SCOM_OCC_SRAM_WAND 0x0006B012
-+#define SCOM_OCC_SRAM_ADDR 0x0006B010
-+#define SCOM_OCC_SRAM_DATA 0x0006B015
-+*/
-+
-+// To generate attn to OCC
-+#define ATTN_DATA                0x0006B035
-+
-+// For BMC to read/write SRAM
-+#define OCB_ADDRESS              0x0006B070
-+#define OCB_DATA                 0x0006B075
-+#define OCB_STATUS_CONTROL_AND   0x0006B072
-+#define OCB_STATUS_CONTROL_OR    0x0006B073
-+
-+#define OCC_COMMAND_ADDR 0xFFFF6000
-+#define OCC_RESPONSE_ADDR 0xFFFF7000
-+
-+static int deinit_occ_resp_buf(occ_response_t *p)
-+{
-+	int b;
-+
-+	if (p == NULL)
-+		return 0;
-+
-+	if (p->data.blocks == NULL)
-+		return 0;
-+
-+	for(b = 0; b < p->data.num_of_sensor_blocks; b++) {
-+		if (!p->data.blocks[b].sensor)
-+			kfree(p->data.blocks[b].sensor);
-+		if (!p->data.blocks[b].powr)
-+			kfree(p->data.blocks[b].powr);
-+		if (!p->data.blocks[b].caps)
-+			kfree(p->data.blocks[b].caps);
-+	}
-+
-+	kfree(p->data.blocks);
-+
-+	memset(p, 0, sizeof(*p));
-+
-+
-+	return 0;
-+}
-+
-+static ssize_t occ_i2c_read(struct i2c_client *client, char *buf, size_t count)
-+{
-+	int ret = 0;
-+
-+	if (count > 8192)
-+		count = 8192;
-+
-+	//printk("i2c_read: reading %zu bytes @0x%x.\n", count, client->addr);
-+	ret = i2c_master_recv(client, buf, count);
-+	return ret;
-+}
-+
-+static ssize_t occ_i2c_write(struct i2c_client *client, const char *buf, size_t count)
-+{
-+	int ret = 0;
-+
-+	if (count > 8192)
-+		count = 8192;
-+
-+	//printk("i2c_write: writing %zu bytes @0x%x.\n", count, client->addr);
-+	ret = i2c_master_send(client, buf, count);
-+	return ret;
-+}
-+
-+/* read two 4-byte value */
-+static int occ_getscom(struct i2c_client *client, uint32_t address, uint32_t *value0, uint32_t *value1)
-+{
-+	uint32_t ret = 0;
-+	char buf[8];
-+	const char* address_buf = (const char*)&address;
-+
-+	//P8 i2c slave requires address to be shifted by 1
-+	address = address << 1;
-+
-+	ret = occ_i2c_write(client, address_buf, sizeof(address));
-+	/* FIXME: ast i2c driver does not read corret value */
-+	//if (ret != sizeof(address))
-+	//	return -I2C_WRITE_ERROR;
-+
-+	ret = occ_i2c_read(client, buf, sizeof(buf));
-+	//if (ret != sizeof(buf))
-+	//	return -I2C_READ_ERROR;
-+
-+	memcpy(value1, &buf[0], sizeof(*value1));
-+	memcpy(value0, &buf[4], sizeof(*value0));
-+
-+	return 0;
-+}
-+
-+/* read 8-byte value and put into data[offset] */
-+static int occ_getscomb(struct i2c_client *client, uint32_t address, char* data, int offset)
-+{
-+	uint32_t ret = 0;
-+	const char* address_buf = (const char*)&address;
-+	char buf[8];
-+	int b = 0;
-+
-+	//P8 i2c slave requires address to be shifted by 1
-+	address = address << 1;
-+
-+	ret = occ_i2c_write(client, address_buf, sizeof(address));
-+	//if (ret != sizeof(address))
-+	//	return -I2C_WRITE_ERROR;
-+
-+	ret = occ_i2c_read(client, buf, sizeof(buf));
-+	//if (ret != sizeof(buf))
-+	//	return -I2C_READ_ERROR;
-+
-+	for (b = 0; b < 8; b++) {
-+		data[offset + b] = buf[7 - b];
-+	}
-+
-+	return 0;
-+}
-+
-+static int occ_putscom(struct i2c_client *client, uint32_t address, uint32_t data0, uint32_t data1)
-+{
-+	const char* address_buf = (const char*)&address;
-+	const char* d0 = (const char*)&data0;
-+	const char* d1 = (const char*)&data1;
-+	char buf[12];
-+	uint32_t ret = 0;
-+
-+	//P8 i2c slave requires address to be shifted by 1
-+	address = address << 1;
-+
-+	memcpy(&buf[0], address_buf, sizeof(address));
-+	memcpy(&buf[4], d1, sizeof(data1));
-+	memcpy(&buf[8],	d0, sizeof(data0));
-+
-+	ret = occ_i2c_write(client, buf, sizeof(buf));
-+	//if (ret != sizeof(buf))
-+	//	return I2C_WRITE_ERROR;
-+
-+	return 0;
-+}
-+
-+static int occ_check_i2c_errors(struct i2c_client *client)
-+{
-+	uint32_t v0;
-+	uint32_t v1;
-+
-+	occ_getscom(client, I2C_STATUS_REG, &v0, &v1);
-+	if (v0 != 0x80000000) {
-+		printk("ERROR present in P8 I2C Slave.  Clearing...\n");
-+		occ_putscom(client, I2C_ERROR_REG, 0x00000000, 0x00000000);
-+		occ_putscom(client, I2C_STATUS_REG, 0x00000000, 0x00000000);
-+		return -1;
-+	}
-+
-+	return 0;
-+}
-+
-+
-+static inline uint16_t get_occdata_length(char* d)
-+{
-+	uint16_t data_length = 0;
-+
-+	data_length = d[3] << 8;
-+	data_length = data_length | d[4];
-+	return data_length;
-+}
-+
-+
-+static int parse_occ_response(char* d, occ_response_t* o)
-+{
-+	int b = 0;
-+	int s = 0;
-+	int ret = 0;
-+	int dnum = 45;
-+
-+	o->sequence_num = d[0];
-+	o->cmd_type = d[1];
-+	o->rtn_status = d[2];
-+	o->data_length = d[3] << 8;
-+	o->data_length = o->data_length | d[4];
-+	o->data.status = d[5];
-+	o->data.ext_status = d[6];
-+	o->data.occs_present = d[7];
-+	o->data.config = d[8];
-+	o->data.occ_state = d[9];
-+	o->data.reserved0 = d[10];
-+	o->data.reserved1 = d[11];
-+	o->data.error_log_id = d[12];
-+	o->data.error_log_addr_start = d[13] << 24;
-+	o->data.error_log_addr_start = o->data.error_log_addr_start | d[14] << 16;
-+	o->data.error_log_addr_start = o->data.error_log_addr_start | d[15] << 8;
-+	o->data.error_log_addr_start = o->data.error_log_addr_start | d[16];
-+	o->data.error_log_length = d[17] << 8;
-+	o->data.error_log_length = o->data.error_log_length | d[18];
-+	o->data.reserved2 = d[19];
-+	o->data.reserved3 = d[20];
-+	strncpy(&o->data.occ_code_level[0], (const char*)&d[21], 16);
-+	strncpy(&o->data.sensor_eye_catcher[0], (const char*)&d[37], 6);
-+	o->data.sensor_eye_catcher[6]='\0';
-+	o->data.num_of_sensor_blocks=d[43];
-+	o->data.sensor_data_version = d[44];
-+
-+	if (strcmp(o->data.sensor_eye_catcher, "SENSOR") != 0) {
-+		printk("ERROR: SENSOR not found at byte 37 (%s)\n",o->data.sensor_eye_catcher);
-+		return -1;
-+	}
-+
-+	if (o->data.num_of_sensor_blocks == 0) {
-+		printk("ERROR: SENSOR block num is 0\n");
-+		return -1;
-+	}
-+
-+	o->data.blocks = kzalloc(sizeof(sensor_data_block) * o->data.num_of_sensor_blocks, GFP_KERNEL);
-+	if (o->data.blocks == NULL)
-+		return -ENOMEM;
-+
-+	//printk("Reading %d sensor blocks\n", o->data.num_of_sensor_blocks);
-+	o->temp_block_id = -1;
-+	o->freq_block_id = -1;
-+	o->power_block_id = -1;
-+	o->caps_block_id = -1;
-+	for(b = 0; b < o->data.num_of_sensor_blocks; b++) {
-+		/* 8-byte sensor block head */
-+		strncpy(&o->data.blocks[b].sensor_type[0], (const char*)&d[dnum], 4);
-+		o->data.blocks[b].reserved0 = d[dnum+4];
-+		o->data.blocks[b].sensor_format = d[dnum+5];
-+		o->data.blocks[b].sensor_length = d[dnum+6];
-+		o->data.blocks[b].num_of_sensors = d[dnum+7];
-+		dnum = dnum + 8;
-+
-+		//printk("sensor block[%d]: type: %s, num_of_sensors: %d, sensor_length: %u\n",
-+			//b, o->data.blocks[b].sensor_type, o->data.blocks[b].num_of_sensors,
-+			//o->data.blocks[b].sensor_length);
-+
-+		/* empty sensor block */
-+		if (o->data.blocks[b].num_of_sensors <= 0)
-+			continue;
-+		if (o->data.blocks[b].sensor_length == 0)
-+			continue;
-+
-+		if (strcmp(o->data.blocks[b].sensor_type, "FREQ") == 0) {
-+			o->data.blocks[b].sensor =
-+				kzalloc(sizeof(occ_sensor) * o->data.blocks[b].num_of_sensors, GFP_KERNEL);
-+
-+			if (o->data.blocks[b].sensor == NULL) {
-+				ret = -ENOMEM;
-+				goto abort;
-+			}
-+			o->freq_block_id = b;
-+			for (s = 0; s < o->data.blocks[b].num_of_sensors; s++) {
-+				o->data.blocks[b].sensor[s].sensor_id = d[dnum] << 8;
-+				o->data.blocks[b].sensor[s].sensor_id =
-+					o->data.blocks[b].sensor[s].sensor_id | d[dnum+1];
-+				o->data.blocks[b].sensor[s].value = d[dnum+2] << 8;
-+				o->data.blocks[b].sensor[s].value = o->data.blocks[b].sensor[s].value | d[dnum+3];
-+				//printk("sensor[%d]-[%d]: id: %u, value: %u\n",
-+				//	b, s, o->data.blocks[b].sensor[s].sensor_id, o->data.blocks[b].sensor[s].value);
-+				dnum = dnum + o->data.blocks[b].sensor_length;
-+			}
-+		}
-+		else if (strcmp(o->data.blocks[b].sensor_type, "TEMP") == 0) {
-+
-+			o->data.blocks[b].sensor =
-+				kzalloc(sizeof(occ_sensor) * o->data.blocks[b].num_of_sensors, GFP_KERNEL);
-+
-+			if (o->data.blocks[b].sensor == NULL) {
-+				ret = -ENOMEM;
-+				goto abort;
-+			}
-+
-+			o->temp_block_id = b;
-+			for (s = 0; s < o->data.blocks[b].num_of_sensors; s++) {
-+				o->data.blocks[b].sensor[s].sensor_id = d[dnum] << 8;
-+				o->data.blocks[b].sensor[s].sensor_id =
-+					o->data.blocks[b].sensor[s].sensor_id | d[dnum+1];
-+				o->data.blocks[b].sensor[s].value = d[dnum+2] << 8;
-+				o->data.blocks[b].sensor[s].value = o->data.blocks[b].sensor[s].value | d[dnum+3];
-+				//printk("sensor[%d]-[%d]: id: %u, value: %u\n",
-+				//	b, s, o->data.blocks[b].sensor[s].sensor_id, o->data.blocks[b].sensor[s].value);
-+				dnum = dnum + o->data.blocks[b].sensor_length;
-+			}
-+		}
-+		else if (strcmp(o->data.blocks[b].sensor_type, "POWR") == 0) {
-+
-+			o->data.blocks[b].powr =
-+				kzalloc(sizeof(powr_sensor) * o->data.blocks[b].num_of_sensors, GFP_KERNEL);
-+
-+			if (o->data.blocks[b].powr == NULL) {
-+				ret = -ENOMEM;
-+				goto abort;
-+			}
-+			o->power_block_id = b;
-+			for (s = 0; s < o->data.blocks[b].num_of_sensors; s++) {
-+				o->data.blocks[b].powr[s].sensor_id = d[dnum] << 8;
-+				o->data.blocks[b].powr[s].sensor_id = o->data.blocks[b].powr[s].sensor_id | d[dnum+1];
-+				o->data.blocks[b].powr[s].update_tag = d[dnum+2] << 24;
-+				o->data.blocks[b].powr[s].update_tag = o->data.blocks[b].powr[s].update_tag | d[dnum+3] << 16;
-+				o->data.blocks[b].powr[s].update_tag = o->data.blocks[b].powr[s].update_tag | d[dnum+4] << 8;
-+				o->data.blocks[b].powr[s].update_tag = o->data.blocks[b].powr[s].update_tag | d[dnum+5];
-+				o->data.blocks[b].powr[s].accumulator = d[dnum+6] << 24;
-+				o->data.blocks[b].powr[s].accumulator = o->data.blocks[b].powr[s].accumulator | d[dnum+7] << 16;
-+				o->data.blocks[b].powr[s].accumulator = o->data.blocks[b].powr[s].accumulator | d[dnum+8] << 8;
-+				o->data.blocks[b].powr[s].accumulator = o->data.blocks[b].powr[s].accumulator | d[dnum+9];
-+				o->data.blocks[b].powr[s].value = d[dnum+10] << 8;
-+				o->data.blocks[b].powr[s].value = o->data.blocks[b].powr[s].value | d[dnum+11];
-+
-+				//printk("sensor[%d]-[%d]: id: %u, value: %u\n",
-+				//	b, s, o->data.blocks[b].powr[s].sensor_id, o->data.blocks[b].powr[s].value);
-+
-+				dnum = dnum + o->data.blocks[b].sensor_length;
-+			}
-+		}
-+		else if (strcmp(o->data.blocks[b].sensor_type, "CAPS") == 0) {
-+
-+			o->data.blocks[b].caps =
-+				kzalloc(sizeof(caps_sensor) * o->data.blocks[b].num_of_sensors, GFP_KERNEL);
-+
-+			if (o->data.blocks[b].caps == NULL) {
-+				ret = -ENOMEM;
-+				goto abort;
-+			}
-+			o->caps_block_id = b;
-+			for (s = 0; s < o->data.blocks[b].num_of_sensors; s++) {
-+				o->data.blocks[b].caps[s].curr_powercap = d[dnum] << 8;
-+				o->data.blocks[b].caps[s].curr_powercap = o->data.blocks[b].caps[s].curr_powercap | d[dnum+1];
-+				o->data.blocks[b].caps[s].curr_powerreading = d[dnum+2] << 8;
-+				o->data.blocks[b].caps[s].curr_powerreading = o->data.blocks[b].caps[s].curr_powerreading | d[dnum+3];
-+				o->data.blocks[b].caps[s].norm_powercap = d[dnum+4] << 8;
-+				o->data.blocks[b].caps[s].norm_powercap = o->data.blocks[b].caps[s].norm_powercap | d[dnum+5];
-+				o->data.blocks[b].caps[s].max_powercap = d[dnum+6] << 8;
-+				o->data.blocks[b].caps[s].max_powercap = o->data.blocks[b].caps[s].max_powercap| d[dnum+7];
-+				o->data.blocks[b].caps[s].min_powercap = d[dnum+8] << 8;
-+				o->data.blocks[b].caps[s].min_powercap = o->data.blocks[b].caps[s].min_powercap| d[dnum+9];
-+				o->data.blocks[b].caps[s].user_powerlimit = d[dnum+10] << 8;
-+				o->data.blocks[b].caps[s].user_powerlimit = o->data.blocks[b].caps[s].user_powerlimit| d[dnum+11];
-+
-+				dnum = dnum + o->data.blocks[b].sensor_length;
-+				//printk("CAPS sensor #%d:\n", s);
-+				//printk("curr_powercap is %x \n", o->data.blocks[b].caps[s].curr_powercap);
-+				//printk("curr_powerreading is %x \n", o->data.blocks[b].caps[s].curr_powerreading);
-+				//printk("norm_powercap is %x \n", o->data.blocks[b].caps[s].norm_powercap);
-+				//printk("max_powercap is %x \n", o->data.blocks[b].caps[s].max_powercap);
-+				//printk("min_powercap is %x \n", o->data.blocks[b].caps[s].min_powercap);
-+				//printk("user_powerlimit is %x \n", o->data.blocks[b].caps[s].user_powerlimit);
-+			}
-+
-+		}
-+		else {
-+			printk("ERROR: sensor type %s not supported\n", o->data.blocks[b].sensor_type);
-+			ret = -1;
-+			goto abort;
-+		}
-+	}
-+
-+	return 0;
-+abort:
-+	deinit_occ_resp_buf(o);
-+	return ret;
-+}
-+
-+/* used for testing */
-+char fake_occ_rsp[OCC_DATA_MAX] = {
-+0x69, 0x00, 0x00, 0x00, 0xa4, 0xc3, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0x70, 0x5f, 0x6f, 0x63, 0x63, 0x5f, 0x31, 0x35, 0x30, 0x37,
-+0x31, 0x36, 0x61, 0x00, 0x00, 0x53, 0x45, 0x4e, 0x53, 0x4f, 0x52, 0x04, 0x01, 0x54, 0x45, 0x4d,
-+0x50, 0x00, 0x01, 0x04, 0x0a, 0x00 ,0x6a, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x6d, 0x00,
-+0x00,0x00,0x6e,0x00, 0x00,0x00,0x6f,0x00, 0x00,0x00,0x70,0x00, 0x00,0x00,0x71,0x00,
-+0x00,0x00,0x73,0x00, 0x00,0x00,0x74,0x00, 0x00,0x00,0x75,0x00, 0x00,0x46,0x52,0x45,
-+0x51,0x00,0x01,0x04, 0x0a,0x00,0x76,0x00, 0x00,0x00,0x78,0x00, 0x00,0x00,0x79,0x00,
-+0x00,0x00,0x7a,0x00, 0x00,0x00,0x7b,0x00, 0x00,0x00,0x7c,0x00, 0x00,0x00,0x7d,0x00,
-+0x00,0x00,0x7f,0x00, 0x00,0x00,0x80,0x00, 0x00,0x00,0x81,0x00, 0x00,0x50,0x4f,0x57,
-+0x52,0x00,0x01,0x0c, 0x00,0x43,0x41,0x50, 0x53,0x00,0x01,0x0c, 0x01,0x00,0x00,0x00,
-+0x00,0x04,0xb0,0x09, 0x60,0x04,0x4c,0x00, 0x00,0x17,0xc5,};
-+
-+//#define DUMP_RAW 1
-+
-+static int occ_get_all(struct i2c_client *client, occ_response_t *occ_resp)
-+{
-+	char occ_data[OCC_DATA_MAX];
-+	uint16_t num_bytes = 0;
-+	int b = 0;
-+	int ret = 0;
-+/*
-+	//Procedure to access SRAM where OCC data is located
-+	occ_putscom(client, SCOM_OCC_SRAM_WOX, 0x08000000, 0x00000000);
-+	occ_putscom(client, SCOM_OCC_SRAM_WAND, 0xFBFFFFFF, 0xFFFFFFFF);
-+	occ_putscom(client, SCOM_OCC_SRAM_ADDR, OCC_RESPONSE_ADDR, 0x00000000);
-+	occ_putscom(client, SCOM_OCC_SRAM_ADDR, OCC_RESPONSE_ADDR, 0x00000000);
-+
-+	occ_getscomb(client, SCOM_OCC_SRAM_DATA, occ_data, 0);
-+
-+*/
-+
-+	// Init OCB
-+	occ_putscom(client, OCB_STATUS_CONTROL_OR,  0x08000000, 0x00000000);
-+	occ_putscom(client, OCB_STATUS_CONTROL_AND, 0xFBFFFFFF, 0xFFFFFFFF);
-+
-+	// Send poll command to OCC
-+	occ_putscom(client, OCB_ADDRESS, OCC_COMMAND_ADDR, 0x00000000);
-+	occ_putscom(client, OCB_ADDRESS, OCC_COMMAND_ADDR, 0x00000000);
-+	occ_putscom(client, OCB_DATA, 0x00000001, 0x10001100);
-+
-+	// Trigger ATTN
-+	occ_putscom(client, ATTN_DATA, 0x01010000, 0x00000000);
-+
-+	// TODO: check command status Refere to
-+	// "1.6.2 OCC Command/Response Sequence" in OCC_OpenPwr_FW_Interfaces1.2.pdf
-+	// Use sleep as workaround
-+	//msleep(2000);
-+
-+	// Get response data
-+	occ_putscom(client, OCB_ADDRESS, OCC_RESPONSE_ADDR, 0x00000000);
-+	occ_getscomb(client, OCB_DATA, occ_data, 0);
-+
-+	/* FIXME: use fake data to test driver without hw */
-+	//printk("i2c-occ: using FAKE occ data\n");
-+	//memcpy(&occ_data[0], &fake_occ_rsp[0], sizeof(occ_data));
-+
-+	num_bytes = get_occdata_length(occ_data);
-+
-+	//printk("OCC data length: %d\n", num_bytes);
-+
-+#ifdef DUMP_RAW
-+	int i = 0;
-+	printk("\nRAW data\n==================\n");
-+	for (i = 0; i < 8; i++) {
-+		if(i == 4) printk("  ");
-+		printk("%02x", occ_data[i]);
-+	}
-+	printk("\n");
-+#endif
-+
-+	if (num_bytes > OCC_DATA_MAX) {
-+		printk("ERROR: OCC data length must be < 4KB\n");
-+		return -1;
-+	}
-+
-+	if (num_bytes <= 0) {
-+		printk("ERROR: OCC data length is zero\n");
-+		return -1;
-+	}
-+
-+	for (b = 8; b < num_bytes + 8; b = b + 8) {
-+		//occ_getscomb(client, SCOM_OCC_SRAM_DATA, occ_data, b);
-+		occ_getscomb(client, OCB_DATA, occ_data, b);
-+#ifdef DUMP_RAW
-+	for (i = 0; i < 8; i++) {
-+		if(i == 4) printk("  ");
-+		printk("%02x", occ_data[b+i]);
-+	}
-+	printk("\n");
-+#endif
-+
-+	}
-+
-+	/* FIXME: use fake data to test driver without hw */
-+	//memcpy(&occ_data[0], &fake_occ_rsp[0], sizeof(occ_data));
-+
-+	ret = parse_occ_response(occ_data, occ_resp);
-+
-+	return ret;
-+}
-+
-+
-+static int occ_update_device(struct device *dev)
-+{
-+	struct occ_drv_data *data = dev_get_drvdata(dev);
-+	struct i2c_client *client = data->client;
-+	int ret = 0;
-+
-+	mutex_lock(&data->update_lock);
-+
-+	if (time_after(jiffies, data->last_updated + data->sample_time)
-+	    || !data->valid) {
-+		deinit_occ_resp_buf(&data->occ_resp);
-+
-+		ret = occ_get_all(client, &data->occ_resp);
-+
-+		data->last_updated = jiffies;
-+		data->valid = 1;
-+	}
-+	mutex_unlock(&data->update_lock);
-+
-+	return ret;
-+}
-+
-+/* ----------------------------------------------------------------------*/
-+/* sysfs attributes for hwmon */
-+
-+static ssize_t show_occ_temp_input(struct device *hwmon_dev, struct device_attribute *da, char *buf)
-+{
-+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
-+	int n = attr->index;
-+	struct device * dev = hwmon_dev->parent;
-+	struct occ_drv_data *data = dev_get_drvdata(dev);
-+	int ret = 0;
-+	occ_sensor *sensor;
-+	int val = 0;
-+
-+	ret = occ_update_device(dev);
-+
-+	if (ret != 0)
-+	{
-+		/* FIXME: to test fake data */
-+		printk("ERROR: cannot get occ sensor data: %d\n", ret);
-+		return ret;
-+	}
-+
-+	if (data->occ_resp.data.blocks == NULL ||
-+		data->occ_resp.data.blocks[data->occ_resp.temp_block_id].sensor == NULL)
-+		return -1;
-+
-+	//printk("block_id: %d, sensor: %d\n", data->occ_resp.temp_block_id, n -1);
-+	sensor = &data->occ_resp.data.blocks[data->occ_resp.temp_block_id].sensor[n - 1];
-+	/* in millidegree Celsius */
-+	val = sensor->value * 1000;
-+	//printk("temp%d sensor value: %d\n", n, val);
-+
-+	//printk("------------- above are debug message, bellow is real output------------\n");
-+	return sprintf(buf, "%d\n", val);
-+}
-+
-+static ssize_t show_occ_temp_label(struct device *hwmon_dev, struct device_attribute *da, char *buf)
-+{
-+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
-+	int n = attr->index;
-+	struct device *dev = hwmon_dev->parent;
-+	struct occ_drv_data *data = dev_get_drvdata(dev);
-+	int ret = 0;
-+	occ_sensor *sensor;
-+	int val = 0;
-+
-+	ret = occ_update_device(dev);
-+
-+	if (ret != 0)
-+	{
-+		/* FIXME: to test fake data */
-+		printk("ERROR: cannot get occ sensor data: %d\n", ret);
-+		return ret;
-+	}
-+
-+	if (data->occ_resp.data.blocks == NULL ||
-+		data->occ_resp.data.blocks[data->occ_resp.temp_block_id].sensor == NULL)
-+		return -1;
-+
-+	//printk("temp_block_id: %d, sensor: %d\n", data->occ_resp.temp_block_id, n -1);
-+	sensor = &data->occ_resp.data.blocks[data->occ_resp.temp_block_id].sensor[n - 1];
-+	val = sensor->sensor_id;
-+	//printk("temp%d sensor id: %d\n", n, val);
-+
-+	//printk("------------- above are debug message, bellow is real output------------\n");
-+	return sprintf(buf, "%d\n", val);
-+}
-+
-+static ssize_t show_occ_power_label(struct device *hwmon_dev, struct device_attribute *da, char *buf)
-+{
-+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
-+	int n = attr->index;
-+	struct device *dev = hwmon_dev->parent;
-+	struct occ_drv_data *data = dev_get_drvdata(dev);
-+	int ret = 0;
-+	powr_sensor *sensor;
-+	int val = 0;
-+
-+	ret = occ_update_device(dev);
-+
-+	if (ret != 0)
-+	{
-+		/* FIXME: to test fake data */
-+		printk("ERROR: cannot get occ sensor data: %d\n", ret);
-+		return ret;
-+	}
-+
-+	//printk("power_block_id: %d, sensor: %d\n", data->occ_resp.power_block_id, n -1);
-+
-+	if (data->occ_resp.data.blocks == NULL ||
-+		data->occ_resp.data.blocks[data->occ_resp.power_block_id].powr == NULL)
-+		return -1;
-+
-+	sensor = &data->occ_resp.data.blocks[data->occ_resp.power_block_id].powr[n - 1];
-+	val = sensor->sensor_id;
-+	//printk("power%d sensor id: %d\n", n, val);
-+
-+	//printk("------------- above are debug message, bellow is real output------------\n");
-+	return sprintf(buf, "%d\n", val);
-+}
-+
-+
-+static ssize_t show_occ_power_input(struct device *hwmon_dev, struct device_attribute *da, char *buf)
-+{
-+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
-+	int n = attr->index;
-+	struct device *dev = hwmon_dev->parent;
-+	struct occ_drv_data *data = dev_get_drvdata(dev);
-+	int ret = 0;
-+	powr_sensor *sensor;
-+	int val = 0;
-+
-+	ret = occ_update_device(dev);
-+
-+	if (ret != 0)
-+	{
-+		/* FIXME: to test fake data */
-+		printk("ERROR: cannot get occ sensor data: %d\n", ret);
-+		return ret;
-+	}
-+
-+	//printk("power block_id: %d, sensor: %d\n", data->occ_resp.power_block_id, n -1);
-+
-+	if (data->occ_resp.data.blocks == NULL ||
-+		data->occ_resp.data.blocks[data->occ_resp.power_block_id].powr == NULL)
-+		return -1;
-+
-+
-+	sensor = &data->occ_resp.data.blocks[data->occ_resp.power_block_id].powr[n - 1];
-+	val = sensor->value;
-+	//printk("power%d sensor value: %d\n", n, val);
-+
-+	//printk("------------- above are debug message, bellow is real output------------\n");
-+	return sprintf(buf, "%d\n", val);
-+}
-+
-+
-+static ssize_t show_occ_freq_label(struct device *hwmon_dev, struct device_attribute *da, char *buf)
-+{
-+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
-+	int n = attr->index;
-+	struct device *dev = hwmon_dev->parent;
-+	struct occ_drv_data *data = dev_get_drvdata(dev);
-+	int ret = 0;
-+	occ_sensor *sensor;
-+	int val = 0;
-+
-+	ret = occ_update_device(dev);
-+
-+	if (ret != 0)
-+	{
-+		/* FIXME: to test fake data */
-+		printk("ERROR: cannot get occ sensor data: %d\n", ret);
-+		return ret;
-+	}
-+
-+	if (data->occ_resp.data.blocks == NULL ||
-+		data->occ_resp.data.blocks[data->occ_resp.freq_block_id].sensor == NULL)
-+		return -1;
-+
-+	//printk("freq_block_id: %d, sensor: %d\n", data->occ_resp.freq_block_id, n -1);
-+	sensor = &data->occ_resp.data.blocks[data->occ_resp.freq_block_id].sensor[n - 1];
-+	val = sensor->sensor_id;
-+	//printk("freq%d sensor id: %d\n", n, val);
-+
-+	//printk("------------- above are debug message, bellow is real output------------\n");
-+	return sprintf(buf, "%d\n", val);
-+}
-+
-+
-+static ssize_t show_occ_freq_input(struct device *hwmon_dev, struct device_attribute *da, char *buf)
-+{
-+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
-+	int n = attr->index;
-+	struct device *dev = hwmon_dev->parent;
-+	struct occ_drv_data *data = dev_get_drvdata(dev);
-+	int ret = 0;
-+	occ_sensor *sensor;
-+	int val = 0;
-+
-+	ret = occ_update_device(dev);
-+
-+	if (ret != 0)
-+	{
-+		/* FIXME: to test fake data */
-+		printk("ERROR: cannot get occ sensor data: %d\n", ret);
-+		return ret;
-+	}
-+
-+	if (data->occ_resp.data.blocks == NULL ||
-+		data->occ_resp.data.blocks[data->occ_resp.freq_block_id].sensor == NULL)
-+		return -1;
-+
-+	//printk("block_id: %d, sensor: %d\n", data->occ_resp.freq_block_id, n -1);
-+	sensor = &data->occ_resp.data.blocks[data->occ_resp.freq_block_id].sensor[n - 1];
-+	val = sensor->value;
-+	//printk("freq%d sensor value: %d\n", n, val);
-+
-+	//printk("------------- above are debug message, bellow is real output------------\n");
-+	return sprintf(buf, "%d\n", val);
-+}
-+
-+static ssize_t show_occ_caps(struct device *hwmon_dev, struct device_attribute *da, char *buf)
-+{
-+	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(da);
-+	int nr = attr->nr;
-+	int n = attr->index;
-+	struct device *dev = hwmon_dev->parent;
-+	struct occ_drv_data *data = dev_get_drvdata(dev);
-+	int ret = 0;
-+	caps_sensor *sensor;
-+	int val = 0;
-+
-+	ret = occ_update_device(dev);
-+	if (ret != 0)
-+	{
-+		/* FIXME: to test fake data */
-+		printk("ERROR: cannot get occ sensor data: %d\n", ret);
-+		return ret;
-+	}
-+
-+	//printk("block_id: %d, sensor: %d, nr: %d\n", data->occ_resp.caps_block_id, n - 1, nr);
-+	if (data->occ_resp.data.blocks == NULL ||
-+		data->occ_resp.data.blocks[data->occ_resp.caps_block_id].caps == NULL)
-+		return -1;
-+
-+	sensor = &data->occ_resp.data.blocks[data->occ_resp.caps_block_id].caps[n - 1];
-+
-+	switch (nr) {
-+		case 0:
-+			val = sensor->curr_powercap;
-+			break;
-+		case 1:
-+			val = sensor->curr_powerreading;
-+			break;
-+		case 2:
-+			val = sensor->norm_powercap;
-+			break;
-+		case 3:
-+			val = sensor->max_powercap;
-+			break;
-+		case 4:
-+			val = sensor->min_powercap;
-+			break;
-+		case 5:
-+			val = sensor->user_powerlimit;
-+			break;
-+		default:
-+			val = 0;
-+	}
-+
-+	//printk("caps%d sensor value: %d, nr: %d\n", n, val, nr);
-+
-+	//printk("------------- above are debug message, bellow is real output------------\n");
-+	return sprintf(buf, "%d\n", val);
-+}
-+
-+#if 0
-+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_occ_temp_input, NULL, 1);
-+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_occ_temp_input, NULL, 2);
-+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_occ_temp_input, NULL, 3);
-+static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_occ_temp_input, NULL, 4);
-+static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_occ_temp_input, NULL, 5);
-+static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_occ_temp_input, NULL, 6);
-+static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_occ_temp_input, NULL, 7);
-+static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_occ_temp_input, NULL, 8);
-+static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, show_occ_temp_input, NULL, 9);
-+static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_occ_temp_label, NULL, 1);
-+static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_occ_temp_label, NULL, 2);
-+static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, show_occ_temp_label, NULL, 3);
-+static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, show_occ_temp_label, NULL, 4);
-+static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO, show_occ_temp_label, NULL, 5);
-+static SENSOR_DEVICE_ATTR(temp6_label, S_IRUGO, show_occ_temp_label, NULL, 6);
-+static SENSOR_DEVICE_ATTR(temp7_label, S_IRUGO, show_occ_temp_label, NULL, 7);
-+static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO, show_occ_temp_label, NULL, 8);
-+static SENSOR_DEVICE_ATTR(temp9_label, S_IRUGO, show_occ_temp_label, NULL, 9);
-+
-+static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, show_occ_power_input, NULL, 1);
-+static SENSOR_DEVICE_ATTR(power1_label, S_IRUGO, show_occ_power_label, NULL, 1);
-+static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, show_occ_power_input, NULL, 2);
-+static SENSOR_DEVICE_ATTR(power2_label, S_IRUGO, show_occ_power_label, NULL, 2);
-+static SENSOR_DEVICE_ATTR(power3_input, S_IRUGO, show_occ_power_input, NULL, 3);
-+static SENSOR_DEVICE_ATTR(power3_label, S_IRUGO, show_occ_power_label, NULL, 3);
-+static SENSOR_DEVICE_ATTR(power4_input, S_IRUGO, show_occ_power_input, NULL, 4);
-+static SENSOR_DEVICE_ATTR(power4_label, S_IRUGO, show_occ_power_label, NULL, 4);
-+
-+static SENSOR_DEVICE_ATTR(freq1_input, S_IRUGO, show_occ_freq_input, NULL, 1);
-+static SENSOR_DEVICE_ATTR(freq1_label, S_IRUGO, show_occ_freq_label, NULL, 1);
-+static SENSOR_DEVICE_ATTR(freq2_input, S_IRUGO, show_occ_freq_input, NULL, 2);
-+static SENSOR_DEVICE_ATTR(freq2_label, S_IRUGO, show_occ_freq_label, NULL, 2);
-+static SENSOR_DEVICE_ATTR(freq3_input, S_IRUGO, show_occ_freq_input, NULL, 3);
-+static SENSOR_DEVICE_ATTR(freq3_label, S_IRUGO, show_occ_freq_label, NULL, 3);
-+static SENSOR_DEVICE_ATTR(freq4_input, S_IRUGO, show_occ_freq_input, NULL, 4);
-+static SENSOR_DEVICE_ATTR(freq4_label, S_IRUGO, show_occ_freq_label, NULL, 4);
-+
-+static struct attribute *occ_attrs[] = {
-+	&sensor_dev_attr_temp1_input.dev_attr.attr,
-+	&sensor_dev_attr_temp2_input.dev_attr.attr,
-+	&sensor_dev_attr_temp3_input.dev_attr.attr,
-+	&sensor_dev_attr_temp4_input.dev_attr.attr,
-+	&sensor_dev_attr_temp5_input.dev_attr.attr,
-+	&sensor_dev_attr_temp6_input.dev_attr.attr,
-+	&sensor_dev_attr_temp7_input.dev_attr.attr,
-+	&sensor_dev_attr_temp8_input.dev_attr.attr,
-+	&sensor_dev_attr_temp9_input.dev_attr.attr,
-+	&sensor_dev_attr_temp1_label.dev_attr.attr,
-+	&sensor_dev_attr_temp2_label.dev_attr.attr,
-+	&sensor_dev_attr_temp3_label.dev_attr.attr,
-+	&sensor_dev_attr_temp4_label.dev_attr.attr,
-+	&sensor_dev_attr_temp5_label.dev_attr.attr,
-+	&sensor_dev_attr_temp6_label.dev_attr.attr,
-+	&sensor_dev_attr_temp7_label.dev_attr.attr,
-+	&sensor_dev_attr_temp8_label.dev_attr.attr,
-+	&sensor_dev_attr_temp9_label.dev_attr.attr,
-+	&sensor_dev_attr_power1_input.dev_attr.attr,
-+	&sensor_dev_attr_power2_input.dev_attr.attr,
-+	&sensor_dev_attr_power3_input.dev_attr.attr,
-+	&sensor_dev_attr_power4_input.dev_attr.attr,
-+	&sensor_dev_attr_power1_label.dev_attr.attr,
-+	&sensor_dev_attr_power2_label.dev_attr.attr,
-+	&sensor_dev_attr_power3_label.dev_attr.attr,
-+	&sensor_dev_attr_power4_label.dev_attr.attr,
-+	&sensor_dev_attr_freq1_input.dev_attr.attr,
-+	&sensor_dev_attr_freq2_input.dev_attr.attr,
-+	&sensor_dev_attr_freq3_input.dev_attr.attr,
-+	&sensor_dev_attr_freq4_input.dev_attr.attr,
-+	&sensor_dev_attr_freq1_label.dev_attr.attr,
-+	&sensor_dev_attr_freq2_label.dev_attr.attr,
-+	&sensor_dev_attr_freq3_label.dev_attr.attr,
-+	&sensor_dev_attr_freq4_label.dev_attr.attr,
-+
-+	NULL
-+};
-+ATTRIBUTE_GROUPS(occ);
-+
-+#endif
-+
-+static struct sensor_device_attribute temp_input[] = {
-+	SENSOR_ATTR(temp1_input, S_IRUGO, show_occ_temp_input, NULL, 1),
-+	SENSOR_ATTR(temp2_input, S_IRUGO, show_occ_temp_input, NULL, 2),
-+	SENSOR_ATTR(temp3_input, S_IRUGO, show_occ_temp_input, NULL, 3),
-+	SENSOR_ATTR(temp4_input, S_IRUGO, show_occ_temp_input, NULL, 4),
-+	SENSOR_ATTR(temp5_input, S_IRUGO, show_occ_temp_input, NULL, 5),
-+	SENSOR_ATTR(temp6_input, S_IRUGO, show_occ_temp_input, NULL, 6),
-+	SENSOR_ATTR(temp7_input, S_IRUGO, show_occ_temp_input, NULL, 7),
-+	SENSOR_ATTR(temp8_input, S_IRUGO, show_occ_temp_input, NULL, 8),
-+	SENSOR_ATTR(temp9_input, S_IRUGO, show_occ_temp_input, NULL, 9),
-+	SENSOR_ATTR(temp10_input, S_IRUGO, show_occ_temp_input, NULL, 10),
-+	SENSOR_ATTR(temp11_input, S_IRUGO, show_occ_temp_input, NULL, 11),
-+	SENSOR_ATTR(temp12_input, S_IRUGO, show_occ_temp_input, NULL, 12),
-+	SENSOR_ATTR(temp13_input, S_IRUGO, show_occ_temp_input, NULL, 13),
-+	SENSOR_ATTR(temp14_input, S_IRUGO, show_occ_temp_input, NULL, 14),
-+	SENSOR_ATTR(temp15_input, S_IRUGO, show_occ_temp_input, NULL, 15),
-+	SENSOR_ATTR(temp16_input, S_IRUGO, show_occ_temp_input, NULL, 16),
-+	SENSOR_ATTR(temp17_input, S_IRUGO, show_occ_temp_input, NULL, 17),
-+	SENSOR_ATTR(temp18_input, S_IRUGO, show_occ_temp_input, NULL, 18),
-+	SENSOR_ATTR(temp19_input, S_IRUGO, show_occ_temp_input, NULL, 19),
-+	SENSOR_ATTR(temp20_input, S_IRUGO, show_occ_temp_input, NULL, 20),
-+	SENSOR_ATTR(temp21_input, S_IRUGO, show_occ_temp_input, NULL, 21),
-+	SENSOR_ATTR(temp22_input, S_IRUGO, show_occ_temp_input, NULL, 22),
-+};
-+
-+static struct sensor_device_attribute temp_label[] = {
-+	SENSOR_ATTR(temp1_label, S_IRUGO, show_occ_temp_label, NULL, 1),
-+	SENSOR_ATTR(temp2_label, S_IRUGO, show_occ_temp_label, NULL, 2),
-+	SENSOR_ATTR(temp3_label, S_IRUGO, show_occ_temp_label, NULL, 3),
-+	SENSOR_ATTR(temp4_label, S_IRUGO, show_occ_temp_label, NULL, 4),
-+	SENSOR_ATTR(temp5_label, S_IRUGO, show_occ_temp_label, NULL, 5),
-+	SENSOR_ATTR(temp6_label, S_IRUGO, show_occ_temp_label, NULL, 6),
-+	SENSOR_ATTR(temp7_label, S_IRUGO, show_occ_temp_label, NULL, 7),
-+	SENSOR_ATTR(temp8_label, S_IRUGO, show_occ_temp_label, NULL, 8),
-+	SENSOR_ATTR(temp9_label, S_IRUGO, show_occ_temp_label, NULL, 9),
-+	SENSOR_ATTR(temp10_label, S_IRUGO, show_occ_temp_label, NULL, 10),
-+	SENSOR_ATTR(temp11_label, S_IRUGO, show_occ_temp_label, NULL, 11),
-+	SENSOR_ATTR(temp12_label, S_IRUGO, show_occ_temp_label, NULL, 12),
-+	SENSOR_ATTR(temp13_label, S_IRUGO, show_occ_temp_label, NULL, 13),
-+	SENSOR_ATTR(temp14_label, S_IRUGO, show_occ_temp_label, NULL, 14),
-+	SENSOR_ATTR(temp15_label, S_IRUGO, show_occ_temp_label, NULL, 15),
-+	SENSOR_ATTR(temp16_label, S_IRUGO, show_occ_temp_label, NULL, 16),
-+	SENSOR_ATTR(temp17_label, S_IRUGO, show_occ_temp_label, NULL, 17),
-+	SENSOR_ATTR(temp18_label, S_IRUGO, show_occ_temp_label, NULL, 18),
-+	SENSOR_ATTR(temp19_label, S_IRUGO, show_occ_temp_label, NULL, 19),
-+	SENSOR_ATTR(temp20_label, S_IRUGO, show_occ_temp_label, NULL, 20),
-+	SENSOR_ATTR(temp21_label, S_IRUGO, show_occ_temp_label, NULL, 21),
-+	SENSOR_ATTR(temp22_label, S_IRUGO, show_occ_temp_label, NULL, 22),
-+
-+};
-+
-+#define TEMP_UNIT_ATTRS(X)                      \
-+{	&temp_input[X].dev_attr.attr,           \
-+	&temp_label[X].dev_attr.attr,          \
-+	NULL                                    \
-+}
-+
-+/* 10-core CPU, occ has 22 temp sensors, more socket, more sensors */
-+static struct attribute *occ_temp_attr[][3] = {
-+	TEMP_UNIT_ATTRS(0),
-+	TEMP_UNIT_ATTRS(1),
-+	TEMP_UNIT_ATTRS(2),
-+	TEMP_UNIT_ATTRS(3),
-+	TEMP_UNIT_ATTRS(4),
-+	TEMP_UNIT_ATTRS(5),
-+	TEMP_UNIT_ATTRS(6),
-+	TEMP_UNIT_ATTRS(7),
-+	TEMP_UNIT_ATTRS(8),
-+	TEMP_UNIT_ATTRS(9),
-+	TEMP_UNIT_ATTRS(10),
-+	TEMP_UNIT_ATTRS(11),
-+	TEMP_UNIT_ATTRS(12),
-+	TEMP_UNIT_ATTRS(13),
-+	TEMP_UNIT_ATTRS(14),
-+	TEMP_UNIT_ATTRS(15),
-+	TEMP_UNIT_ATTRS(16),
-+	TEMP_UNIT_ATTRS(17),
-+	TEMP_UNIT_ATTRS(18),
-+	TEMP_UNIT_ATTRS(19),
-+	TEMP_UNIT_ATTRS(20),
-+	TEMP_UNIT_ATTRS(21),
-+};
-+
-+static const struct attribute_group occ_temp_attr_group[] = {
-+	{ .attrs = occ_temp_attr[0] },
-+	{ .attrs = occ_temp_attr[1] },
-+	{ .attrs = occ_temp_attr[2] },
-+	{ .attrs = occ_temp_attr[3] },
-+	{ .attrs = occ_temp_attr[4] },
-+	{ .attrs = occ_temp_attr[5] },
-+	{ .attrs = occ_temp_attr[6] },
-+	{ .attrs = occ_temp_attr[7] },
-+	{ .attrs = occ_temp_attr[8] },
-+	{ .attrs = occ_temp_attr[9] },
-+	{ .attrs = occ_temp_attr[10] },
-+	{ .attrs = occ_temp_attr[11] },
-+	{ .attrs = occ_temp_attr[12] },
-+	{ .attrs = occ_temp_attr[13] },
-+	{ .attrs = occ_temp_attr[14] },
-+	{ .attrs = occ_temp_attr[15] },
-+	{ .attrs = occ_temp_attr[16] },
-+	{ .attrs = occ_temp_attr[17] },
-+	{ .attrs = occ_temp_attr[18] },
-+	{ .attrs = occ_temp_attr[19] },
-+	{ .attrs = occ_temp_attr[20] },
-+	{ .attrs = occ_temp_attr[21] },
-+};
-+
-+
-+static struct sensor_device_attribute freq_input[] = {
-+	SENSOR_ATTR(freq1_input, S_IRUGO, show_occ_freq_input, NULL, 1),
-+	SENSOR_ATTR(freq2_input, S_IRUGO, show_occ_freq_input, NULL, 2),
-+	SENSOR_ATTR(freq3_input, S_IRUGO, show_occ_freq_input, NULL, 3),
-+	SENSOR_ATTR(freq4_input, S_IRUGO, show_occ_freq_input, NULL, 4),
-+	SENSOR_ATTR(freq5_input, S_IRUGO, show_occ_freq_input, NULL, 5),
-+	SENSOR_ATTR(freq6_input, S_IRUGO, show_occ_freq_input, NULL, 6),
-+	SENSOR_ATTR(freq7_input, S_IRUGO, show_occ_freq_input, NULL, 7),
-+	SENSOR_ATTR(freq8_input, S_IRUGO, show_occ_freq_input, NULL, 8),
-+	SENSOR_ATTR(freq9_input, S_IRUGO, show_occ_freq_input, NULL, 9),
-+	SENSOR_ATTR(freq10_input, S_IRUGO, show_occ_freq_input, NULL, 10),
-+};
-+
-+static struct sensor_device_attribute freq_label[] = {
-+	SENSOR_ATTR(freq1_label, S_IRUGO, show_occ_freq_label, NULL, 1),
-+	SENSOR_ATTR(freq2_label, S_IRUGO, show_occ_freq_label, NULL, 2),
-+	SENSOR_ATTR(freq3_label, S_IRUGO, show_occ_freq_label, NULL, 3),
-+	SENSOR_ATTR(freq4_label, S_IRUGO, show_occ_freq_label, NULL, 4),
-+	SENSOR_ATTR(freq5_label, S_IRUGO, show_occ_freq_label, NULL, 5),
-+	SENSOR_ATTR(freq6_label, S_IRUGO, show_occ_freq_label, NULL, 6),
-+	SENSOR_ATTR(freq7_label, S_IRUGO, show_occ_freq_label, NULL, 7),
-+	SENSOR_ATTR(freq8_label, S_IRUGO, show_occ_freq_label, NULL, 8),
-+	SENSOR_ATTR(freq9_label, S_IRUGO, show_occ_freq_label, NULL, 9),
-+	SENSOR_ATTR(freq10_label, S_IRUGO, show_occ_freq_label, NULL, 10),
-+
-+};
-+
-+#define FREQ_UNIT_ATTRS(X)                      \
-+{	&freq_input[X].dev_attr.attr,           \
-+	&freq_label[X].dev_attr.attr,          \
-+	NULL                                    \
-+}
-+
-+/* 10-core CPU, occ has 22 freq sensors, more socket, more sensors */
-+static struct attribute *occ_freq_attr[][3] = {
-+	FREQ_UNIT_ATTRS(0),
-+	FREQ_UNIT_ATTRS(1),
-+	FREQ_UNIT_ATTRS(2),
-+	FREQ_UNIT_ATTRS(3),
-+	FREQ_UNIT_ATTRS(4),
-+	FREQ_UNIT_ATTRS(5),
-+	FREQ_UNIT_ATTRS(6),
-+	FREQ_UNIT_ATTRS(7),
-+	FREQ_UNIT_ATTRS(8),
-+	FREQ_UNIT_ATTRS(9),
-+};
-+
-+static const struct attribute_group occ_freq_attr_group[] = {
-+	{ .attrs = occ_freq_attr[0] },
-+	{ .attrs = occ_freq_attr[1] },
-+	{ .attrs = occ_freq_attr[2] },
-+	{ .attrs = occ_freq_attr[3] },
-+	{ .attrs = occ_freq_attr[4] },
-+	{ .attrs = occ_freq_attr[5] },
-+	{ .attrs = occ_freq_attr[6] },
-+	{ .attrs = occ_freq_attr[7] },
-+	{ .attrs = occ_freq_attr[8] },
-+	{ .attrs = occ_freq_attr[9] },
-+};
-+
-+static struct sensor_device_attribute_2 caps_curr_powercap[] = {
-+	SENSOR_ATTR_2(caps_curr_powercap, S_IRUGO, show_occ_caps, NULL, 0, 1),
-+};
-+static struct sensor_device_attribute_2 caps_curr_powerreading[] = {
-+	SENSOR_ATTR_2(caps_curr_powerreading, S_IRUGO, show_occ_caps, NULL, 1, 1),
-+};
-+static struct sensor_device_attribute_2 caps_norm_powercap[] = {
-+	SENSOR_ATTR_2(caps_norm_powercap, S_IRUGO, show_occ_caps, NULL, 2, 1),
-+};
-+static struct sensor_device_attribute_2 caps_max_powercap[] = {
-+	SENSOR_ATTR_2(caps_max_powercap, S_IRUGO, show_occ_caps, NULL, 3, 1),
-+};
-+static struct sensor_device_attribute_2 caps_min_powercap[] = {
-+	SENSOR_ATTR_2(caps_min_powercap, S_IRUGO, show_occ_caps, NULL, 4, 1),
-+};
-+static struct sensor_device_attribute_2 caps_user_powerlimit[] = {
-+	SENSOR_ATTR_2(caps_user_powerlimit, S_IRUGO, show_occ_caps, NULL, 5, 1),
-+};
-+#define CAPS_UNIT_ATTRS(X)                      \
-+{	&caps_curr_powercap[X].dev_attr.attr,           \
-+	&caps_curr_powerreading[X].dev_attr.attr,           \
-+	&caps_norm_powercap[X].dev_attr.attr,           \
-+	&caps_max_powercap[X].dev_attr.attr,           \
-+	&caps_min_powercap[X].dev_attr.attr,           \
-+	&caps_user_powerlimit[X].dev_attr.attr,           \
-+	NULL                                    \
-+}
-+
-+/* 10-core CPU, occ has 1 caps sensors */
-+static struct attribute *occ_caps_attr[][7] = {
-+	CAPS_UNIT_ATTRS(0),
-+};
-+static const struct attribute_group occ_caps_attr_group[] = {
-+	{ .attrs = occ_caps_attr[0] },
-+};
-+
-+static struct sensor_device_attribute power_input[] = {
-+	SENSOR_ATTR(power1_input, S_IRUGO, show_occ_power_input, NULL, 1),
-+	SENSOR_ATTR(power2_input, S_IRUGO, show_occ_power_input, NULL, 2),
-+	SENSOR_ATTR(power3_input, S_IRUGO, show_occ_power_input, NULL, 3),
-+	SENSOR_ATTR(power4_input, S_IRUGO, show_occ_power_input, NULL, 4),
-+	SENSOR_ATTR(power5_input, S_IRUGO, show_occ_power_input, NULL, 5),
-+	SENSOR_ATTR(power6_input, S_IRUGO, show_occ_power_input, NULL, 6),
-+	SENSOR_ATTR(power7_input, S_IRUGO, show_occ_power_input, NULL, 7),
-+	SENSOR_ATTR(power8_input, S_IRUGO, show_occ_power_input, NULL, 8),
-+	SENSOR_ATTR(power9_input, S_IRUGO, show_occ_power_input, NULL, 9),
-+	SENSOR_ATTR(power10_input, S_IRUGO, show_occ_power_input, NULL, 10),
-+	SENSOR_ATTR(power11_input, S_IRUGO, show_occ_power_input, NULL, 11),
-+};
-+
-+static struct sensor_device_attribute power_label[] = {
-+	SENSOR_ATTR(power1_label, S_IRUGO, show_occ_power_label, NULL, 1),
-+	SENSOR_ATTR(power2_label, S_IRUGO, show_occ_power_label, NULL, 2),
-+	SENSOR_ATTR(power3_label, S_IRUGO, show_occ_power_label, NULL, 3),
-+	SENSOR_ATTR(power4_label, S_IRUGO, show_occ_power_label, NULL, 4),
-+	SENSOR_ATTR(power5_label, S_IRUGO, show_occ_power_label, NULL, 5),
-+	SENSOR_ATTR(power6_label, S_IRUGO, show_occ_power_label, NULL, 6),
-+	SENSOR_ATTR(power7_label, S_IRUGO, show_occ_power_label, NULL, 7),
-+	SENSOR_ATTR(power8_label, S_IRUGO, show_occ_power_label, NULL, 8),
-+	SENSOR_ATTR(power9_label, S_IRUGO, show_occ_power_label, NULL, 9),
-+	SENSOR_ATTR(power10_label, S_IRUGO, show_occ_power_label, NULL, 10),
-+	SENSOR_ATTR(power11_label, S_IRUGO, show_occ_power_label, NULL, 11),
-+};
-+
-+#define POWER_UNIT_ATTRS(X)                      \
-+{	&power_input[X].dev_attr.attr,           \
-+	&power_label[X].dev_attr.attr,          \
-+	NULL                                    \
-+}
-+
-+/* 10-core CPU, occ has 11 power sensors, more socket, more sensors */
-+static struct attribute *occ_power_attr[][3] = {
-+	POWER_UNIT_ATTRS(0),
-+	POWER_UNIT_ATTRS(1),
-+	POWER_UNIT_ATTRS(2),
-+	POWER_UNIT_ATTRS(3),
-+	POWER_UNIT_ATTRS(4),
-+	POWER_UNIT_ATTRS(5),
-+	POWER_UNIT_ATTRS(6),
-+	POWER_UNIT_ATTRS(7),
-+	POWER_UNIT_ATTRS(8),
-+	POWER_UNIT_ATTRS(9),
-+	POWER_UNIT_ATTRS(10),
-+};
-+
-+static const struct attribute_group occ_power_attr_group[] = {
-+	{ .attrs = occ_power_attr[0] },
-+	{ .attrs = occ_power_attr[1] },
-+	{ .attrs = occ_power_attr[2] },
-+	{ .attrs = occ_power_attr[3] },
-+	{ .attrs = occ_power_attr[4] },
-+	{ .attrs = occ_power_attr[5] },
-+	{ .attrs = occ_power_attr[6] },
-+	{ .attrs = occ_power_attr[7] },
-+	{ .attrs = occ_power_attr[8] },
-+	{ .attrs = occ_power_attr[9] },
-+	{ .attrs = occ_power_attr[10] },
-+};
-+
-+static void occ_remove_sysfs_files(struct device *dev)
-+{
-+	int i = 0;
-+
-+	for (i = 0; i < ARRAY_SIZE(occ_temp_attr_group); i++)
-+		sysfs_remove_group(&dev->kobj, &occ_temp_attr_group[i]);
-+
-+	for (i = 0; i < ARRAY_SIZE(occ_freq_attr_group); i++)
-+		sysfs_remove_group(&dev->kobj, &occ_freq_attr_group[i]);
-+
-+	for (i = 0; i < ARRAY_SIZE(occ_power_attr_group); i++)
-+		sysfs_remove_group(&dev->kobj, &occ_power_attr_group[i]);
-+
-+	for (i = 0; i < ARRAY_SIZE(occ_caps_attr_group); i++)
-+		sysfs_remove_group(&dev->kobj, &occ_caps_attr_group[i]);
-+}
-+
-+
-+static int occ_create_sysfs_attribute(struct device *dev)
-+{
-+	/* The sensor number varies for different
-+	 * platform depending on core number. We'd better
-+	 * create them dynamically  */
-+	struct occ_drv_data *data = dev_get_drvdata(dev);
-+	int i = 0;
-+	int num_of_sensors = 0;
-+	int ret = 0;
-+
-+	/* get sensor number from occ. */
-+	ret = occ_update_device(dev);
-+	if (ret != 0)
-+	{
-+		/* FIXME: to test fake data */
-+		printk("ERROR: cannot get occ sensor data: %d\n", ret);
-+		return ret;
-+	}
-+
-+	if (data->occ_resp.data.blocks == NULL)
-+		return -1;
-+
-+	/* temp sensors */
-+	if (data->occ_resp.temp_block_id >= 0)
-+	{
-+		num_of_sensors = data->occ_resp.data.blocks[data->occ_resp.temp_block_id].num_of_sensors;
-+		for (i = 0; i < num_of_sensors; i++)
-+		{
-+			//printk("create temp group: %d\n", i);
-+			//ret = sysfs_create_group(&dev->kobj, &occ_temp_attr_group[i]);
-+			ret = sysfs_create_group(&data->hwmon_dev->kobj, &occ_temp_attr_group[i]);
-+			if (ret)
-+			{
-+				dev_err(dev, "error create temp sysfs entry\n");
-+				goto error;
-+			}
-+		}
-+	}
-+
-+	/* freq sensors */
-+	if (data->occ_resp.freq_block_id >= 0)
-+	{
-+		num_of_sensors = data->occ_resp.data.blocks[data->occ_resp.freq_block_id].num_of_sensors;
-+		for (i = 0; i < num_of_sensors; i++)
-+		{
-+			//printk("create freq group: %d\n", i);
-+			//ret = sysfs_create_group(&dev->kobj, &occ_temp_attr_group[i]);
-+			ret = sysfs_create_group(&data->hwmon_dev->kobj, &occ_freq_attr_group[i]);
-+			if (ret)
-+			{
-+				dev_err(dev, "error create freq sysfs entry\n");
-+				goto error;
-+			}
-+		}
-+	}
-+
-+	/* power sensors */
-+	//printk("power_block_id: %d\n", data->occ_resp.power_block_id);
-+	if (data->occ_resp.power_block_id >= 0)
-+	{
-+		num_of_sensors = data->occ_resp.data.blocks[data->occ_resp.power_block_id].num_of_sensors;
-+		for (i = 0; i < num_of_sensors; i++)
-+		{
-+			//printk("create power group: %d\n", i);
-+			//ret = sysfs_create_group(&dev->kobj, &occ_temp_attr_group[i]);
-+			ret = sysfs_create_group(&data->hwmon_dev->kobj, &occ_power_attr_group[i]);
-+			if (ret)
-+			{
-+				dev_err(dev, "error create power sysfs entry\n");
-+				goto error;
-+			}
-+		}
-+	}
-+
-+	/* caps sensors */
-+	//printk("caps_block_id: %d\n", data->occ_resp.caps_block_id);
-+	if (data->occ_resp.caps_block_id >= 0)
-+	{
-+		num_of_sensors = data->occ_resp.data.blocks[data->occ_resp.caps_block_id].num_of_sensors;
-+		for (i = 0; i < num_of_sensors; i++)
-+		{
-+			//printk("create caps group: %d\n", i);
-+			//ret = sysfs_create_group(&dev->kobj, &occ_temp_attr_group[i]);
-+			ret = sysfs_create_group(&data->hwmon_dev->kobj, &occ_caps_attr_group[i]);
-+			if (ret)
-+			{
-+				dev_err(dev, "error create caps sysfs entry\n");
-+				goto error;
-+			}
-+		}
-+	}
-+
-+	return 0;
-+error:
-+	occ_remove_sysfs_files(data->hwmon_dev);
-+	return ret;
-+}
-+
-+/*-----------------------------------------------------------------------*/
-+/* device probe and removal */
-+
-+#define OCC_I2C_ADDR 0x50
-+#define OCC_I2C_NAME "occ-i2c"
-+
-+enum occ_type {
-+	occ_id,
-+};
-+
-+static int occ_probe(struct i2c_client *client, const struct i2c_device_id *id)
-+{
-+	struct device *dev = &client->dev;
-+	struct occ_drv_data *data;
-+	unsigned long funcs;
-+	struct device_node *np = dev->of_node;
-+	//u32 pval = 0;
-+	int ret = 0;
-+
-+	data = devm_kzalloc(dev, sizeof(struct occ_drv_data), GFP_KERNEL);
-+	if (!data)
-+		return -ENOMEM;
-+
-+	data->client = client;
-+	i2c_set_clientdata(client, data);
-+	mutex_init(&data->update_lock);
-+	data->sample_time = HZ;
-+
-+	/* Yi: i2c-core should assign address to
-+	 * client when detection - but it does not work  FIXME  */
-+	//client->addr = OCC_I2C_ADDR;
-+
-+	/* Yi: read address from device table */
-+	//if (of_property_read_u32(np, "reg", &pval)) {
-+	//	dev_err(&client->dev, "invalid reg\n");
-+	//}
-+	//client->addr = pval;
-+
-+	/* configure the driver */
-+	//dev_dbg(dev, "occ register hwmon @0x%x\n", client->addr);
-+	//data->hwmon_dev = hwmon_device_register_with_groups(dev, "occ",
-+	//						    data, occ_groups);
-+
-+	/* Yi: try to create sysfs attributes dynamically */
-+	data->hwmon_dev = hwmon_device_register(dev);
-+	if (IS_ERR(data->hwmon_dev))
-+		return PTR_ERR(data->hwmon_dev);
-+
-+	ret = occ_create_sysfs_attribute(dev);
-+	if (ret)
-+	{
-+		hwmon_device_unregister(data->hwmon_dev);
-+		return ret;
-+	}
-+
-+	data->hwmon_dev->parent = dev;
-+
-+	//dev_dbg(dev, "%s: sensor '%s'\n",
-+	//	 dev_name(data->hwmon_dev), client->name);
-+
-+	funcs = i2c_get_functionality(client->adapter);
-+	//dev_info(dev, "i2c adaptor supports function: 0x%lx\n", funcs);
-+
-+	/* Yi: seems always error? disable for now */
-+	//occ_check_i2c_errors(client);
-+
-+	//dev_info(dev, "occ i2c driver ready: i2c addr@0x%x\n", client->addr);
-+	printk("occ i2c driver ready: i2c addr@0x%x\n", client->addr);
-+
-+	return 0;
-+}
-+
-+static int occ_remove(struct i2c_client *client)
-+{
-+	struct occ_drv_data *data = i2c_get_clientdata(client);
-+
-+	/* free allocated sensor memory */
-+	deinit_occ_resp_buf(&data->occ_resp);
-+
-+	//occ_remove_sysfs_files(&client->dev);
-+	occ_remove_sysfs_files(data->hwmon_dev);
-+	hwmon_device_unregister(data->hwmon_dev);
-+	return 0;
-+}
-+
-+/* used for old-style board info */
-+static const struct i2c_device_id occ_ids[] = {
-+	{ OCC_I2C_NAME, occ_id, },
-+	{ /* LIST END */ }
-+};
-+MODULE_DEVICE_TABLE(i2c, occ_ids);
-+
-+static const struct of_device_id i2c_occ_of_match[] = {
-+	{.compatible = "ibm,occ-i2c"},
-+	{},
-+};
-+
-+MODULE_DEVICE_TABLE(of, i2c_occ_of_match);
-+
-+#ifdef CONFIG_PM
-+static int occ_suspend(struct device *dev)
-+{
-+	//struct i2c_client *client = to_i2c_client(dev);
-+	/* TODO */
-+	return 0;
-+}
-+
-+static int occ_resume(struct device *dev)
-+{
-+	//struct i2c_client *client = to_i2c_client(dev);
-+	/* TODO */
-+	return 0;
-+}
-+
-+static const struct dev_pm_ops occ_dev_pm_ops = {
-+	.suspend	= occ_suspend,
-+	.resume		= occ_resume,
-+};
-+#define OCC_DEV_PM_OPS (&occ_dev_pm_ops)
-+#else
-+#define OCC_DEV_PM_OPS NULL
-+#endif /* CONFIG_PM */
-+
-+/* Yi: i2c-core uses i2c-detect() to detect device in bellow address list.
-+   If exists, address will be assigned to client.
-+ * It is also possible to read address from device table. */
-+static const unsigned short normal_i2c[] = {0x50, 0x51, I2C_CLIENT_END };
-+
-+/* Return 0 if detection is successful, -ENODEV otherwise */
-+static int occ_detect(struct i2c_client *new_client,
-+		       struct i2c_board_info *info)
-+{
-+	/* i2c-core need this function to create new device */
-+	strncpy(info->type, OCC_I2C_NAME, sizeof(OCC_I2C_NAME));
-+	return 0;
-+}
-+
-+static struct i2c_driver occ_driver = {
-+	.class		= I2C_CLASS_HWMON,
-+	.driver = {
-+		.name	= OCC_I2C_NAME,
-+		.pm	= OCC_DEV_PM_OPS,
-+		.of_match_table = i2c_occ_of_match,
-+	},
-+	.probe		= occ_probe,
-+	.remove		= occ_remove,
-+	.id_table	= occ_ids,
-+	.address_list	= normal_i2c,
-+	.detect		= occ_detect,
-+};
-+
-+module_i2c_driver(occ_driver);
-+
-+#if 0
-+/* Create new i2c device */
-+static struct i2c_board_info my_dev_info[] __initdata = {
-+	{
-+		I2C_BOARD_INFO(OCC_I2C_NAME, 0x50),
-+	},
-+};
-+
-+static struct i2c_client *my_client;
-+
-+static int occ_init(void)
-+{
-+	static int sys_adap_bus_num = 3;
-+	struct i2c_adapter* adap = i2c_get_adapter(sys_adap_bus_num);
-+
-+	if(adap==NULL) {
-+		printk("[OCC-DEBUG] i2c_get_adapter fail!\n");
-+		return -1;
-+	}
-+
-+	my_client = i2c_new_device(adap, &my_dev_info[0]);
-+	if( my_client==NULL ){
-+		printk("[OCC-DEBUG] i2c_new_device fail!\n");
-+		return -1;
-+	}
-+	i2c_put_adapter(adap);
-+	return i2c_add_driver(&occ_driver);
-+}
-+
-+static void __exit occ_exit(void)
-+{
-+	i2c_unregister_device(my_client);
-+	i2c_del_driver(&occ_driver);
-+}
-+
-+module_init(occ_init);
-+module_exit(occ_exit);
-+
-+#endif
-+
-+MODULE_AUTHOR("Li Yi <shliyi@cn.ibm.com>");
-+MODULE_DESCRIPTION("BMC OCC monitor driver");
-+MODULE_LICENSE("GPL");
diff --git a/meta-openbmc-machines/meta-openpower/meta-rackspace/meta-barreleye/recipes-kernel/linux/linux-obmc_%.bbappend b/meta-openbmc-machines/meta-openpower/meta-rackspace/meta-barreleye/recipes-kernel/linux/linux-obmc_%.bbappend
deleted file mode 100644
index 1099689..0000000
--- a/meta-openbmc-machines/meta-openpower/meta-rackspace/meta-barreleye/recipes-kernel/linux/linux-obmc_%.bbappend
+++ /dev/null
@@ -1,3 +0,0 @@
-FILESEXTRAPATHS_prepend := "${THISDIR}/linux-obmc:"
-SRC_URI += "file://barreleye.cfg"
-SRC_URI += "file://occ_hwmon.patch"
diff --git a/meta-phosphor/common/recipes-bsp/u-boot/files/0001-am335x_evm.h-Add-use-DEFAULT_LINUX_BOOT_ENV-environm.patch b/meta-phosphor/common/recipes-bsp/u-boot/files/0001-am335x_evm.h-Add-use-DEFAULT_LINUX_BOOT_ENV-environm.patch
deleted file mode 100644
index 77e35bb..0000000
--- a/meta-phosphor/common/recipes-bsp/u-boot/files/0001-am335x_evm.h-Add-use-DEFAULT_LINUX_BOOT_ENV-environm.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From 5701384cea4a829b772bf7a96a74825b58c22385 Mon Sep 17 00:00:00 2001
-From: Denys Dmytriyenko <denys@ti.com>
-Date: Thu, 17 Apr 2014 12:25:40 -0400
-Subject: [PATCH] am335x_evm.h: Add, use DEFAULT_LINUX_BOOT_ENV environment
- string
-
-Modified version of the patch currently being reviewed for mainline:
-http://patchwork.ozlabs.org/patch/334861/
-
-To deal with a reoccurring problem properly we need to specify addresses
-for the Linux kernel, Flatted Device Tree and ramdisk that obey the
-constraints within the kernel's Documentation/arm/Booting file but also
-make sure that we relocate things within a valid address range.
-
-Signed-off-by: Denys Dmytriyenko <denys@ti.com>
-Signed-off-by: Tom Rini <trini@ti.com>
-
-Upstream-Status: Pending
----
- include/configs/am335x_evm.h | 31 ++++++++++++++++++++++++++-----
- 1 file changed, 26 insertions(+), 5 deletions(-)
-
-diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
-index c5a6d4b..01e32b3 100644
---- a/include/configs/am335x_evm.h
-+++ b/include/configs/am335x_evm.h
-@@ -54,10 +54,7 @@
- #define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
- #ifndef CONFIG_SPL_BUILD
- #define CONFIG_EXTRA_ENV_SETTINGS \
--	"loadaddr=0x80200000\0" \
--	"fdtaddr=0x80F80000\0" \
--	"fdt_high=0xffffffff\0" \
--	"rdaddr=0x81000000\0" \
-+	DEFAULT_LINUX_BOOT_ENV \
- 	"bootdir=/boot\0" \
- 	"bootfile=uImage\0" \
- 	"fdtfile=undefined\0" \
-@@ -197,7 +194,31 @@
- #define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_MEMTEST_START \
- 					+ (8 * 1024 * 1024))
- 
--#define CONFIG_SYS_LOAD_ADDR		0x81000000 /* Default load address */
-+/*
-+ * Our DDR memory always starts at 0x80000000 and U-Boot shall have
-+ * relocated itself to higher in memory by the time this value is used.
-+ * However, set this to a 32MB offset to allow for easier Linux kernel
-+ * booting as the default is often used as the kernel load address.
-+ */
-+#define CONFIG_SYS_LOAD_ADDR		0x82000000 /* Default load address */
-+
-+/*
-+ * We setup defaults based on constraints from the Linux kernel, which should
-+ * also be safe elsewhere.  We have the default load at 32MB into DDR (for
-+ * the kernel), FDT above 128MB (the maximum location for the end of the
-+ * kernel), and the ramdisk 512KB above that (allowing for hopefully never
-+ * seen large trees).  We say all of this must be within the first 256MB
-+ * as that will normally be within the kernel lowmem and thus visible via
-+ * bootm_size and we only run on platforms with 256MB or more of memory.
-+ */
-+#define DEFAULT_LINUX_BOOT_ENV \
-+	"loadaddr=0x82000000\0" \
-+	"kernel_addr_r=0x82000000\0" \
-+	"fdtaddr=0x88000000\0" \
-+	"fdt_addr_r=0x88000000\0" \
-+	"rdaddr=0x88080000\0" \
-+	"ramdisk_addr_r=0x88080000\0" \
-+	"bootm_size=0x10000000\0"
- 
- #define CONFIG_MMC
- #define CONFIG_GENERIC_MMC
--- 
-1.9.2
-
diff --git a/meta-phosphor/common/recipes-bsp/u-boot/u-boot_2013.07.bb b/meta-phosphor/common/recipes-bsp/u-boot/u-boot_2013.07.bb
index f3e2f56..80715e7 100644
--- a/meta-phosphor/common/recipes-bsp/u-boot/u-boot_2013.07.bb
+++ b/meta-phosphor/common/recipes-bsp/u-boot/u-boot_2013.07.bb
@@ -12,13 +12,12 @@
 
 # This revision corresponds to the tag "v2013.07"
 # We use the revision in order to avoid having to fetch it from the repo during parse
-SRCREV = "62c175fbb8a0f9a926c88294ea9f7e88eb898f6c"
+SRCREV = "${AUTOREV}"
 
 PV = "v2013.07+git${SRCPV}"
 
-SRC_URI = "git://git.denx.de/u-boot.git;branch=master \
-          file://0001-am335x_evm.h-Add-use-DEFAULT_LINUX_BOOT_ENV-environm.patch \
-          "
+UBRANCH = "v2013.07-aspeed-openbmc"
+SRC_URI = "git://git@github.com/openbmc/u-boot.git;branch=${UBRANCH};protocol=https"
 
 S = "${WORKDIR}/git"
 
diff --git a/meta-phosphor/common/recipes-kernel/linux/linux-obmc_4.3.bb b/meta-phosphor/common/recipes-kernel/linux/linux-obmc_4.3.bb
index a898c78..3b1eec8 100644
--- a/meta-phosphor/common/recipes-kernel/linux/linux-obmc_4.3.bb
+++ b/meta-phosphor/common/recipes-kernel/linux/linux-obmc_4.3.bb
@@ -10,7 +10,7 @@
 LINUX_VERSION ?= "4.3"
 LINUX_VERSION_EXTENSION ?= "-${SRCREV}"
 
-SRCREV="openbmc-20151217-1"
+SRCREV="openbmc-20160127-1"
 
 PV = "${LINUX_VERSION}+git${SRCPV}"
 
diff --git a/meta-phosphor/common/recipes-phosphor/host-ipmid/btbridged.bb b/meta-phosphor/common/recipes-phosphor/host-ipmid/btbridged.bb
index 14a9611..a1a32d9 100644
--- a/meta-phosphor/common/recipes-phosphor/host-ipmid/btbridged.bb
+++ b/meta-phosphor/common/recipes-phosphor/host-ipmid/btbridged.bb
@@ -11,7 +11,7 @@
 
 S = "${WORKDIR}/git"
 SRC_URI += "git://github.com/openbmc/btbridge"
-SRCREV="d2f64ecf533ed6940d1de003cf979eb62d05e3e6"
+SRCREV="39b3700766d851009258544aa0f75365f024c597"
 
 # This is how linux-libc-headers says to include custom uapi headers
 EXTRA_OEMAKE_append = "CFLAGS=-I${STAGING_KERNEL_DIR}/include/uapi"
diff --git a/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid-fru.bb b/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid-fru.bb
index d61b2e6..72d847d 100644
--- a/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid-fru.bb
+++ b/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid-fru.bb
@@ -18,7 +18,7 @@
 
 SRC_URI += "git://github.com/openbmc/ipmi-fru-parser"
 
-SRCREV = "20656b1e15bebd7bc2754bd680f045e253bd2809"
+SRCREV = "63696f4b23c9fd0a84ce539a6414ada406aaf229"
 
 FILES_${PN} += "${libdir}/host-ipmid/*.so"
 FILES_${PN}-dbg += "${libdir}/host-ipmid/.debug"
@@ -31,4 +31,4 @@
 
 
 #        install -m 0755 -d ${D}${libdir}/host-ipmid
-#        install -m 0755 ${S}/*.so ${D}${libdir}/host-ipmid/
\ No newline at end of file
+#        install -m 0755 ${S}/*.so ${D}${libdir}/host-ipmid/
diff --git a/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid.bb b/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid.bb
index c03405c..2a8aa07 100644
--- a/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid.bb
+++ b/meta-phosphor/common/recipes-phosphor/host-ipmid/host-ipmid.bb
@@ -14,7 +14,7 @@
 
 SRC_URI += "git://github.com/openbmc/phosphor-host-ipmid"
 
-SRCREV = "903327c4e9f901a692939338b0b4651aa815cedd"
+SRCREV = "e90d8bf6a342649dba2fd1589a3cddb3cd051bb1"
 
 
 S = "${WORKDIR}/git"
diff --git a/meta-phosphor/common/recipes-phosphor/skeleton/skeleton.bb b/meta-phosphor/common/recipes-phosphor/skeleton/skeleton.bb
index 87327be..fab50ea 100644
--- a/meta-phosphor/common/recipes-phosphor/skeleton/skeleton.bb
+++ b/meta-phosphor/common/recipes-phosphor/skeleton/skeleton.bb
@@ -16,7 +16,7 @@
 RDEPENDS_${PN} += "python-subprocess python-tftpy"
 SRC_URI += "git://github.com/openbmc/skeleton"
 
-SRCREV = "08b2b46a6df8b5cf93fcd17453072a2ddb48b598"
+SRCREV = "abe4953f941f63b4a3f531af15f6dba68870f3a9"
 
 S = "${WORKDIR}"