|
@@ -43,6 +43,7 @@
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/i2c-omap.h>
|
|
|
#include <linux/pm_runtime.h>
|
|
|
+#include <linux/pm_qos.h>
|
|
|
|
|
|
/* I2C controller revisions */
|
|
|
#define OMAP_I2C_OMAP1_REV_2 0x20
|
|
@@ -186,9 +187,8 @@ struct omap_i2c_dev {
|
|
|
int reg_shift; /* bit shift for I2C register addresses */
|
|
|
struct completion cmd_complete;
|
|
|
struct resource *ioarea;
|
|
|
- u32 latency; /* maximum mpu wkup latency */
|
|
|
- void (*set_mpu_wkup_lat)(struct device *dev,
|
|
|
- long latency);
|
|
|
+ u32 latency; /* maximum MPU wkup latency */
|
|
|
+ struct pm_qos_request pm_qos_request;
|
|
|
u32 speed; /* Speed of bus in kHz */
|
|
|
u32 dtrev; /* extra revision from DT */
|
|
|
u32 flags;
|
|
@@ -494,9 +494,7 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)
|
|
|
dev->b_hw = 1; /* Enable hardware fixes */
|
|
|
|
|
|
/* calculate wakeup latency constraint for MPU */
|
|
|
- if (dev->set_mpu_wkup_lat != NULL)
|
|
|
- dev->latency = (1000000 * dev->threshold) /
|
|
|
- (1000 * dev->speed / 8);
|
|
|
+ dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -631,8 +629,16 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
|
|
|
if (r < 0)
|
|
|
goto out;
|
|
|
|
|
|
- if (dev->set_mpu_wkup_lat != NULL)
|
|
|
- dev->set_mpu_wkup_lat(dev->dev, dev->latency);
|
|
|
+ /*
|
|
|
+ * When waiting for completion of a i2c transfer, we need to
|
|
|
+ * set a wake up latency constraint for the MPU. This is to
|
|
|
+ * ensure quick enough wakeup from idle, when transfer
|
|
|
+ * completes.
|
|
|
+ */
|
|
|
+ if (dev->latency)
|
|
|
+ pm_qos_add_request(&dev->pm_qos_request,
|
|
|
+ PM_QOS_CPU_DMA_LATENCY,
|
|
|
+ dev->latency);
|
|
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)));
|
|
@@ -640,8 +646,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- if (dev->set_mpu_wkup_lat != NULL)
|
|
|
- dev->set_mpu_wkup_lat(dev->dev, -1);
|
|
|
+ if (dev->latency)
|
|
|
+ pm_qos_remove_request(&dev->pm_qos_request);
|
|
|
|
|
|
if (r == 0)
|
|
|
r = num;
|
|
@@ -1097,7 +1103,6 @@ omap_i2c_probe(struct platform_device *pdev)
|
|
|
} else if (pdata != NULL) {
|
|
|
dev->speed = pdata->clkrate;
|
|
|
dev->flags = pdata->flags;
|
|
|
- dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
|
|
|
dev->dtrev = pdata->rev;
|
|
|
}
|
|
|
|
|
@@ -1153,9 +1158,8 @@ omap_i2c_probe(struct platform_device *pdev)
|
|
|
dev->b_hw = 1; /* Enable hardware fixes */
|
|
|
|
|
|
/* calculate wakeup latency constraint for MPU */
|
|
|
- if (dev->set_mpu_wkup_lat != NULL)
|
|
|
- dev->latency = (1000000 * dev->fifo_size) /
|
|
|
- (1000 * dev->speed / 8);
|
|
|
+ dev->latency = (1000000 * dev->fifo_size) /
|
|
|
+ (1000 * dev->speed / 8);
|
|
|
}
|
|
|
|
|
|
/* reset ASAP, clearing any IRQs */
|