aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Pihet <jean.pihet@newoldbits.com>2012-09-20 12:08:03 -0400
committerWolfram Sang <w.sang@pengutronix.de>2012-10-06 07:43:38 -0400
commit3db11feffc1ad2ab9dea27789e6b5b3032827adc (patch)
treea278dcfc5c39ab80fc0357645f87754ed9f51423
parent43fea5813c56e4327371fd3c2209791ef7822de2 (diff)
ARM: OMAP: convert I2C driver to PM QoS for MPU latency constraints
Convert the driver from the outdated omap_pm_set_max_mpu_wakeup_lat API to the new PM QoS API. Since the constraint is on the MPU subsystem, use the PM_QOS_CPU_DMA_LATENCY class of PM QoS. The resulting MPU constraints are used by cpuidle to decide the next power state of the MPU subsystem. The I2C device latency timing is derived from the FIFO size and the clock speed and so is applicable to all OMAP SoCs. Signed-off-by: Jean Pihet <j-pihet@ti.com> Acked-by: Shubhrajyoti D <shubhrajyoti@ti.com> Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Kevin Hilman <khilman@ti.com> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
-rw-r--r--arch/arm/plat-omap/i2c.c21
-rw-r--r--drivers/i2c/busses/i2c-omap.c32
-rw-r--r--include/linux/i2c-omap.h1
3 files changed, 18 insertions, 36 deletions
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index db071bc71c4d..dba8338f6cd7 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -26,7 +26,6 @@
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <linux/i2c-omap.h>
30#include <linux/slab.h> 29#include <linux/slab.h>
31#include <linux/err.h> 30#include <linux/err.h>
32#include <linux/clk.h> 31#include <linux/clk.h>
@@ -34,7 +33,6 @@
34#include <mach/irqs.h> 33#include <mach/irqs.h>
35#include <plat/mux.h> 34#include <plat/mux.h>
36#include <plat/i2c.h> 35#include <plat/i2c.h>
37#include <plat/omap-pm.h>
38#include <plat/omap_device.h> 36#include <plat/omap_device.h>
39 37
40#define OMAP_I2C_SIZE 0x3f 38#define OMAP_I2C_SIZE 0x3f
@@ -129,16 +127,6 @@ static inline int omap1_i2c_add_bus(int bus_id)
129 127
130 128
131#ifdef CONFIG_ARCH_OMAP2PLUS 129#ifdef CONFIG_ARCH_OMAP2PLUS
132/*
133 * XXX This function is a temporary compatibility wrapper - only
134 * needed until the I2C driver can be converted to call
135 * omap_pm_set_max_dev_wakeup_lat() and handle a return code.
136 */
137static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
138{
139 omap_pm_set_max_mpu_wakeup_lat(dev, t);
140}
141
142static inline int omap2_i2c_add_bus(int bus_id) 130static inline int omap2_i2c_add_bus(int bus_id)
143{ 131{
144 int l; 132 int l;
@@ -170,15 +158,6 @@ static inline int omap2_i2c_add_bus(int bus_id)
170 dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr; 158 dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr;
171 pdata->flags = dev_attr->flags; 159 pdata->flags = dev_attr->flags;
172 160
173 /*
174 * When waiting for completion of a i2c transfer, we need to
175 * set a wake up latency constraint for the MPU. This is to
176 * ensure quick enough wakeup from idle, when transfer
177 * completes.
178 * Only omap3 has support for constraints
179 */
180 if (cpu_is_omap34xx())
181 pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
182 pdev = omap_device_build(name, bus_id, oh, pdata, 161 pdev = omap_device_build(name, bus_id, oh, pdata,
183 sizeof(struct omap_i2c_bus_platform_data), 162 sizeof(struct omap_i2c_bus_platform_data),
184 NULL, 0, 0); 163 NULL, 0, 0);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index c78431a4970a..b6c6b95d4a07 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -43,6 +43,7 @@
43#include <linux/slab.h> 43#include <linux/slab.h>
44#include <linux/i2c-omap.h> 44#include <linux/i2c-omap.h>
45#include <linux/pm_runtime.h> 45#include <linux/pm_runtime.h>
46#include <linux/pm_qos.h>
46 47
47/* I2C controller revisions */ 48/* I2C controller revisions */
48#define OMAP_I2C_OMAP1_REV_2 0x20 49#define OMAP_I2C_OMAP1_REV_2 0x20
@@ -186,9 +187,8 @@ struct omap_i2c_dev {
186 int reg_shift; /* bit shift for I2C register addresses */ 187 int reg_shift; /* bit shift for I2C register addresses */
187 struct completion cmd_complete; 188 struct completion cmd_complete;
188 struct resource *ioarea; 189 struct resource *ioarea;
189 u32 latency; /* maximum mpu wkup latency */ 190 u32 latency; /* maximum MPU wkup latency */
190 void (*set_mpu_wkup_lat)(struct device *dev, 191 struct pm_qos_request pm_qos_request;
191 long latency);
192 u32 speed; /* Speed of bus in kHz */ 192 u32 speed; /* Speed of bus in kHz */
193 u32 dtrev; /* extra revision from DT */ 193 u32 dtrev; /* extra revision from DT */
194 u32 flags; 194 u32 flags;
@@ -494,9 +494,7 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)
494 dev->b_hw = 1; /* Enable hardware fixes */ 494 dev->b_hw = 1; /* Enable hardware fixes */
495 495
496 /* calculate wakeup latency constraint for MPU */ 496 /* calculate wakeup latency constraint for MPU */
497 if (dev->set_mpu_wkup_lat != NULL) 497 dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8);
498 dev->latency = (1000000 * dev->threshold) /
499 (1000 * dev->speed / 8);
500} 498}
501 499
502/* 500/*
@@ -631,8 +629,16 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
631 if (r < 0) 629 if (r < 0)
632 goto out; 630 goto out;
633 631
634 if (dev->set_mpu_wkup_lat != NULL) 632 /*
635 dev->set_mpu_wkup_lat(dev->dev, dev->latency); 633 * When waiting for completion of a i2c transfer, we need to
634 * set a wake up latency constraint for the MPU. This is to
635 * ensure quick enough wakeup from idle, when transfer
636 * completes.
637 */
638 if (dev->latency)
639 pm_qos_add_request(&dev->pm_qos_request,
640 PM_QOS_CPU_DMA_LATENCY,
641 dev->latency);
636 642
637 for (i = 0; i < num; i++) { 643 for (i = 0; i < num; i++) {
638 r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1))); 644 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)
640 break; 646 break;
641 } 647 }
642 648
643 if (dev->set_mpu_wkup_lat != NULL) 649 if (dev->latency)
644 dev->set_mpu_wkup_lat(dev->dev, -1); 650 pm_qos_remove_request(&dev->pm_qos_request);
645 651
646 if (r == 0) 652 if (r == 0)
647 r = num; 653 r = num;
@@ -1097,7 +1103,6 @@ omap_i2c_probe(struct platform_device *pdev)
1097 } else if (pdata != NULL) { 1103 } else if (pdata != NULL) {
1098 dev->speed = pdata->clkrate; 1104 dev->speed = pdata->clkrate;
1099 dev->flags = pdata->flags; 1105 dev->flags = pdata->flags;
1100 dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
1101 dev->dtrev = pdata->rev; 1106 dev->dtrev = pdata->rev;
1102 } 1107 }
1103 1108
@@ -1153,9 +1158,8 @@ omap_i2c_probe(struct platform_device *pdev)
1153 dev->b_hw = 1; /* Enable hardware fixes */ 1158 dev->b_hw = 1; /* Enable hardware fixes */
1154 1159
1155 /* calculate wakeup latency constraint for MPU */ 1160 /* calculate wakeup latency constraint for MPU */
1156 if (dev->set_mpu_wkup_lat != NULL) 1161 dev->latency = (1000000 * dev->fifo_size) /
1157 dev->latency = (1000000 * dev->fifo_size) / 1162 (1000 * dev->speed / 8);
1158 (1000 * dev->speed / 8);
1159 } 1163 }
1160 1164
1161 /* reset ASAP, clearing any IRQs */ 1165 /* reset ASAP, clearing any IRQs */
diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
index 92a0dc75bc74..df804ba73e0b 100644
--- a/include/linux/i2c-omap.h
+++ b/include/linux/i2c-omap.h
@@ -34,7 +34,6 @@ struct omap_i2c_bus_platform_data {
34 u32 clkrate; 34 u32 clkrate;
35 u32 rev; 35 u32 rev;
36 u32 flags; 36 u32 flags;
37 void (*set_mpu_wkup_lat)(struct device *dev, long set);
38}; 37};
39 38
40#endif 39#endif