diff --git a/drivers/hwmon/occ/common.c b/drivers/hwmon/occ/common.c
index e6d3fb5..6ffcee7 100644
--- a/drivers/hwmon/occ/common.c
+++ b/drivers/hwmon/occ/common.c
@@ -118,6 +118,53 @@ struct extended_sensor {
 	u8 data[6];
 } __packed;
 
+static void occ_update_prev_power_avgs(struct occ *occ)
+{
+	u8 i;
+	struct power_sensor_1 *ps1;
+	struct power_sensor_2 *ps2;
+	struct power_sensor_a0 *psa0;
+	struct occ_sensor *power = &occ->sensors.power;
+	struct occ_power_avg *prevs = occ->prev_power_avgs;
+
+	switch (power->version) {
+	case 1:
+		for (i = 0; i < power->num_sensors; ++i) {
+			ps1 = ((struct power_sensor_1 *)power->data) + i;
+
+			prevs[i].accumulator =
+				get_unaligned_be32(&ps1->accumulator);
+			prevs[i].update_tag =
+				get_unaligned_be32(&ps1->update_tag);
+		}
+		break;
+	case 2:
+		for (i = 0; i < power->num_sensors; ++i) {
+			ps2 = ((struct power_sensor_2 *)power->data) + i;
+
+			prevs[i].accumulator =
+				get_unaligned_be64(&ps2->accumulator);
+			prevs[i].update_tag =
+				get_unaligned_be32(&ps2->update_tag);
+		}
+		break;
+	case 0xA0:
+		for (i = 0; i < power->num_sensors; ++i) {
+			psa0 = ((struct power_sensor_a0 *)power->data) + i;
+
+			prevs[i].accumulator = psa0->system.accumulator;
+			prevs[i].update_tag = psa0->system.update_tag;
+			prevs[i + 1].accumulator = psa0->proc.accumulator;
+			prevs[i + 1].update_tag = psa0->proc.update_tag;
+			prevs[i + 2].accumulator = psa0->vdd.accumulator;
+			prevs[i + 2].update_tag = psa0->vdd.update_tag;
+			prevs[i + 3].accumulator = psa0->vdn.accumulator;
+			prevs[i + 3].update_tag = psa0->vdn.update_tag;
+		}
+		break;
+	}
+}
+
 static int occ_poll(struct occ *occ)
 {
 	int rc;
@@ -135,6 +182,8 @@ static int occ_poll(struct occ *occ)
 	cmd[6] = checksum & 0xFF;	/* checksum lsb */
 	cmd[7] = 0;
 
+	occ_update_prev_power_avgs(occ);
+
 	/* mutex should already be locked if necessary */
 	rc = occ->send_cmd(occ, cmd);
 	if (rc) {
@@ -208,6 +257,7 @@ int occ_update_response(struct occ *occ)
 	/* limit the maximum rate of polling the OCC */
 	if (time_after(jiffies, occ->last_update + OCC_UPDATE_FREQUENCY)) {
 		rc = occ_poll(occ);
+		occ->prev_update = occ->last_update;
 		occ->last_update = jiffies;
 	} else {
 		rc = occ->last_error;
@@ -364,6 +414,14 @@ static ssize_t occ_show_freq_2(struct device *dev,
 	return snprintf(buf, PAGE_SIZE - 1, "%u\n", val);
 }
 
+static u64 occ_power_avg(struct occ *occ, u8 idx, u64 accum, u32 samples)
+{
+	struct occ_power_avg *avg = &occ->prev_power_avgs[idx];
+
+	return div_u64((accum - avg->accumulator) * 1000000ULL,
+		       samples - avg->update_tag);
+}
+
 static ssize_t occ_show_power_1(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
@@ -385,13 +443,12 @@ static ssize_t occ_show_power_1(struct device *dev,
 		val = get_unaligned_be16(&power->sensor_id);
 		break;
 	case 1:
-		val = get_unaligned_be32(&power->accumulator) /
-			get_unaligned_be32(&power->update_tag);
-		val *= 1000000ULL;
+		val = occ_power_avg(occ, sattr->index,
+				    get_unaligned_be32(&power->accumulator),
+				    get_unaligned_be32(&power->update_tag));
 		break;
 	case 2:
-		val = (u64)get_unaligned_be32(&power->update_tag) *
-			   occ->powr_sample_time_us;
+		val = jiffies_to_usecs(occ->last_update - occ->prev_update);
 		break;
 	case 3:
 		val = get_unaligned_be16(&power->value) * 1000000ULL;
@@ -403,12 +460,6 @@ static ssize_t occ_show_power_1(struct device *dev,
 	return snprintf(buf, PAGE_SIZE - 1, "%llu\n", val);
 }
 
-static u64 occ_get_powr_avg(u64 *accum, u32 *samples)
-{
-	return div64_u64(get_unaligned_be64(accum) * 1000000ULL,
-			 get_unaligned_be32(samples));
-}
-
 static ssize_t occ_show_power_2(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
@@ -431,12 +482,12 @@ static ssize_t occ_show_power_2(struct device *dev,
 				get_unaligned_be32(&power->sensor_id),
 				power->function_id, power->apss_channel);
 	case 1:
-		val = occ_get_powr_avg(&power->accumulator,
-				       &power->update_tag);
+		val = occ_power_avg(occ, sattr->index,
+				    get_unaligned_be64(&power->accumulator),
+				    get_unaligned_be32(&power->update_tag));
 		break;
 	case 2:
-		val = (u64)get_unaligned_be32(&power->update_tag) *
-			   occ->powr_sample_time_us;
+		val = jiffies_to_usecs(occ->last_update - occ->prev_update);
 		break;
 	case 3:
 		val = get_unaligned_be16(&power->value) * 1000000ULL;
@@ -452,6 +503,8 @@ static ssize_t occ_show_power_a0(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
 	int rc;
+	u32 samples;
+	u64 accum;
 	u64 val = 0;
 	struct power_sensor_a0 *power;
 	struct occ *occ = dev_get_drvdata(dev);
@@ -469,12 +522,15 @@ static ssize_t occ_show_power_a0(struct device *dev,
 		return snprintf(buf, PAGE_SIZE - 1, "%u_system\n",
 				get_unaligned_be32(&power->sensor_id));
 	case 1:
-		val = occ_get_powr_avg(&power->system.accumulator,
-				       &power->system.update_tag);
+		accum = get_unaligned_be64(&power->system.accumulator);
+		samples = get_unaligned_be32(&power->system.update_tag);
+		val = occ_power_avg(occ, sattr->index, accum, samples);
 		break;
 	case 2:
-		val = (u64)get_unaligned_be32(&power->system.update_tag) *
-			   occ->powr_sample_time_us;
+	case 6:
+	case 10:
+	case 14:
+		val = jiffies_to_usecs(occ->last_update - occ->prev_update);
 		break;
 	case 3:
 		val = get_unaligned_be16(&power->system.value) * 1000000ULL;
@@ -483,12 +539,9 @@ static ssize_t occ_show_power_a0(struct device *dev,
 		return snprintf(buf, PAGE_SIZE - 1, "%u_proc\n",
 				get_unaligned_be32(&power->sensor_id));
 	case 5:
-		val = occ_get_powr_avg(&power->proc.accumulator,
-				       &power->proc.update_tag);
-		break;
-	case 6:
-		val = (u64)get_unaligned_be32(&power->proc.update_tag) *
-			   occ->powr_sample_time_us;
+		accum = get_unaligned_be64(&power->proc.accumulator);
+		samples = get_unaligned_be32(&power->proc.update_tag);
+		val = occ_power_avg(occ, sattr->index + 1, accum, samples);
 		break;
 	case 7:
 		val = get_unaligned_be16(&power->proc.value) * 1000000ULL;
@@ -497,12 +550,9 @@ static ssize_t occ_show_power_a0(struct device *dev,
 		return snprintf(buf, PAGE_SIZE - 1, "%u_vdd\n",
 				get_unaligned_be32(&power->sensor_id));
 	case 9:
-		val = occ_get_powr_avg(&power->vdd.accumulator,
-				       &power->vdd.update_tag);
-		break;
-	case 10:
-		val = (u64)get_unaligned_be32(&power->vdd.update_tag) *
-			   occ->powr_sample_time_us;
+		accum = get_unaligned_be64(&power->vdd.accumulator);
+		samples = get_unaligned_be32(&power->vdd.update_tag);
+		val = occ_power_avg(occ, sattr->index + 2, accum, samples);
 		break;
 	case 11:
 		val = get_unaligned_be16(&power->vdd.value) * 1000000ULL;
@@ -511,12 +561,9 @@ static ssize_t occ_show_power_a0(struct device *dev,
 		return snprintf(buf, PAGE_SIZE - 1, "%u_vdn\n",
 				get_unaligned_be32(&power->sensor_id));
 	case 13:
-		val = occ_get_powr_avg(&power->vdn.accumulator,
-				       &power->vdn.update_tag);
-		break;
-	case 14:
-		val = (u64)get_unaligned_be32(&power->vdn.update_tag) *
-			   occ->powr_sample_time_us;
+		accum = get_unaligned_be64(&power->vdn.accumulator);
+		samples = get_unaligned_be32(&power->vdn.update_tag);
+		val = occ_power_avg(occ, sattr->index + 3, accum, samples);
 		break;
 	case 15:
 		val = get_unaligned_be16(&power->vdn.value) * 1000000ULL;
@@ -719,6 +766,7 @@ static ssize_t occ_show_extended(struct device *dev,
 static int occ_setup_sensor_attrs(struct occ *occ)
 {
 	unsigned int i, s, num_attrs = 0;
+	unsigned int power_avgs_size = 0;
 	struct device *dev = occ->bus_dev;
 	struct occ_sensors *sensors = &occ->sensors;
 	struct occ_attribute *attr;
@@ -761,9 +809,13 @@ static int occ_setup_sensor_attrs(struct occ *occ)
 		/* fall through */
 	case 1:
 		num_attrs += (sensors->power.num_sensors * 4);
+		power_avgs_size = sizeof(struct occ_power_avg) *
+			sensors->power.num_sensors;
 		break;
 	case 0xA0:
 		num_attrs += (sensors->power.num_sensors * 16);
+		power_avgs_size = sizeof(struct occ_power_avg) *
+			sensors->power.num_sensors * 4;
 		show_power = occ_show_power_a0;
 		break;
 	default:
@@ -792,6 +844,13 @@ static int occ_setup_sensor_attrs(struct occ *occ)
 		sensors->extended.num_sensors = 0;
 	}
 
+	if (power_avgs_size) {
+		occ->prev_power_avgs = devm_kzalloc(dev, power_avgs_size,
+						    GFP_KERNEL);
+		if (!occ->prev_power_avgs)
+			return -ENOMEM;
+	}
+
 	occ->attrs = devm_kzalloc(dev, sizeof(*occ->attrs) * num_attrs,
 				  GFP_KERNEL);
 	if (!occ->attrs)
diff --git a/drivers/hwmon/occ/common.h b/drivers/hwmon/occ/common.h
index c676e48..08970f8 100644
--- a/drivers/hwmon/occ/common.h
+++ b/drivers/hwmon/occ/common.h
@@ -87,17 +87,24 @@ struct occ_attribute {
 	struct sensor_device_attribute_2 sensor;
 };
 
+struct occ_power_avg {
+	u64 accumulator;
+	u32 update_tag;
+};
+
 struct occ {
 	struct device *bus_dev;
 
 	struct occ_response resp;
 	struct occ_sensors sensors;
+	struct occ_power_avg *prev_power_avgs;
 
 	int powr_sample_time_us;	/* average power sample time */
 	u8 poll_cmd_data;		/* to perform OCC poll command */
 	int (*send_cmd)(struct occ *occ, u8 *cmd);
 
 	unsigned long last_update;
+	unsigned long prev_update;
 	struct mutex lock;		/* lock OCC access */
 
 	struct device *hwmon;
