diff options
| author | Mohsan Habibi <mohsan@motorola.com> | 2014-06-13 16:49:06 -0400 |
|---|---|---|
| committer | Mohsan Habibi <mohsan@motorola.com> | 2014-06-17 18:32:32 -0400 |
| commit | b7a769d59041a3b52a95cd9e96a38dd285aa70f7 (patch) | |
| tree | 10f3157de3f7a9acff618554dd34108097133ae6 | |
| parent | df4b6dc1b018da53d9d4507094bbbc9a429d7b3a (diff) | |
| download | olio-linux-3.10-b7a769d59041a3b52a95cd9e96a38dd285aa70f7.tar.xz olio-linux-3.10-b7a769d59041a3b52a95cd9e96a38dd285aa70f7.zip | |
IKXCLOCK-2142 i2c: omap: convert I2C driver to PM QoS for 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.
Based on: 671d9f5 OMAP: convert I2C driver to PM QoS for latency
constraints
Change-Id: Iea5ac78d89019ed6e8888a0d6489057186748bfa
Signed-off-by: Mohsan Habibi <mohsan@motorola.com>
| -rw-r--r-- | arch/arm/mach-omap2/i2c.c | 19 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-omap.c | 34 | ||||
| -rw-r--r-- | include/linux/i2c-omap.h | 1 |
3 files changed, 20 insertions, 34 deletions
diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c index d940e53dd9f..728ca6729a3 100644 --- a/arch/arm/mach-omap2/i2c.c +++ b/arch/arm/mach-omap2/i2c.c @@ -121,16 +121,6 @@ static int __init omap_i2c_nr_ports(void) return ports; } -/* - * XXX This function is a temporary compatibility wrapper - only - * needed until the I2C driver can be converted to call - * omap_pm_set_max_dev_wakeup_lat() and handle a return code. - */ -static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t) -{ - omap_pm_set_max_mpu_wakeup_lat(dev, t); -} - static const char name[] = "omap_i2c"; int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *i2c_pdata, @@ -168,15 +158,6 @@ int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *i2c_pdata, dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr; pdata->flags = dev_attr->flags; - /* - * 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. - * Only omap3 has support for constraints - */ - if (cpu_is_omap34xx()) - pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(struct omap_i2c_bus_platform_data)); WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name); diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index e02f9e36a7b..86fff71a5db 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -43,6 +43,7 @@ #include <linux/slab.h> #include <linux/i2c-omap.h> #include <linux/pm_runtime.h> +#include <linux/pm_qos.h> #include <linux/pinctrl/consumer.h> /* I2C controller revisions */ @@ -188,9 +189,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 flags; u16 cmd_err; @@ -504,9 +504,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 >> 3); } /* @@ -645,8 +643,13 @@ 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. + */ + pm_qos_update_request(&dev->pm_qos_request, dev->latency); for (i = 0; i < num; i++) { r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1))); @@ -659,8 +662,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) omap_i2c_wait_for_bb(dev); - if (dev->set_mpu_wkup_lat != NULL) - dev->set_mpu_wkup_lat(dev->dev, -1); + pm_qos_update_request(&dev->pm_qos_request, + PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE); out: pm_runtime_mark_last_busy(dev->dev); @@ -1120,7 +1123,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->pins = devm_pinctrl_get_select_default(&pdev->dev); @@ -1151,6 +1153,9 @@ omap_i2c_probe(struct platform_device *pdev) if (IS_ERR_VALUE(r)) goto err_free_mem; + pm_qos_add_request(&dev->pm_qos_request, PM_QOS_CPU_DMA_LATENCY, + PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE); + /* * Read the Rev hi bit-[15:14] ie scheme this is 1 indicates ver2. * On omap1/3/2 Offset 4 is IE Reg the bit [15:14] is 0 at reset. @@ -1206,9 +1211,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 >> 3); } /* reset ASAP, clearing any IRQs */ @@ -1257,6 +1261,7 @@ omap_i2c_probe(struct platform_device *pdev) err_unuse_clocks: omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); + pm_qos_remove_request(&dev->pm_qos_request); pm_runtime_put(dev->dev); pm_runtime_disable(&pdev->dev); err_free_mem: @@ -1275,6 +1280,7 @@ static int omap_i2c_remove(struct platform_device *pdev) return ret; omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); + pm_qos_remove_request(&dev->pm_qos_request); pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); return 0; diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h index babe0cf6d56..509ce0d65f2 100644 --- a/include/linux/i2c-omap.h +++ b/include/linux/i2c-omap.h @@ -32,7 +32,6 @@ struct omap_i2c_bus_platform_data { u32 clkrate; u32 rev; u32 flags; - void (*set_mpu_wkup_lat)(struct device *dev, long set); }; #endif |