All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class
@ 2011-06-30 15:11 jean.pihet
  2011-06-30 15:11 ` [PATCH 01/11] PM: add a per-device wake-up latency constraints plist jean.pihet
                   ` (23 more replies)
  0 siblings, 24 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

This patch set is in an RFC state, for review and comments.

In order to implement the new class in PM QoS the following changes have been
made:

1. Add a new PM QoS class for device wake-up constraints
(PM_QOS_DEV_WAKEUP_LATENCY).
Due to the per-device nature of the new class the constraints lists are stored
inside the device dev_pm_info struct instead of the internal per-class
constraints lists.
The new class is only available from kernel drivers and so is not exported to
user space.

2. Added a notification of device insertion/removal from the device PM framework
to PM QoS.
This allows to init/de-init the per-device constraints list upon device insertion
and removal.
RFC state for comments and review, barely tested

3. Make the pm_qos_add_request API more generic by using a
struct pm_qos_parameters parameter. This allows easy extension in the future.

4. Upon a change of the strongest constraint in the PM_QOS_DEV_WAKEUP_LATENCY
class a notification chain mechanism is used to take action on the system.
This is the proposed way to have PM QoS and the platform dependant code to
interact with each other, cf. 4 below.
The notification mechanism now passes the constraint request struct ptr in
order for the notifier callback to have access to the full set of constraint
data, e.g. the struct device ptr.

5. cpuidle interaction with the OMAP3 cpuidle handler
Since cpuidle is a CPU centric framework it decides the MPU next power state
based on the MPU exit_latency and target_residency figures.
    
The rest of the power domains get their next power state programmed from
the PM_QOS_DEV_WAKEUP_LATENCY class of the PM QoS framework, via the device
wake-up latency constraints.

Note: the exit_latency and target_residency figures of the MPU include the MPU
itself and the peripherals needed for the MPU to execute instructions (e.g.
main memory, caches, IRQ controller, MMU etc).
Some of those peripherals can belong to other power domains than the MPU
subsystem and so the corresponding latencies must be included in those figures.

6. Update the pm_qos_add_request callers to the generic API

7. Minor clean-ups and rename of struct fields

Questions:
1. How to retrieve the device ptr from a given device driver in order to add
a constraint on it?
2. The device struct has recently been extended with the power domain
information. Can this be used to apply the constraints on power domains?

On-going developments, patches in preparation:
1. write Documentation for the new PM QoS class
2. validate the constraints framework on OMAP4 HW (done on OMAP3)
3. refine the power domains wake-up latency and the cpuidle figures

Based on the master branch of the linux-omap git tree (3.0.0-rc3). Compile
tested using OMAP and x86 generic defconfigs.
Tested on OMAP3 Beagleboard (ES2.x) with full RETention and OFF modes.


Changelog:

v2:
. Rework after comments on the mailing lists
. Added a notification of device insertion/removal from the device PM framework
. Validated on OMAP3 HW


Jean Pihet (10):
  PM: add a per-device wake-up latency constraints plist
  PM: extend PM QoS with per-device wake-up constraints
  PM QoS: support the dynamic devices insertion and removal
  OMAP PM: create a PM layer plugin for per-device constraints
  OMAP PM: early init of the pwrdms states
  OMAP2+: powerdomain: control power domains next state
  OMAP3: powerdomain data: add wake-up latency figures
  OMAP2+: omap_hwmod: manage the wake-up latency constraints
  OMAP: PM CONSTRAINTS: implement the devices wake-up latency
    constraints
  OMAP2+: cpuidle only influences the MPU state

Vishwanath BS (1):
  OMAP4: powerdomain data: add wake-up latency figures

 arch/arm/mach-omap2/cpuidle34xx.c            |   42 +---
 arch/arm/mach-omap2/omap_hwmod.c             |   26 ++-
 arch/arm/mach-omap2/pm.h                     |   17 ++-
 arch/arm/mach-omap2/pm34xx.c                 |    2 +-
 arch/arm/mach-omap2/pm44xx.c                 |    2 +-
 arch/arm/mach-omap2/powerdomain.c            |  190 ++++++++++++++
 arch/arm/mach-omap2/powerdomain.h            |   33 +++-
 arch/arm/mach-omap2/powerdomains3xxx_data.c  |   77 ++++++
 arch/arm/mach-omap2/powerdomains44xx_data.c  |   85 +++++++
 arch/arm/plat-omap/Kconfig                   |    7 +
 arch/arm/plat-omap/Makefile                  |    1 +
 arch/arm/plat-omap/i2c.c                     |   20 --
 arch/arm/plat-omap/include/plat/omap-pm.h    |  128 ----------
 arch/arm/plat-omap/include/plat/omap_hwmod.h |    2 +
 arch/arm/plat-omap/omap-pm-constraints.c     |  344 ++++++++++++++++++++++++++
 arch/arm/plat-omap/omap-pm-noop.c            |   89 -------
 drivers/base/power/main.c                    |    5 +
 drivers/i2c/busses/i2c-omap.c                |   35 ++-
 drivers/media/video/via-camera.c             |    5 +-
 drivers/net/e1000e/netdev.c                  |    9 +-
 drivers/net/wireless/ipw2x00/ipw2100.c       |    6 +-
 include/linux/pm.h                           |    3 +
 include/linux/pm_qos_params.h                |   42 ++--
 kernel/pm_qos_params.c                       |  231 ++++++++++++------
 sound/core/pcm_native.c                      |    8 +-
 25 files changed, 1023 insertions(+), 386 deletions(-)
 create mode 100644 arch/arm/plat-omap/omap-pm-constraints.c

-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 122+ messages in thread

* [PATCH 01/11] PM: add a per-device wake-up latency constraints plist
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` jean.pihet
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

Add the field wakeup_lat_plist_head in the struct dev_pm_info
and the initialization of the plist in device_pm_init.

This enables the implementation of per-device constraints in
PM QoS.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 drivers/base/power/main.c |    3 +++
 include/linux/pm.h        |    2 ++
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index aa632020..b1fd96b 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -96,6 +96,8 @@ void device_pm_add(struct device *dev)
 			dev_name(dev->parent));
 	list_add_tail(&dev->power.entry, &dpm_list);
 	mutex_unlock(&dpm_list_mtx);
+	/* ToDo: call PM QoS to init the per-device wakeup latency constraints */
+	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
 }
 
 /**
@@ -106,6 +108,7 @@ void device_pm_remove(struct device *dev)
 {
 	pr_debug("PM: Removing info for %s:%s\n",
 		 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
+	/* ToDo: call PM QoS to de-init the per-device wakeup latency constraints */
 	complete_all(&dev->power.completion);
 	mutex_lock(&dpm_list_mtx);
 	list_del_init(&dev->power.entry);
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 3160648..35fe682 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -22,6 +22,7 @@
 #define _LINUX_PM_H
 
 #include <linux/list.h>
+#include <linux/plist.h>
 #include <linux/workqueue.h>
 #include <linux/spinlock.h>
 #include <linux/wait.h>
@@ -462,6 +463,7 @@ struct dev_pm_info {
 	unsigned long		accounting_timestamp;
 	void			*subsys_data;  /* Owned by the subsystem. */
 #endif
+	struct plist_head	wakeup_lat_plist_head;
 };
 
 extern void update_pm_runtime_accounting(struct device *dev);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 01/11] PM: add a per-device wake-up latency constraints plist
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
  2011-06-30 15:11 ` [PATCH 01/11] PM: add a per-device wake-up latency constraints plist jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-07-02 19:39   ` Rafael J. Wysocki
  2011-07-02 19:39   ` Rafael J. Wysocki
  2011-06-30 15:11 ` [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints jean.pihet
                   ` (21 subsequent siblings)
  23 siblings, 2 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

Add the field wakeup_lat_plist_head in the struct dev_pm_info
and the initialization of the plist in device_pm_init.

This enables the implementation of per-device constraints in
PM QoS.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 drivers/base/power/main.c |    3 +++
 include/linux/pm.h        |    2 ++
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index aa632020..b1fd96b 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -96,6 +96,8 @@ void device_pm_add(struct device *dev)
 			dev_name(dev->parent));
 	list_add_tail(&dev->power.entry, &dpm_list);
 	mutex_unlock(&dpm_list_mtx);
+	/* ToDo: call PM QoS to init the per-device wakeup latency constraints */
+	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
 }
 
 /**
@@ -106,6 +108,7 @@ void device_pm_remove(struct device *dev)
 {
 	pr_debug("PM: Removing info for %s:%s\n",
 		 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
+	/* ToDo: call PM QoS to de-init the per-device wakeup latency constraints */
 	complete_all(&dev->power.completion);
 	mutex_lock(&dpm_list_mtx);
 	list_del_init(&dev->power.entry);
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 3160648..35fe682 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -22,6 +22,7 @@
 #define _LINUX_PM_H
 
 #include <linux/list.h>
+#include <linux/plist.h>
 #include <linux/workqueue.h>
 #include <linux/spinlock.h>
 #include <linux/wait.h>
@@ -462,6 +463,7 @@ struct dev_pm_info {
 	unsigned long		accounting_timestamp;
 	void			*subsys_data;  /* Owned by the subsystem. */
 #endif
+	struct plist_head	wakeup_lat_plist_head;
 };
 
 extern void update_pm_runtime_accounting(struct device *dev);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
  2011-06-30 15:11 ` [PATCH 01/11] PM: add a per-device wake-up latency constraints plist jean.pihet
  2011-06-30 15:11 ` jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` jean.pihet
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

- add a new PM QoS class PM_QOS_DEV_WAKEUP_LATENCY for device wake-up
constraints. Due to the per-device nature of the new class the constraints
list is stored inside the device dev_pm_info struct instead of the internal
per-class constraints lists.
The new class is only available from kernel drivers and so is not exported
to user space.
The new class is used to put constraints on given devices in the system
while the existing PM_QOS_CPU_DMA_LATENCY class is used by cpuidle to
determine the next MPU subsystem state.

- make the pm_qos_add_request API more generic by using a struct
pm_qos_parameters parameter

- the notification mechanism now passes the constraint request struct ptr
in order for the notifier callback to have access to the full set of
constraint data, e.g. the struct device ptr

- update the pm_qos_add_request callers to the generic API

- minor clean-ups and rename of struct fields

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/plat-omap/i2c.c               |   20 ----
 drivers/i2c/busses/i2c-omap.c          |   35 ++++---
 drivers/media/video/via-camera.c       |    5 +-
 drivers/net/e1000e/netdev.c            |    9 +-
 drivers/net/wireless/ipw2x00/ipw2100.c |    6 +-
 include/linux/pm_qos_params.h          |   40 +++++---
 kernel/pm_qos_params.c                 |  185 +++++++++++++++++++-------------
 sound/core/pcm_native.c                |    8 +-
 8 files changed, 177 insertions(+), 131 deletions(-)

diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index 3341ca4..e1e2502 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -34,7 +34,6 @@
 #include <mach/irqs.h>
 #include <plat/mux.h>
 #include <plat/i2c.h>
-#include <plat/omap-pm.h>
 #include <plat/omap_device.h>
 
 #define OMAP_I2C_SIZE		0x3f
@@ -113,16 +112,6 @@ static inline int omap1_i2c_add_bus(int bus_id)
 
 
 #ifdef CONFIG_ARCH_OMAP2PLUS
-/*
- * 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 struct omap_device_pm_latency omap_i2c_latency[] = {
 	[0] = {
 		.deactivate_func	= omap_device_idle_hwmods,
@@ -151,15 +140,6 @@ static inline int omap2_i2c_add_bus(int bus_id)
 	}
 
 	pdata = &i2c_pdata[bus_id - 1];
-	/*
-	 * 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;
 	od = omap_device_build(name, bus_id, oh, pdata,
 			sizeof(struct omap_i2c_bus_platform_data),
 			omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 58a58c7..66fd76b 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -40,6 +40,7 @@
 #include <linux/slab.h>
 #include <linux/i2c-omap.h>
 #include <linux/pm_runtime.h>
+#include <linux/pm_qos_params.h>
 
 /* I2C controller revisions */
 #define OMAP_I2C_REV_2			0x20
@@ -179,8 +180,7 @@ struct omap_i2c_dev {
 	struct completion	cmd_complete;
 	struct resource		*ioarea;
 	u32			latency;	/* maximum mpu wkup latency */
-	void			(*set_mpu_wkup_lat)(struct device *dev,
-						    long latency);
+	struct pm_qos_request_list pm_qos_request;
 	u32			speed;		/* Speed of bus in Khz */
 	u16			cmd_err;
 	u8			*buf;
@@ -641,6 +641,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 	struct omap_i2c_dev *dev = i2c_get_adapdata(adap);
 	int i;
 	int r;
+	struct pm_qos_parameters pm_qos_params;
 
 	omap_i2c_unidle(dev);
 
@@ -648,8 +649,19 @@ 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.
+	 * Only OMAP3 has support for constraints
+	 */
+	if (cpu_is_omap34xx()) {
+		pm_qos_params.dev = dev->dev;
+		pm_qos_params.class = PM_QOS_CPU_DMA_LATENCY;
+		pm_qos_params.value = dev->latency;
+		pm_qos_add_request(&dev->pm_qos_request, &pm_qos_params);
+	}
 
 	for (i = 0; i < num; i++) {
 		r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)));
@@ -657,8 +669,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 (cpu_is_omap34xx())
+		pm_qos_remove_request(&dev->pm_qos_request);
 
 	if (r == 0)
 		r = num;
@@ -1007,13 +1019,10 @@ omap_i2c_probe(struct platform_device *pdev)
 		goto err_release_region;
 	}
 
-	if (pdata != NULL) {
+	if (pdata != NULL)
 		speed = pdata->clkrate;
-		dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
-	} else {
+	else
 		speed = 100;	/* Default speed */
-		dev->set_mpu_wkup_lat = NULL;
-	}
 
 	dev->speed = speed;
 	dev->idle = 1;
@@ -1066,8 +1075,8 @@ omap_i2c_probe(struct platform_device *pdev)
 			dev->fifo_size = (dev->fifo_size / 2);
 			dev->b_hw = 1; /* Enable hardware fixes */
 		}
-		/* calculate wakeup latency constraint for MPU */
-		if (dev->set_mpu_wkup_lat != NULL)
+		/* calculate device wakeup latency constraint */
+		if (cpu_is_omap34xx())
 			dev->latency = (1000000 * dev->fifo_size) /
 				       (1000 * speed / 8);
 	}
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 85d3048..5ca12e2 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -1086,6 +1086,7 @@ static int viacam_streamon(struct file *filp, void *priv, enum v4l2_buf_type t)
 {
 	struct via_camera *cam = priv;
 	int ret = 0;
+	struct pm_qos_parameters pm_qos_params;
 
 	if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
@@ -1120,7 +1121,9 @@ static int viacam_streamon(struct file *filp, void *priv, enum v4l2_buf_type t)
 	 * requirement which will keep the CPU out of the deeper sleep
 	 * states.
 	 */
-	pm_qos_add_request(&cam->qos_request, PM_QOS_CPU_DMA_LATENCY, 50);
+	pm_qos_params.class = PM_QOS_CPU_DMA_LATENCY;
+	pm_qos_params.value = 50;
+	pm_qos_add_request(&cam->qos_request, &pm_qos_params);
 	/*
 	 * Fire things up.
 	 */
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 3310c3d..c4cce8a 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -3604,6 +3604,7 @@ static int e1000_open(struct net_device *netdev)
 	struct e1000_hw *hw = &adapter->hw;
 	struct pci_dev *pdev = adapter->pdev;
 	int err;
+	struct pm_qos_parameters pm_qos_params;
 
 	/* disallow open during test */
 	if (test_bit(__E1000_TESTING, &adapter->state))
@@ -3641,10 +3642,12 @@ static int e1000_open(struct net_device *netdev)
 
 	/* DMA latency requirement to workaround early-receive/jumbo issue */
 	if ((adapter->flags & FLAG_HAS_ERT) ||
-	    (adapter->hw.mac.type == e1000_pch2lan))
+	    (adapter->hw.mac.type == e1000_pch2lan)) {
+		pm_qos_params.class = PM_QOS_CPU_DMA_LATENCY;
+		pm_qos_params.value = PM_QOS_DEFAULT_VALUE;
 		pm_qos_add_request(&adapter->netdev->pm_qos_req,
-				   PM_QOS_CPU_DMA_LATENCY,
-				   PM_QOS_DEFAULT_VALUE);
+				   &pm_qos_params);
+	}
 
 	/*
 	 * before we allocate an interrupt, we must be ready to handle it.
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 4430775..585ad04 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -6643,12 +6643,14 @@ static struct pci_driver ipw2100_pci_driver = {
 static int __init ipw2100_init(void)
 {
 	int ret;
+	struct pm_qos_parameters pm_qos_params;
 
 	printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
 	printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
 
-	pm_qos_add_request(&ipw2100_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
-			   PM_QOS_DEFAULT_VALUE);
+	pm_qos_params.class = PM_QOS_CPU_DMA_LATENCY;
+	pm_qos_params.value = PM_QOS_DEFAULT_VALUE;
+	pm_qos_add_request(&ipw2100_pm_qos_req, &pm_qos_params);
 
 	ret = pci_register_driver(&ipw2100_pci_driver);
 	if (ret)
diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
index a7d87f9..e6e16cb 100644
--- a/include/linux/pm_qos_params.h
+++ b/include/linux/pm_qos_params.h
@@ -8,31 +8,41 @@
 #include <linux/notifier.h>
 #include <linux/miscdevice.h>
 
-#define PM_QOS_RESERVED 0
-#define PM_QOS_CPU_DMA_LATENCY 1
-#define PM_QOS_NETWORK_LATENCY 2
-#define PM_QOS_NETWORK_THROUGHPUT 3
+#define	PM_QOS_RESERVED			0
+#define	PM_QOS_CPU_DMA_LATENCY		1
+#define	PM_QOS_DEV_WAKEUP_LATENCY	2
+#define	PM_QOS_NETWORK_LATENCY		3
+#define	PM_QOS_NETWORK_THROUGHPUT	4
 
-#define PM_QOS_NUM_CLASSES 4
-#define PM_QOS_DEFAULT_VALUE -1
+#define PM_QOS_NUM_CLASSES		5
+#define PM_QOS_DEFAULT_VALUE		-1
 
-#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
-#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
-#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE	0
+#define	PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
+#define	PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE	0
+#define	PM_QOS_NETWORK_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
+#define	PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE	0
 
 struct pm_qos_request_list {
 	struct plist_node list;
-	int pm_qos_class;
+	int class;
+	struct device *dev;
 };
 
-void pm_qos_add_request(struct pm_qos_request_list *l, int pm_qos_class, s32 value);
+struct pm_qos_parameters {
+	int class;
+	struct device *dev;
+	s32 value;
+};
+
+void pm_qos_add_request(struct pm_qos_request_list *l,
+			struct pm_qos_parameters *params);
 void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
-		s32 new_value);
+			   s32 new_value);
 void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
 
-int pm_qos_request(int pm_qos_class);
-int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
-int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
+int pm_qos_request(int class);
+int pm_qos_add_notifier(int class, struct notifier_block *notifier);
+int pm_qos_remove_notifier(int class, struct notifier_block *notifier);
 int pm_qos_request_active(struct pm_qos_request_list *req);
 
 #endif
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
index 6824ca7..d61c8e5 100644
--- a/kernel/pm_qos_params.c
+++ b/kernel/pm_qos_params.c
@@ -60,7 +60,7 @@ enum pm_qos_type {
  * types linux supports for 32 bit quantites
  */
 struct pm_qos_object {
-	struct plist_head requests;
+	struct plist_head *requests;
 	struct blocking_notifier_head *notifiers;
 	struct miscdevice pm_qos_power_miscdev;
 	char *name;
@@ -72,9 +72,12 @@ struct pm_qos_object {
 static DEFINE_SPINLOCK(pm_qos_lock);
 
 static struct pm_qos_object null_pm_qos;
+
 static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier);
+static struct plist_head _cpu_dma_reqs =
+			PLIST_HEAD_INIT(_cpu_dma_reqs, pm_qos_lock);
 static struct pm_qos_object cpu_dma_pm_qos = {
-	.requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock),
+	.requests = &_cpu_dma_reqs,
 	.notifiers = &cpu_dma_lat_notifier,
 	.name = "cpu_dma_latency",
 	.target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
@@ -82,9 +85,20 @@ static struct pm_qos_object cpu_dma_pm_qos = {
 	.type = PM_QOS_MIN,
 };
 
+static BLOCKING_NOTIFIER_HEAD(dev_wakeup_lat_notifier);
+static struct pm_qos_object dev_wakeup_lat_pm_qos = {
+	.notifiers = &dev_wakeup_lat_notifier,
+	.name = "dev_wakeup_latency",
+	.target_value = PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE,
+	.default_value = PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE,
+	.type = PM_QOS_MIN,
+};
+
 static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
+static struct plist_head _network_lat_reqs =
+			PLIST_HEAD_INIT(_network_lat_reqs, pm_qos_lock);
 static struct pm_qos_object network_lat_pm_qos = {
-	.requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock),
+	.requests = &_network_lat_reqs,
 	.notifiers = &network_lat_notifier,
 	.name = "network_latency",
 	.target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
@@ -94,8 +108,10 @@ static struct pm_qos_object network_lat_pm_qos = {
 
 
 static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier);
+static struct plist_head _network_throughput_reqs =
+			PLIST_HEAD_INIT(_network_throughput_reqs, pm_qos_lock);
 static struct pm_qos_object network_throughput_pm_qos = {
-	.requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock),
+	.requests = &_network_throughput_reqs,
 	.notifiers = &network_throughput_notifier,
 	.name = "network_throughput",
 	.target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
@@ -107,6 +123,7 @@ static struct pm_qos_object network_throughput_pm_qos = {
 static struct pm_qos_object *pm_qos_array[] = {
 	&null_pm_qos,
 	&cpu_dma_pm_qos,
+	&dev_wakeup_lat_pm_qos,
 	&network_lat_pm_qos,
 	&network_throughput_pm_qos
 };
@@ -129,19 +146,19 @@ static const struct file_operations pm_qos_power_fops = {
 /* unlocked internal variant */
 static inline int pm_qos_get_value(struct pm_qos_object *o)
 {
-	if (plist_head_empty(&o->requests))
+	if (plist_head_empty(o->requests))
 		return o->default_value;
 
 	switch (o->type) {
-	case PM_QOS_MIN:
-		return plist_first(&o->requests)->prio;
+		case PM_QOS_MIN:
+			return plist_first(o->requests)->prio;
 
-	case PM_QOS_MAX:
-		return plist_last(&o->requests)->prio;
+		case PM_QOS_MAX:
+			return plist_last(o->requests)->prio;
 
-	default:
-		/* runtime check for not using enum */
-		BUG();
+		default:
+			/* runtime check for not using enum */
+			BUG();
 	}
 }
 
@@ -155,13 +172,22 @@ static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value)
 	o->target_value = value;
 }
 
-static void update_target(struct pm_qos_object *o, struct plist_node *node,
-			  int del, int value)
+static void update_target(struct pm_qos_request_list *req, int del, int value)
 {
 	unsigned long flags;
 	int prev_value, curr_value;
+	struct pm_qos_object *o = pm_qos_array[req->class];
+	struct plist_node *node = &req->list;
 
 	spin_lock_irqsave(&pm_qos_lock, flags);
+	/*
+	 * PM_QOS_DEV_WAKEUP_LATENCY:
+	 * Use the per-device wake-up latency constraints list for
+	 * constraints storage
+	 */
+	if (req->class == PM_QOS_DEV_WAKEUP_LATENCY)
+		o->requests = &req->dev->power.wakeup_lat_plist_head;
+
 	prev_value = pm_qos_get_value(o);
 	/* PM_QOS_DEFAULT_VALUE is a signal that the value is unchanged */
 	if (value != PM_QOS_DEFAULT_VALUE) {
@@ -170,13 +196,13 @@ static void update_target(struct pm_qos_object *o, struct plist_node *node,
 		 * with new value and add, then see if the extremal
 		 * changed
 		 */
-		plist_del(node, &o->requests);
+		plist_del(node, o->requests);
 		plist_node_init(node, value);
-		plist_add(node, &o->requests);
+		plist_add(node, o->requests);
 	} else if (del) {
-		plist_del(node, &o->requests);
+		plist_del(node, o->requests);
 	} else {
-		plist_add(node, &o->requests);
+		plist_add(node, o->requests);
 	}
 	curr_value = pm_qos_get_value(o);
 	pm_qos_set_value(o, curr_value);
@@ -185,7 +211,7 @@ static void update_target(struct pm_qos_object *o, struct plist_node *node,
 	if (prev_value != curr_value)
 		blocking_notifier_call_chain(o->notifiers,
 					     (unsigned long)curr_value,
-					     NULL);
+					     req);
 }
 
 static int register_pm_qos_misc(struct pm_qos_object *qos)
@@ -199,65 +225,71 @@ static int register_pm_qos_misc(struct pm_qos_object *qos)
 
 static int find_pm_qos_object_by_minor(int minor)
 {
-	int pm_qos_class;
+	int class;
 
-	for (pm_qos_class = 0;
-		pm_qos_class < PM_QOS_NUM_CLASSES; pm_qos_class++) {
+	for (class = 0;
+		class < PM_QOS_NUM_CLASSES; class++) {
 		if (minor ==
-			pm_qos_array[pm_qos_class]->pm_qos_power_miscdev.minor)
-			return pm_qos_class;
+			pm_qos_array[class]->pm_qos_power_miscdev.minor)
+			return class;
 	}
 	return -1;
 }
 
 /**
  * pm_qos_request - returns current system wide qos expectation
- * @pm_qos_class: identification of which qos value is requested
+ * @class: identification of which qos value is requested
  *
  * This function returns the current target value.
  */
-int pm_qos_request(int pm_qos_class)
+int pm_qos_request(int class)
 {
-	return pm_qos_read_value(pm_qos_array[pm_qos_class]);
+	if (class == PM_QOS_DEV_WAKEUP_LATENCY)
+		return pm_qos_get_value(pm_qos_array[class]);
+	else
+		return pm_qos_read_value(pm_qos_array[class]);
 }
 EXPORT_SYMBOL_GPL(pm_qos_request);
 
 int pm_qos_request_active(struct pm_qos_request_list *req)
 {
-	return req->pm_qos_class != 0;
+	return req->class != 0;
 }
 EXPORT_SYMBOL_GPL(pm_qos_request_active);
 
 /**
  * pm_qos_add_request - inserts new qos request into the list
  * @dep: pointer to a preallocated handle
- * @pm_qos_class: identifies which list of qos request to use
- * @value: defines the qos request
+ * @params: request parameters
  *
- * This function inserts a new entry in the pm_qos_class list of requested qos
+ * This function inserts a new entry in the class list of requested qos
  * performance characteristics.  It recomputes the aggregate QoS expectations
- * for the pm_qos_class of parameters and initializes the pm_qos_request_list
- * handle.  Caller needs to save this handle for later use in updates and
+ * for the class of parameters and initializes the pm_qos_request_list
+ * handle. Caller needs to save this handle for later use in updates and
  * removal.
  */
 
-void pm_qos_add_request(struct pm_qos_request_list *dep,
-			int pm_qos_class, s32 value)
+void pm_qos_add_request(struct pm_qos_request_list *pm_qos_req,
+			struct pm_qos_parameters *pm_qos_params)
 {
-	struct pm_qos_object *o =  pm_qos_array[pm_qos_class];
+	struct pm_qos_object *o =  pm_qos_array[pm_qos_params->class];
 	int new_value;
 
-	if (pm_qos_request_active(dep)) {
-		WARN(1, KERN_ERR "pm_qos_add_request() called for already added request\n");
+	if ((pm_qos_params->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
+	    (pm_qos_request_active(pm_qos_req))) {
+		WARN(1, KERN_ERR "pm_qos_add_request() called for already "
+		     "added request\n");
 		return;
 	}
-	if (value == PM_QOS_DEFAULT_VALUE)
+
+	if (pm_qos_params->value == PM_QOS_DEFAULT_VALUE)
 		new_value = o->default_value;
 	else
-		new_value = value;
-	plist_node_init(&dep->list, new_value);
-	dep->pm_qos_class = pm_qos_class;
-	update_target(o, &dep->list, 0, PM_QOS_DEFAULT_VALUE);
+		new_value = pm_qos_params->value;
+	plist_node_init(&pm_qos_req->list, new_value);
+	pm_qos_req->class = pm_qos_params->class;
+	pm_qos_req->dev = pm_qos_params->dev;
+	update_target(pm_qos_req, 0, PM_QOS_DEFAULT_VALUE);
 }
 EXPORT_SYMBOL_GPL(pm_qos_add_request);
 
@@ -266,8 +298,8 @@ EXPORT_SYMBOL_GPL(pm_qos_add_request);
  * @pm_qos_req : handle to list element holding a pm_qos request to use
  * @value: defines the qos request
  *
- * Updates an existing qos request for the pm_qos_class of parameters along
- * with updating the target pm_qos_class value.
+ * Updates an existing qos request for the class of parameters along
+ * with updating the target class value.
  *
  * Attempts are made to make this code callable on hot code paths.
  */
@@ -275,25 +307,25 @@ void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
 			   s32 new_value)
 {
 	s32 temp;
-	struct pm_qos_object *o;
+	struct pm_qos_object *o = pm_qos_array[pm_qos_req->class];
 
 	if (!pm_qos_req) /*guard against callers passing in null */
 		return;
 
-	if (!pm_qos_request_active(pm_qos_req)) {
-		WARN(1, KERN_ERR "pm_qos_update_request() called for unknown object\n");
+	if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
+	    (!pm_qos_request_active(pm_qos_req))) {
+		WARN(1, KERN_ERR "pm_qos_update_request() called for unknown "
+		     "object\n");
 		return;
 	}
 
-	o = pm_qos_array[pm_qos_req->pm_qos_class];
-
 	if (new_value == PM_QOS_DEFAULT_VALUE)
 		temp = o->default_value;
 	else
 		temp = new_value;
 
 	if (temp != pm_qos_req->list.prio)
-		update_target(o, &pm_qos_req->list, 0, temp);
+		update_target(pm_qos_req, 0, temp);
 }
 EXPORT_SYMBOL_GPL(pm_qos_update_request);
 
@@ -302,42 +334,41 @@ EXPORT_SYMBOL_GPL(pm_qos_update_request);
  * @pm_qos_req: handle to request list element
  *
  * Will remove pm qos request from the list of requests and
- * recompute the current target value for the pm_qos_class.  Call this
+ * recompute the current target value for the class.  Call this
  * on slow code paths.
  */
 void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req)
 {
-	struct pm_qos_object *o;
-
 	if (pm_qos_req == NULL)
 		return;
 		/* silent return to keep pcm code cleaner */
 
-	if (!pm_qos_request_active(pm_qos_req)) {
-		WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown object\n");
+	if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
+	    (!pm_qos_request_active(pm_qos_req))) {
+		WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown "
+		     "object\n");
 		return;
 	}
 
-	o = pm_qos_array[pm_qos_req->pm_qos_class];
-	update_target(o, &pm_qos_req->list, 1, PM_QOS_DEFAULT_VALUE);
+	update_target(pm_qos_req, 1, PM_QOS_DEFAULT_VALUE);
 	memset(pm_qos_req, 0, sizeof(*pm_qos_req));
 }
 EXPORT_SYMBOL_GPL(pm_qos_remove_request);
 
 /**
  * pm_qos_add_notifier - sets notification entry for changes to target value
- * @pm_qos_class: identifies which qos target changes should be notified.
+ * @class: identifies which qos target changes should be notified.
  * @notifier: notifier block managed by caller.
  *
  * will register the notifier into a notification chain that gets called
- * upon changes to the pm_qos_class target value.
+ * upon changes to the class target value.
  */
-int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier)
+int pm_qos_add_notifier(int class, struct notifier_block *notifier)
 {
 	int retval;
 
 	retval = blocking_notifier_chain_register(
-			pm_qos_array[pm_qos_class]->notifiers, notifier);
+			pm_qos_array[class]->notifiers, notifier);
 
 	return retval;
 }
@@ -345,18 +376,18 @@ EXPORT_SYMBOL_GPL(pm_qos_add_notifier);
 
 /**
  * pm_qos_remove_notifier - deletes notification entry from chain.
- * @pm_qos_class: identifies which qos target changes are notified.
+ * @class: identifies which qos target changes are notified.
  * @notifier: notifier block to be removed.
  *
  * will remove the notifier from the notification chain that gets called
- * upon changes to the pm_qos_class target value.
+ * upon changes to the class target value.
  */
-int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier)
+int pm_qos_remove_notifier(int class, struct notifier_block *notifier)
 {
 	int retval;
 
 	retval = blocking_notifier_chain_unregister(
-			pm_qos_array[pm_qos_class]->notifiers, notifier);
+			pm_qos_array[class]->notifiers, notifier);
 
 	return retval;
 }
@@ -364,15 +395,17 @@ EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
 
 static int pm_qos_power_open(struct inode *inode, struct file *filp)
 {
-	long pm_qos_class;
+	struct pm_qos_parameters pm_qos_params;
 
-	pm_qos_class = find_pm_qos_object_by_minor(iminor(inode));
-	if (pm_qos_class >= 0) {
-               struct pm_qos_request_list *req = kzalloc(sizeof(*req), GFP_KERNEL);
+	pm_qos_params.class = find_pm_qos_object_by_minor(iminor(inode));
+	if (pm_qos_params.class >= 0) {
+		struct pm_qos_request_list *req = kzalloc(sizeof(*req),
+							  GFP_KERNEL);
 		if (!req)
 			return -ENOMEM;
 
-		pm_qos_add_request(req, pm_qos_class, PM_QOS_DEFAULT_VALUE);
+		pm_qos_params.value = PM_QOS_DEFAULT_VALUE;
+		pm_qos_add_request(req, &pm_qos_params);
 		filp->private_data = req;
 
 		if (filp->private_data)
@@ -406,7 +439,7 @@ static ssize_t pm_qos_power_read(struct file *filp, char __user *buf,
 	if (!pm_qos_request_active(pm_qos_req))
 		return -EINVAL;
 
-	o = pm_qos_array[pm_qos_req->pm_qos_class];
+	o = pm_qos_array[pm_qos_req->class];
 	spin_lock_irqsave(&pm_qos_lock, flags);
 	value = pm_qos_get_value(o);
 	spin_unlock_irqrestore(&pm_qos_lock, flags);
@@ -462,18 +495,20 @@ static int __init pm_qos_power_init(void)
 
 	ret = register_pm_qos_misc(&cpu_dma_pm_qos);
 	if (ret < 0) {
-		printk(KERN_ERR "pm_qos_param: cpu_dma_latency setup failed\n");
+		printk(KERN_ERR
+		       "pm_qos_param: cpu_dma_latency setup failed\n");
 		return ret;
 	}
 	ret = register_pm_qos_misc(&network_lat_pm_qos);
 	if (ret < 0) {
-		printk(KERN_ERR "pm_qos_param: network_latency setup failed\n");
+		printk(KERN_ERR
+		       "pm_qos_param: network_latency setup failed\n");
 		return ret;
 	}
 	ret = register_pm_qos_misc(&network_throughput_pm_qos);
 	if (ret < 0)
 		printk(KERN_ERR
-			"pm_qos_param: network_throughput setup failed\n");
+		       "pm_qos_param: network_throughput setup failed\n");
 
 	return ret;
 }
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 1c6be91..a19605c 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -375,6 +375,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
 	int err, usecs;
 	unsigned int bits;
 	snd_pcm_uframes_t frames;
+	struct pm_qos_parameters pm_qos_params;
 
 	if (PCM_RUNTIME_CHECK(substream))
 		return -ENXIO;
@@ -455,9 +456,12 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
 
 	if (pm_qos_request_active(&substream->latency_pm_qos_req))
 		pm_qos_remove_request(&substream->latency_pm_qos_req);
-	if ((usecs = period_to_usecs(runtime)) >= 0)
+	if ((usecs = period_to_usecs(runtime)) >= 0) {
+		pm_qos_params.class = PM_QOS_CPU_DMA_LATENCY;
+		pm_qos_params.value = usecs;
 		pm_qos_add_request(&substream->latency_pm_qos_req,
-				   PM_QOS_CPU_DMA_LATENCY, usecs);
+				   &pm_qos_params);
+	}
 	return 0;
  _error:
 	/* hardware might be unusable from this time,
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (2 preceding siblings ...)
  2011-06-30 15:11 ` [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-07-02 21:10   ` Rafael J. Wysocki
                     ` (3 more replies)
  2011-06-30 15:11 ` [PATCH 03/11] PM QoS: support the dynamic devices insertion and removal jean.pihet
                   ` (19 subsequent siblings)
  23 siblings, 4 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

- add a new PM QoS class PM_QOS_DEV_WAKEUP_LATENCY for device wake-up
constraints. Due to the per-device nature of the new class the constraints
list is stored inside the device dev_pm_info struct instead of the internal
per-class constraints lists.
The new class is only available from kernel drivers and so is not exported
to user space.
The new class is used to put constraints on given devices in the system
while the existing PM_QOS_CPU_DMA_LATENCY class is used by cpuidle to
determine the next MPU subsystem state.

- make the pm_qos_add_request API more generic by using a struct
pm_qos_parameters parameter

- the notification mechanism now passes the constraint request struct ptr
in order for the notifier callback to have access to the full set of
constraint data, e.g. the struct device ptr

- update the pm_qos_add_request callers to the generic API

- minor clean-ups and rename of struct fields

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/plat-omap/i2c.c               |   20 ----
 drivers/i2c/busses/i2c-omap.c          |   35 ++++---
 drivers/media/video/via-camera.c       |    5 +-
 drivers/net/e1000e/netdev.c            |    9 +-
 drivers/net/wireless/ipw2x00/ipw2100.c |    6 +-
 include/linux/pm_qos_params.h          |   40 +++++---
 kernel/pm_qos_params.c                 |  185 +++++++++++++++++++-------------
 sound/core/pcm_native.c                |    8 +-
 8 files changed, 177 insertions(+), 131 deletions(-)

diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index 3341ca4..e1e2502 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -34,7 +34,6 @@
 #include <mach/irqs.h>
 #include <plat/mux.h>
 #include <plat/i2c.h>
-#include <plat/omap-pm.h>
 #include <plat/omap_device.h>
 
 #define OMAP_I2C_SIZE		0x3f
@@ -113,16 +112,6 @@ static inline int omap1_i2c_add_bus(int bus_id)
 
 
 #ifdef CONFIG_ARCH_OMAP2PLUS
-/*
- * 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 struct omap_device_pm_latency omap_i2c_latency[] = {
 	[0] = {
 		.deactivate_func	= omap_device_idle_hwmods,
@@ -151,15 +140,6 @@ static inline int omap2_i2c_add_bus(int bus_id)
 	}
 
 	pdata = &i2c_pdata[bus_id - 1];
-	/*
-	 * 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;
 	od = omap_device_build(name, bus_id, oh, pdata,
 			sizeof(struct omap_i2c_bus_platform_data),
 			omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 58a58c7..66fd76b 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -40,6 +40,7 @@
 #include <linux/slab.h>
 #include <linux/i2c-omap.h>
 #include <linux/pm_runtime.h>
+#include <linux/pm_qos_params.h>
 
 /* I2C controller revisions */
 #define OMAP_I2C_REV_2			0x20
@@ -179,8 +180,7 @@ struct omap_i2c_dev {
 	struct completion	cmd_complete;
 	struct resource		*ioarea;
 	u32			latency;	/* maximum mpu wkup latency */
-	void			(*set_mpu_wkup_lat)(struct device *dev,
-						    long latency);
+	struct pm_qos_request_list pm_qos_request;
 	u32			speed;		/* Speed of bus in Khz */
 	u16			cmd_err;
 	u8			*buf;
@@ -641,6 +641,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 	struct omap_i2c_dev *dev = i2c_get_adapdata(adap);
 	int i;
 	int r;
+	struct pm_qos_parameters pm_qos_params;
 
 	omap_i2c_unidle(dev);
 
@@ -648,8 +649,19 @@ 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.
+	 * Only OMAP3 has support for constraints
+	 */
+	if (cpu_is_omap34xx()) {
+		pm_qos_params.dev = dev->dev;
+		pm_qos_params.class = PM_QOS_CPU_DMA_LATENCY;
+		pm_qos_params.value = dev->latency;
+		pm_qos_add_request(&dev->pm_qos_request, &pm_qos_params);
+	}
 
 	for (i = 0; i < num; i++) {
 		r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)));
@@ -657,8 +669,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 (cpu_is_omap34xx())
+		pm_qos_remove_request(&dev->pm_qos_request);
 
 	if (r == 0)
 		r = num;
@@ -1007,13 +1019,10 @@ omap_i2c_probe(struct platform_device *pdev)
 		goto err_release_region;
 	}
 
-	if (pdata != NULL) {
+	if (pdata != NULL)
 		speed = pdata->clkrate;
-		dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
-	} else {
+	else
 		speed = 100;	/* Default speed */
-		dev->set_mpu_wkup_lat = NULL;
-	}
 
 	dev->speed = speed;
 	dev->idle = 1;
@@ -1066,8 +1075,8 @@ omap_i2c_probe(struct platform_device *pdev)
 			dev->fifo_size = (dev->fifo_size / 2);
 			dev->b_hw = 1; /* Enable hardware fixes */
 		}
-		/* calculate wakeup latency constraint for MPU */
-		if (dev->set_mpu_wkup_lat != NULL)
+		/* calculate device wakeup latency constraint */
+		if (cpu_is_omap34xx())
 			dev->latency = (1000000 * dev->fifo_size) /
 				       (1000 * speed / 8);
 	}
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 85d3048..5ca12e2 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -1086,6 +1086,7 @@ static int viacam_streamon(struct file *filp, void *priv, enum v4l2_buf_type t)
 {
 	struct via_camera *cam = priv;
 	int ret = 0;
+	struct pm_qos_parameters pm_qos_params;
 
 	if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
@@ -1120,7 +1121,9 @@ static int viacam_streamon(struct file *filp, void *priv, enum v4l2_buf_type t)
 	 * requirement which will keep the CPU out of the deeper sleep
 	 * states.
 	 */
-	pm_qos_add_request(&cam->qos_request, PM_QOS_CPU_DMA_LATENCY, 50);
+	pm_qos_params.class = PM_QOS_CPU_DMA_LATENCY;
+	pm_qos_params.value = 50;
+	pm_qos_add_request(&cam->qos_request, &pm_qos_params);
 	/*
 	 * Fire things up.
 	 */
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 3310c3d..c4cce8a 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -3604,6 +3604,7 @@ static int e1000_open(struct net_device *netdev)
 	struct e1000_hw *hw = &adapter->hw;
 	struct pci_dev *pdev = adapter->pdev;
 	int err;
+	struct pm_qos_parameters pm_qos_params;
 
 	/* disallow open during test */
 	if (test_bit(__E1000_TESTING, &adapter->state))
@@ -3641,10 +3642,12 @@ static int e1000_open(struct net_device *netdev)
 
 	/* DMA latency requirement to workaround early-receive/jumbo issue */
 	if ((adapter->flags & FLAG_HAS_ERT) ||
-	    (adapter->hw.mac.type == e1000_pch2lan))
+	    (adapter->hw.mac.type == e1000_pch2lan)) {
+		pm_qos_params.class = PM_QOS_CPU_DMA_LATENCY;
+		pm_qos_params.value = PM_QOS_DEFAULT_VALUE;
 		pm_qos_add_request(&adapter->netdev->pm_qos_req,
-				   PM_QOS_CPU_DMA_LATENCY,
-				   PM_QOS_DEFAULT_VALUE);
+				   &pm_qos_params);
+	}
 
 	/*
 	 * before we allocate an interrupt, we must be ready to handle it.
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 4430775..585ad04 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -6643,12 +6643,14 @@ static struct pci_driver ipw2100_pci_driver = {
 static int __init ipw2100_init(void)
 {
 	int ret;
+	struct pm_qos_parameters pm_qos_params;
 
 	printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
 	printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
 
-	pm_qos_add_request(&ipw2100_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
-			   PM_QOS_DEFAULT_VALUE);
+	pm_qos_params.class = PM_QOS_CPU_DMA_LATENCY;
+	pm_qos_params.value = PM_QOS_DEFAULT_VALUE;
+	pm_qos_add_request(&ipw2100_pm_qos_req, &pm_qos_params);
 
 	ret = pci_register_driver(&ipw2100_pci_driver);
 	if (ret)
diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
index a7d87f9..e6e16cb 100644
--- a/include/linux/pm_qos_params.h
+++ b/include/linux/pm_qos_params.h
@@ -8,31 +8,41 @@
 #include <linux/notifier.h>
 #include <linux/miscdevice.h>
 
-#define PM_QOS_RESERVED 0
-#define PM_QOS_CPU_DMA_LATENCY 1
-#define PM_QOS_NETWORK_LATENCY 2
-#define PM_QOS_NETWORK_THROUGHPUT 3
+#define	PM_QOS_RESERVED			0
+#define	PM_QOS_CPU_DMA_LATENCY		1
+#define	PM_QOS_DEV_WAKEUP_LATENCY	2
+#define	PM_QOS_NETWORK_LATENCY		3
+#define	PM_QOS_NETWORK_THROUGHPUT	4
 
-#define PM_QOS_NUM_CLASSES 4
-#define PM_QOS_DEFAULT_VALUE -1
+#define PM_QOS_NUM_CLASSES		5
+#define PM_QOS_DEFAULT_VALUE		-1
 
-#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
-#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
-#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE	0
+#define	PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
+#define	PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE	0
+#define	PM_QOS_NETWORK_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
+#define	PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE	0
 
 struct pm_qos_request_list {
 	struct plist_node list;
-	int pm_qos_class;
+	int class;
+	struct device *dev;
 };
 
-void pm_qos_add_request(struct pm_qos_request_list *l, int pm_qos_class, s32 value);
+struct pm_qos_parameters {
+	int class;
+	struct device *dev;
+	s32 value;
+};
+
+void pm_qos_add_request(struct pm_qos_request_list *l,
+			struct pm_qos_parameters *params);
 void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
-		s32 new_value);
+			   s32 new_value);
 void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
 
-int pm_qos_request(int pm_qos_class);
-int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
-int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
+int pm_qos_request(int class);
+int pm_qos_add_notifier(int class, struct notifier_block *notifier);
+int pm_qos_remove_notifier(int class, struct notifier_block *notifier);
 int pm_qos_request_active(struct pm_qos_request_list *req);
 
 #endif
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
index 6824ca7..d61c8e5 100644
--- a/kernel/pm_qos_params.c
+++ b/kernel/pm_qos_params.c
@@ -60,7 +60,7 @@ enum pm_qos_type {
  * types linux supports for 32 bit quantites
  */
 struct pm_qos_object {
-	struct plist_head requests;
+	struct plist_head *requests;
 	struct blocking_notifier_head *notifiers;
 	struct miscdevice pm_qos_power_miscdev;
 	char *name;
@@ -72,9 +72,12 @@ struct pm_qos_object {
 static DEFINE_SPINLOCK(pm_qos_lock);
 
 static struct pm_qos_object null_pm_qos;
+
 static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier);
+static struct plist_head _cpu_dma_reqs =
+			PLIST_HEAD_INIT(_cpu_dma_reqs, pm_qos_lock);
 static struct pm_qos_object cpu_dma_pm_qos = {
-	.requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock),
+	.requests = &_cpu_dma_reqs,
 	.notifiers = &cpu_dma_lat_notifier,
 	.name = "cpu_dma_latency",
 	.target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
@@ -82,9 +85,20 @@ static struct pm_qos_object cpu_dma_pm_qos = {
 	.type = PM_QOS_MIN,
 };
 
+static BLOCKING_NOTIFIER_HEAD(dev_wakeup_lat_notifier);
+static struct pm_qos_object dev_wakeup_lat_pm_qos = {
+	.notifiers = &dev_wakeup_lat_notifier,
+	.name = "dev_wakeup_latency",
+	.target_value = PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE,
+	.default_value = PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE,
+	.type = PM_QOS_MIN,
+};
+
 static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
+static struct plist_head _network_lat_reqs =
+			PLIST_HEAD_INIT(_network_lat_reqs, pm_qos_lock);
 static struct pm_qos_object network_lat_pm_qos = {
-	.requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock),
+	.requests = &_network_lat_reqs,
 	.notifiers = &network_lat_notifier,
 	.name = "network_latency",
 	.target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
@@ -94,8 +108,10 @@ static struct pm_qos_object network_lat_pm_qos = {
 
 
 static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier);
+static struct plist_head _network_throughput_reqs =
+			PLIST_HEAD_INIT(_network_throughput_reqs, pm_qos_lock);
 static struct pm_qos_object network_throughput_pm_qos = {
-	.requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock),
+	.requests = &_network_throughput_reqs,
 	.notifiers = &network_throughput_notifier,
 	.name = "network_throughput",
 	.target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
@@ -107,6 +123,7 @@ static struct pm_qos_object network_throughput_pm_qos = {
 static struct pm_qos_object *pm_qos_array[] = {
 	&null_pm_qos,
 	&cpu_dma_pm_qos,
+	&dev_wakeup_lat_pm_qos,
 	&network_lat_pm_qos,
 	&network_throughput_pm_qos
 };
@@ -129,19 +146,19 @@ static const struct file_operations pm_qos_power_fops = {
 /* unlocked internal variant */
 static inline int pm_qos_get_value(struct pm_qos_object *o)
 {
-	if (plist_head_empty(&o->requests))
+	if (plist_head_empty(o->requests))
 		return o->default_value;
 
 	switch (o->type) {
-	case PM_QOS_MIN:
-		return plist_first(&o->requests)->prio;
+		case PM_QOS_MIN:
+			return plist_first(o->requests)->prio;
 
-	case PM_QOS_MAX:
-		return plist_last(&o->requests)->prio;
+		case PM_QOS_MAX:
+			return plist_last(o->requests)->prio;
 
-	default:
-		/* runtime check for not using enum */
-		BUG();
+		default:
+			/* runtime check for not using enum */
+			BUG();
 	}
 }
 
@@ -155,13 +172,22 @@ static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value)
 	o->target_value = value;
 }
 
-static void update_target(struct pm_qos_object *o, struct plist_node *node,
-			  int del, int value)
+static void update_target(struct pm_qos_request_list *req, int del, int value)
 {
 	unsigned long flags;
 	int prev_value, curr_value;
+	struct pm_qos_object *o = pm_qos_array[req->class];
+	struct plist_node *node = &req->list;
 
 	spin_lock_irqsave(&pm_qos_lock, flags);
+	/*
+	 * PM_QOS_DEV_WAKEUP_LATENCY:
+	 * Use the per-device wake-up latency constraints list for
+	 * constraints storage
+	 */
+	if (req->class == PM_QOS_DEV_WAKEUP_LATENCY)
+		o->requests = &req->dev->power.wakeup_lat_plist_head;
+
 	prev_value = pm_qos_get_value(o);
 	/* PM_QOS_DEFAULT_VALUE is a signal that the value is unchanged */
 	if (value != PM_QOS_DEFAULT_VALUE) {
@@ -170,13 +196,13 @@ static void update_target(struct pm_qos_object *o, struct plist_node *node,
 		 * with new value and add, then see if the extremal
 		 * changed
 		 */
-		plist_del(node, &o->requests);
+		plist_del(node, o->requests);
 		plist_node_init(node, value);
-		plist_add(node, &o->requests);
+		plist_add(node, o->requests);
 	} else if (del) {
-		plist_del(node, &o->requests);
+		plist_del(node, o->requests);
 	} else {
-		plist_add(node, &o->requests);
+		plist_add(node, o->requests);
 	}
 	curr_value = pm_qos_get_value(o);
 	pm_qos_set_value(o, curr_value);
@@ -185,7 +211,7 @@ static void update_target(struct pm_qos_object *o, struct plist_node *node,
 	if (prev_value != curr_value)
 		blocking_notifier_call_chain(o->notifiers,
 					     (unsigned long)curr_value,
-					     NULL);
+					     req);
 }
 
 static int register_pm_qos_misc(struct pm_qos_object *qos)
@@ -199,65 +225,71 @@ static int register_pm_qos_misc(struct pm_qos_object *qos)
 
 static int find_pm_qos_object_by_minor(int minor)
 {
-	int pm_qos_class;
+	int class;
 
-	for (pm_qos_class = 0;
-		pm_qos_class < PM_QOS_NUM_CLASSES; pm_qos_class++) {
+	for (class = 0;
+		class < PM_QOS_NUM_CLASSES; class++) {
 		if (minor ==
-			pm_qos_array[pm_qos_class]->pm_qos_power_miscdev.minor)
-			return pm_qos_class;
+			pm_qos_array[class]->pm_qos_power_miscdev.minor)
+			return class;
 	}
 	return -1;
 }
 
 /**
  * pm_qos_request - returns current system wide qos expectation
- * @pm_qos_class: identification of which qos value is requested
+ * @class: identification of which qos value is requested
  *
  * This function returns the current target value.
  */
-int pm_qos_request(int pm_qos_class)
+int pm_qos_request(int class)
 {
-	return pm_qos_read_value(pm_qos_array[pm_qos_class]);
+	if (class == PM_QOS_DEV_WAKEUP_LATENCY)
+		return pm_qos_get_value(pm_qos_array[class]);
+	else
+		return pm_qos_read_value(pm_qos_array[class]);
 }
 EXPORT_SYMBOL_GPL(pm_qos_request);
 
 int pm_qos_request_active(struct pm_qos_request_list *req)
 {
-	return req->pm_qos_class != 0;
+	return req->class != 0;
 }
 EXPORT_SYMBOL_GPL(pm_qos_request_active);
 
 /**
  * pm_qos_add_request - inserts new qos request into the list
  * @dep: pointer to a preallocated handle
- * @pm_qos_class: identifies which list of qos request to use
- * @value: defines the qos request
+ * @params: request parameters
  *
- * This function inserts a new entry in the pm_qos_class list of requested qos
+ * This function inserts a new entry in the class list of requested qos
  * performance characteristics.  It recomputes the aggregate QoS expectations
- * for the pm_qos_class of parameters and initializes the pm_qos_request_list
- * handle.  Caller needs to save this handle for later use in updates and
+ * for the class of parameters and initializes the pm_qos_request_list
+ * handle. Caller needs to save this handle for later use in updates and
  * removal.
  */
 
-void pm_qos_add_request(struct pm_qos_request_list *dep,
-			int pm_qos_class, s32 value)
+void pm_qos_add_request(struct pm_qos_request_list *pm_qos_req,
+			struct pm_qos_parameters *pm_qos_params)
 {
-	struct pm_qos_object *o =  pm_qos_array[pm_qos_class];
+	struct pm_qos_object *o =  pm_qos_array[pm_qos_params->class];
 	int new_value;
 
-	if (pm_qos_request_active(dep)) {
-		WARN(1, KERN_ERR "pm_qos_add_request() called for already added request\n");
+	if ((pm_qos_params->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
+	    (pm_qos_request_active(pm_qos_req))) {
+		WARN(1, KERN_ERR "pm_qos_add_request() called for already "
+		     "added request\n");
 		return;
 	}
-	if (value == PM_QOS_DEFAULT_VALUE)
+
+	if (pm_qos_params->value == PM_QOS_DEFAULT_VALUE)
 		new_value = o->default_value;
 	else
-		new_value = value;
-	plist_node_init(&dep->list, new_value);
-	dep->pm_qos_class = pm_qos_class;
-	update_target(o, &dep->list, 0, PM_QOS_DEFAULT_VALUE);
+		new_value = pm_qos_params->value;
+	plist_node_init(&pm_qos_req->list, new_value);
+	pm_qos_req->class = pm_qos_params->class;
+	pm_qos_req->dev = pm_qos_params->dev;
+	update_target(pm_qos_req, 0, PM_QOS_DEFAULT_VALUE);
 }
 EXPORT_SYMBOL_GPL(pm_qos_add_request);
 
@@ -266,8 +298,8 @@ EXPORT_SYMBOL_GPL(pm_qos_add_request);
  * @pm_qos_req : handle to list element holding a pm_qos request to use
  * @value: defines the qos request
  *
- * Updates an existing qos request for the pm_qos_class of parameters along
- * with updating the target pm_qos_class value.
+ * Updates an existing qos request for the class of parameters along
+ * with updating the target class value.
  *
  * Attempts are made to make this code callable on hot code paths.
  */
@@ -275,25 +307,25 @@ void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
 			   s32 new_value)
 {
 	s32 temp;
-	struct pm_qos_object *o;
+	struct pm_qos_object *o = pm_qos_array[pm_qos_req->class];
 
 	if (!pm_qos_req) /*guard against callers passing in null */
 		return;
 
-	if (!pm_qos_request_active(pm_qos_req)) {
-		WARN(1, KERN_ERR "pm_qos_update_request() called for unknown object\n");
+	if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
+	    (!pm_qos_request_active(pm_qos_req))) {
+		WARN(1, KERN_ERR "pm_qos_update_request() called for unknown "
+		     "object\n");
 		return;
 	}
 
-	o = pm_qos_array[pm_qos_req->pm_qos_class];
-
 	if (new_value == PM_QOS_DEFAULT_VALUE)
 		temp = o->default_value;
 	else
 		temp = new_value;
 
 	if (temp != pm_qos_req->list.prio)
-		update_target(o, &pm_qos_req->list, 0, temp);
+		update_target(pm_qos_req, 0, temp);
 }
 EXPORT_SYMBOL_GPL(pm_qos_update_request);
 
@@ -302,42 +334,41 @@ EXPORT_SYMBOL_GPL(pm_qos_update_request);
  * @pm_qos_req: handle to request list element
  *
  * Will remove pm qos request from the list of requests and
- * recompute the current target value for the pm_qos_class.  Call this
+ * recompute the current target value for the class.  Call this
  * on slow code paths.
  */
 void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req)
 {
-	struct pm_qos_object *o;
-
 	if (pm_qos_req == NULL)
 		return;
 		/* silent return to keep pcm code cleaner */
 
-	if (!pm_qos_request_active(pm_qos_req)) {
-		WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown object\n");
+	if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
+	    (!pm_qos_request_active(pm_qos_req))) {
+		WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown "
+		     "object\n");
 		return;
 	}
 
-	o = pm_qos_array[pm_qos_req->pm_qos_class];
-	update_target(o, &pm_qos_req->list, 1, PM_QOS_DEFAULT_VALUE);
+	update_target(pm_qos_req, 1, PM_QOS_DEFAULT_VALUE);
 	memset(pm_qos_req, 0, sizeof(*pm_qos_req));
 }
 EXPORT_SYMBOL_GPL(pm_qos_remove_request);
 
 /**
  * pm_qos_add_notifier - sets notification entry for changes to target value
- * @pm_qos_class: identifies which qos target changes should be notified.
+ * @class: identifies which qos target changes should be notified.
  * @notifier: notifier block managed by caller.
  *
  * will register the notifier into a notification chain that gets called
- * upon changes to the pm_qos_class target value.
+ * upon changes to the class target value.
  */
-int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier)
+int pm_qos_add_notifier(int class, struct notifier_block *notifier)
 {
 	int retval;
 
 	retval = blocking_notifier_chain_register(
-			pm_qos_array[pm_qos_class]->notifiers, notifier);
+			pm_qos_array[class]->notifiers, notifier);
 
 	return retval;
 }
@@ -345,18 +376,18 @@ EXPORT_SYMBOL_GPL(pm_qos_add_notifier);
 
 /**
  * pm_qos_remove_notifier - deletes notification entry from chain.
- * @pm_qos_class: identifies which qos target changes are notified.
+ * @class: identifies which qos target changes are notified.
  * @notifier: notifier block to be removed.
  *
  * will remove the notifier from the notification chain that gets called
- * upon changes to the pm_qos_class target value.
+ * upon changes to the class target value.
  */
-int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier)
+int pm_qos_remove_notifier(int class, struct notifier_block *notifier)
 {
 	int retval;
 
 	retval = blocking_notifier_chain_unregister(
-			pm_qos_array[pm_qos_class]->notifiers, notifier);
+			pm_qos_array[class]->notifiers, notifier);
 
 	return retval;
 }
@@ -364,15 +395,17 @@ EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
 
 static int pm_qos_power_open(struct inode *inode, struct file *filp)
 {
-	long pm_qos_class;
+	struct pm_qos_parameters pm_qos_params;
 
-	pm_qos_class = find_pm_qos_object_by_minor(iminor(inode));
-	if (pm_qos_class >= 0) {
-               struct pm_qos_request_list *req = kzalloc(sizeof(*req), GFP_KERNEL);
+	pm_qos_params.class = find_pm_qos_object_by_minor(iminor(inode));
+	if (pm_qos_params.class >= 0) {
+		struct pm_qos_request_list *req = kzalloc(sizeof(*req),
+							  GFP_KERNEL);
 		if (!req)
 			return -ENOMEM;
 
-		pm_qos_add_request(req, pm_qos_class, PM_QOS_DEFAULT_VALUE);
+		pm_qos_params.value = PM_QOS_DEFAULT_VALUE;
+		pm_qos_add_request(req, &pm_qos_params);
 		filp->private_data = req;
 
 		if (filp->private_data)
@@ -406,7 +439,7 @@ static ssize_t pm_qos_power_read(struct file *filp, char __user *buf,
 	if (!pm_qos_request_active(pm_qos_req))
 		return -EINVAL;
 
-	o = pm_qos_array[pm_qos_req->pm_qos_class];
+	o = pm_qos_array[pm_qos_req->class];
 	spin_lock_irqsave(&pm_qos_lock, flags);
 	value = pm_qos_get_value(o);
 	spin_unlock_irqrestore(&pm_qos_lock, flags);
@@ -462,18 +495,20 @@ static int __init pm_qos_power_init(void)
 
 	ret = register_pm_qos_misc(&cpu_dma_pm_qos);
 	if (ret < 0) {
-		printk(KERN_ERR "pm_qos_param: cpu_dma_latency setup failed\n");
+		printk(KERN_ERR
+		       "pm_qos_param: cpu_dma_latency setup failed\n");
 		return ret;
 	}
 	ret = register_pm_qos_misc(&network_lat_pm_qos);
 	if (ret < 0) {
-		printk(KERN_ERR "pm_qos_param: network_latency setup failed\n");
+		printk(KERN_ERR
+		       "pm_qos_param: network_latency setup failed\n");
 		return ret;
 	}
 	ret = register_pm_qos_misc(&network_throughput_pm_qos);
 	if (ret < 0)
 		printk(KERN_ERR
-			"pm_qos_param: network_throughput setup failed\n");
+		       "pm_qos_param: network_throughput setup failed\n");
 
 	return ret;
 }
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 1c6be91..a19605c 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -375,6 +375,7 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
 	int err, usecs;
 	unsigned int bits;
 	snd_pcm_uframes_t frames;
+	struct pm_qos_parameters pm_qos_params;
 
 	if (PCM_RUNTIME_CHECK(substream))
 		return -ENXIO;
@@ -455,9 +456,12 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
 
 	if (pm_qos_request_active(&substream->latency_pm_qos_req))
 		pm_qos_remove_request(&substream->latency_pm_qos_req);
-	if ((usecs = period_to_usecs(runtime)) >= 0)
+	if ((usecs = period_to_usecs(runtime)) >= 0) {
+		pm_qos_params.class = PM_QOS_CPU_DMA_LATENCY;
+		pm_qos_params.value = usecs;
 		pm_qos_add_request(&substream->latency_pm_qos_req,
-				   PM_QOS_CPU_DMA_LATENCY, usecs);
+				   &pm_qos_params);
+	}
 	return 0;
  _error:
 	/* hardware might be unusable from this time,
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 03/11] PM QoS: support the dynamic devices insertion and removal
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (4 preceding siblings ...)
  2011-06-30 15:11 ` [PATCH 03/11] PM QoS: support the dynamic devices insertion and removal jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` [PATCH 04/11] OMAP PM: create a PM layer plugin for per-device constraints jean.pihet
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

The devices wake-up latency constraints class of PM QoS is
storing the constraints list using the device pm_info struct.

This patch adds the init and de-init of the per-device constraints
list in order to support the dynamic insertion and removal
of the devices in the system.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 drivers/base/power/main.c     |    8 +++--
 include/linux/pm.h            |    1 +
 include/linux/pm_qos_params.h |    2 +
 kernel/pm_qos_params.c        |   70 ++++++++++++++++++++++++++++++++--------
 4 files changed, 64 insertions(+), 17 deletions(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index b1fd96b..51f5526 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -27,6 +27,7 @@
 #include <linux/sched.h>
 #include <linux/async.h>
 #include <linux/suspend.h>
+#include <linux/pm_qos_params.h>
 
 #include "../base.h"
 #include "power.h"
@@ -96,8 +97,8 @@ void device_pm_add(struct device *dev)
 			dev_name(dev->parent));
 	list_add_tail(&dev->power.entry, &dpm_list);
 	mutex_unlock(&dpm_list_mtx);
-	/* ToDo: call PM QoS to init the per-device wakeup latency constraints */
-	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
+	/* Call PM QoS to init the per-device wakeup latency constraints */
+	pm_qos_dev_wakeup_lat_init(dev);
 }
 
 /**
@@ -108,7 +109,8 @@ void device_pm_remove(struct device *dev)
 {
 	pr_debug("PM: Removing info for %s:%s\n",
 		 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
-	/* ToDo: call PM QoS to de-init the per-device wakeup latency constraints */
+	/* Call PM QoS to de-init the per-device wakeup latency constraints */
+	pm_qos_dev_wakeup_lat_deinit(dev);
 	complete_all(&dev->power.completion);
 	mutex_lock(&dpm_list_mtx);
 	list_del_init(&dev->power.entry);
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 35fe682..d9b6092 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -464,6 +464,7 @@ struct dev_pm_info {
 	void			*subsys_data;  /* Owned by the subsystem. */
 #endif
 	struct plist_head	wakeup_lat_plist_head;
+	int			wakeup_lat_init;
 };
 
 extern void update_pm_runtime_accounting(struct device *dev);
diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
index e6e16cb..5b6707a 100644
--- a/include/linux/pm_qos_params.h
+++ b/include/linux/pm_qos_params.h
@@ -45,4 +45,6 @@ int pm_qos_add_notifier(int class, struct notifier_block *notifier);
 int pm_qos_remove_notifier(int class, struct notifier_block *notifier);
 int pm_qos_request_active(struct pm_qos_request_list *req);
 
+void pm_qos_dev_wakeup_lat_init(struct device *dev);
+void pm_qos_dev_wakeup_lat_deinit(struct device *dev);
 #endif
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
index d61c8e5..6f25ccb 100644
--- a/kernel/pm_qos_params.c
+++ b/kernel/pm_qos_params.c
@@ -275,11 +275,21 @@ void pm_qos_add_request(struct pm_qos_request_list *pm_qos_req,
 	struct pm_qos_object *o =  pm_qos_array[pm_qos_params->class];
 	int new_value;
 
-	if ((pm_qos_params->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
-	    (pm_qos_request_active(pm_qos_req))) {
-		WARN(1, KERN_ERR "pm_qos_add_request() called for already "
-		     "added request\n");
-		return;
+	if (pm_qos_params->class == PM_QOS_DEV_WAKEUP_LATENCY) {
+		if (!pm_qos_params->dev) {
+			WARN(1, KERN_ERR "pm_qos_add_request() called for "
+				"invalid device\n");
+			return;
+		}
+		/* Silently return if the device is being released */
+		if (!pm_qos_params->dev->power.wakeup_lat_init)
+			return;
+	} else {
+		if (pm_qos_request_active(pm_qos_req)) {
+			WARN(1, KERN_ERR "pm_qos_add_request() called for "
+				"already added request\n");
+			return;
+		}
 	}
 
 	if (pm_qos_params->value == PM_QOS_DEFAULT_VALUE)
@@ -312,11 +322,16 @@ void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
 	if (!pm_qos_req) /*guard against callers passing in null */
 		return;
 
-	if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
-	    (!pm_qos_request_active(pm_qos_req))) {
-		WARN(1, KERN_ERR "pm_qos_update_request() called for unknown "
-		     "object\n");
-		return;
+	if (pm_qos_req->class == PM_QOS_DEV_WAKEUP_LATENCY) {
+		/* Silently return if the device is being released */
+		if (!pm_qos_req->dev->power.wakeup_lat_init)
+			return;
+	} else {
+		if (!pm_qos_request_active(pm_qos_req)) {
+			WARN(1, KERN_ERR "pm_qos_update_request() called "
+				"for unknown object\n");
+			return;
+		}
 	}
 
 	if (new_value == PM_QOS_DEFAULT_VALUE)
@@ -343,11 +358,16 @@ void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req)
 		return;
 		/* silent return to keep pcm code cleaner */
 
-	if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
-	    (!pm_qos_request_active(pm_qos_req))) {
-		WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown "
-		     "object\n");
+	if (pm_qos_req->class == PM_QOS_DEV_WAKEUP_LATENCY) {
+		/* Silently return if the device is being released */
+		if (!pm_qos_req->dev->power.wakeup_lat_init)
+			return;
+	} else {
+		if (!pm_qos_request_active(pm_qos_req)) {
+			WARN(1, KERN_ERR "pm_qos_remove_request() called "
+				"for unknown object\n");
 		return;
+		}
 	}
 
 	update_target(pm_qos_req, 1, PM_QOS_DEFAULT_VALUE);
@@ -393,6 +413,28 @@ int pm_qos_remove_notifier(int class, struct notifier_block *notifier)
 }
 EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
 
+/* Called from the device PM subsystem at device init */
+void pm_qos_dev_wakeup_lat_init(struct device *dev)
+{
+	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
+	dev->power.wakeup_lat_init = 1;
+}
+
+/* Called from the device PM subsystem at device release */
+void pm_qos_dev_wakeup_lat_deinit(struct device *dev)
+{
+	struct pm_qos_request_list *req, *tmp;
+
+	dev->power.wakeup_lat_init = 0;
+
+	/* Flush the constraints list for the device */
+	plist_for_each_entry_safe(req, tmp,
+				  &dev->power.wakeup_lat_plist_head,
+				  list)
+		update_target(req, 1, PM_QOS_DEFAULT_VALUE);
+	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
+}
+
 static int pm_qos_power_open(struct inode *inode, struct file *filp)
 {
 	struct pm_qos_parameters pm_qos_params;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 03/11] PM QoS: support the dynamic devices insertion and removal
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (3 preceding siblings ...)
  2011-06-30 15:11 ` jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-07-02 21:14   ` Rafael J. Wysocki
  2011-07-02 21:14   ` Rafael J. Wysocki
  2011-06-30 15:11 ` jean.pihet
                   ` (18 subsequent siblings)
  23 siblings, 2 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

The devices wake-up latency constraints class of PM QoS is
storing the constraints list using the device pm_info struct.

This patch adds the init and de-init of the per-device constraints
list in order to support the dynamic insertion and removal
of the devices in the system.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 drivers/base/power/main.c     |    8 +++--
 include/linux/pm.h            |    1 +
 include/linux/pm_qos_params.h |    2 +
 kernel/pm_qos_params.c        |   70 ++++++++++++++++++++++++++++++++--------
 4 files changed, 64 insertions(+), 17 deletions(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index b1fd96b..51f5526 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -27,6 +27,7 @@
 #include <linux/sched.h>
 #include <linux/async.h>
 #include <linux/suspend.h>
+#include <linux/pm_qos_params.h>
 
 #include "../base.h"
 #include "power.h"
@@ -96,8 +97,8 @@ void device_pm_add(struct device *dev)
 			dev_name(dev->parent));
 	list_add_tail(&dev->power.entry, &dpm_list);
 	mutex_unlock(&dpm_list_mtx);
-	/* ToDo: call PM QoS to init the per-device wakeup latency constraints */
-	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
+	/* Call PM QoS to init the per-device wakeup latency constraints */
+	pm_qos_dev_wakeup_lat_init(dev);
 }
 
 /**
@@ -108,7 +109,8 @@ void device_pm_remove(struct device *dev)
 {
 	pr_debug("PM: Removing info for %s:%s\n",
 		 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
-	/* ToDo: call PM QoS to de-init the per-device wakeup latency constraints */
+	/* Call PM QoS to de-init the per-device wakeup latency constraints */
+	pm_qos_dev_wakeup_lat_deinit(dev);
 	complete_all(&dev->power.completion);
 	mutex_lock(&dpm_list_mtx);
 	list_del_init(&dev->power.entry);
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 35fe682..d9b6092 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -464,6 +464,7 @@ struct dev_pm_info {
 	void			*subsys_data;  /* Owned by the subsystem. */
 #endif
 	struct plist_head	wakeup_lat_plist_head;
+	int			wakeup_lat_init;
 };
 
 extern void update_pm_runtime_accounting(struct device *dev);
diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
index e6e16cb..5b6707a 100644
--- a/include/linux/pm_qos_params.h
+++ b/include/linux/pm_qos_params.h
@@ -45,4 +45,6 @@ int pm_qos_add_notifier(int class, struct notifier_block *notifier);
 int pm_qos_remove_notifier(int class, struct notifier_block *notifier);
 int pm_qos_request_active(struct pm_qos_request_list *req);
 
+void pm_qos_dev_wakeup_lat_init(struct device *dev);
+void pm_qos_dev_wakeup_lat_deinit(struct device *dev);
 #endif
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
index d61c8e5..6f25ccb 100644
--- a/kernel/pm_qos_params.c
+++ b/kernel/pm_qos_params.c
@@ -275,11 +275,21 @@ void pm_qos_add_request(struct pm_qos_request_list *pm_qos_req,
 	struct pm_qos_object *o =  pm_qos_array[pm_qos_params->class];
 	int new_value;
 
-	if ((pm_qos_params->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
-	    (pm_qos_request_active(pm_qos_req))) {
-		WARN(1, KERN_ERR "pm_qos_add_request() called for already "
-		     "added request\n");
-		return;
+	if (pm_qos_params->class == PM_QOS_DEV_WAKEUP_LATENCY) {
+		if (!pm_qos_params->dev) {
+			WARN(1, KERN_ERR "pm_qos_add_request() called for "
+				"invalid device\n");
+			return;
+		}
+		/* Silently return if the device is being released */
+		if (!pm_qos_params->dev->power.wakeup_lat_init)
+			return;
+	} else {
+		if (pm_qos_request_active(pm_qos_req)) {
+			WARN(1, KERN_ERR "pm_qos_add_request() called for "
+				"already added request\n");
+			return;
+		}
 	}
 
 	if (pm_qos_params->value == PM_QOS_DEFAULT_VALUE)
@@ -312,11 +322,16 @@ void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
 	if (!pm_qos_req) /*guard against callers passing in null */
 		return;
 
-	if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
-	    (!pm_qos_request_active(pm_qos_req))) {
-		WARN(1, KERN_ERR "pm_qos_update_request() called for unknown "
-		     "object\n");
-		return;
+	if (pm_qos_req->class == PM_QOS_DEV_WAKEUP_LATENCY) {
+		/* Silently return if the device is being released */
+		if (!pm_qos_req->dev->power.wakeup_lat_init)
+			return;
+	} else {
+		if (!pm_qos_request_active(pm_qos_req)) {
+			WARN(1, KERN_ERR "pm_qos_update_request() called "
+				"for unknown object\n");
+			return;
+		}
 	}
 
 	if (new_value == PM_QOS_DEFAULT_VALUE)
@@ -343,11 +358,16 @@ void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req)
 		return;
 		/* silent return to keep pcm code cleaner */
 
-	if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
-	    (!pm_qos_request_active(pm_qos_req))) {
-		WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown "
-		     "object\n");
+	if (pm_qos_req->class == PM_QOS_DEV_WAKEUP_LATENCY) {
+		/* Silently return if the device is being released */
+		if (!pm_qos_req->dev->power.wakeup_lat_init)
+			return;
+	} else {
+		if (!pm_qos_request_active(pm_qos_req)) {
+			WARN(1, KERN_ERR "pm_qos_remove_request() called "
+				"for unknown object\n");
 		return;
+		}
 	}
 
 	update_target(pm_qos_req, 1, PM_QOS_DEFAULT_VALUE);
@@ -393,6 +413,28 @@ int pm_qos_remove_notifier(int class, struct notifier_block *notifier)
 }
 EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
 
+/* Called from the device PM subsystem at device init */
+void pm_qos_dev_wakeup_lat_init(struct device *dev)
+{
+	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
+	dev->power.wakeup_lat_init = 1;
+}
+
+/* Called from the device PM subsystem at device release */
+void pm_qos_dev_wakeup_lat_deinit(struct device *dev)
+{
+	struct pm_qos_request_list *req, *tmp;
+
+	dev->power.wakeup_lat_init = 0;
+
+	/* Flush the constraints list for the device */
+	plist_for_each_entry_safe(req, tmp,
+				  &dev->power.wakeup_lat_plist_head,
+				  list)
+		update_target(req, 1, PM_QOS_DEFAULT_VALUE);
+	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
+}
+
 static int pm_qos_power_open(struct inode *inode, struct file *filp)
 {
 	struct pm_qos_parameters pm_qos_params;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 04/11] OMAP PM: create a PM layer plugin for per-device constraints
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (5 preceding siblings ...)
  2011-06-30 15:11 ` jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` jean.pihet
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

Created arch/arm/plat-omap/omap-pm-constraints.c file from
arch/arm/plat-omap/omap-pm-noop.c and the associated Kconfig option
OMAP_PM_CONSTRAINTS.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/plat-omap/Kconfig               |    7 +
 arch/arm/plat-omap/Makefile              |    1 +
 arch/arm/plat-omap/omap-pm-constraints.c |  363 ++++++++++++++++++++++++++++++
 3 files changed, 371 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-omap/omap-pm-constraints.c

diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 49a4c75..725d942 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -217,6 +217,13 @@ config OMAP_PM_NONE
 config OMAP_PM_NOOP
 	bool "No-op/debug PM layer"
 
+config OMAP_PM_CONSTRAINTS
+	depends on PM
+	bool "Per device constraints"
+	help
+	  Select this option to enable the PM layer plugin for
+	  the per-device constraints support
+
 endchoice
 
 endmenu
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index f0233e6..f2e09f1 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -32,3 +32,4 @@ obj-y += $(i2c-omap-m) $(i2c-omap-y)
 obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
 
 obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
+obj-$(CONFIG_OMAP_PM_CONSTRAINTS) += omap-pm-constraints.o
diff --git a/arch/arm/plat-omap/omap-pm-constraints.c b/arch/arm/plat-omap/omap-pm-constraints.c
new file mode 100644
index 0000000..c8b4e4c
--- /dev/null
+++ b/arch/arm/plat-omap/omap-pm-constraints.c
@@ -0,0 +1,363 @@
+/*
+ * omap-pm.c - OMAP power management interface
+ *
+ * This code implements the OMAP power management interface to
+ * drivers, CPUIdle, CPUFreq, and DSP Bridge.
+ *
+ * Copyright (C) 2008-2009 Texas Instruments, Inc.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Interface developed by (in alphabetical order):
+ * Karthik Dasu, Tony Lindgren, Jean Pihet, Rajendra Nayak, Sakari Poussa,
+ * Veeramanikandan Raju, Anand Sawant, Igor Stoppa, Paul Walmsley,
+ * Richard Woodruff
+ */
+
+#undef DEBUG
+
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
+/* Interface documentation is in mach/omap-pm.h */
+#include <plat/omap-pm.h>
+#include <plat/omap_device.h>
+
+static bool off_mode_enabled;
+static u32 dummy_context_loss_counter;
+
+/*
+ * Device-driver-originated constraints (via board-*.c files)
+ */
+
+int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
+{
+	if (!dev || t < -1) {
+		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+		return -EINVAL;
+	};
+
+	if (t == -1)
+		pr_debug("OMAP PM: remove max MPU wakeup latency constraint: "
+			 "dev %s\n", dev_name(dev));
+	else
+		pr_debug("OMAP PM: add max MPU wakeup latency constraint: "
+			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+	/*
+	 * For current Linux, this needs to map the MPU to a
+	 * powerdomain, then go through the list of current max lat
+	 * constraints on the MPU and find the smallest.  If
+	 * the latency constraint has changed, the code should
+	 * recompute the state to enter for the next powerdomain
+	 * state.
+	 *
+	 * TI CDP code can call constraint_set here.
+	 */
+
+	return 0;
+}
+
+int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
+{
+	if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
+	    agent_id != OCP_TARGET_AGENT)) {
+		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+		return -EINVAL;
+	};
+
+	if (r == 0)
+		pr_debug("OMAP PM: remove min bus tput constraint: "
+			 "dev %s for agent_id %d\n", dev_name(dev), agent_id);
+	else
+		pr_debug("OMAP PM: add min bus tput constraint: "
+			 "dev %s for agent_id %d: rate %ld KiB\n",
+			 dev_name(dev), agent_id, r);
+
+	/*
+	 * This code should model the interconnect and compute the
+	 * required clock frequency, convert that to a VDD2 OPP ID, then
+	 * set the VDD2 OPP appropriately.
+	 *
+	 * TI CDP code can call constraint_set here on the VDD2 OPP.
+	 */
+
+	return 0;
+}
+
+int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
+				   long t)
+{
+	if (!req_dev || !dev || t < -1) {
+		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+		return -EINVAL;
+	};
+
+	if (t == -1)
+		pr_debug("OMAP PM: remove max device latency constraint: "
+			 "dev %s\n", dev_name(dev));
+	else
+		pr_debug("OMAP PM: add max device latency constraint: "
+			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+	/*
+	 * For current Linux, this needs to map the device to a
+	 * powerdomain, then go through the list of current max lat
+	 * constraints on that powerdomain and find the smallest.  If
+	 * the latency constraint has changed, the code should
+	 * recompute the state to enter for the next powerdomain
+	 * state.  Conceivably, this code should also determine
+	 * whether to actually disable the device clocks or not,
+	 * depending on how long it takes to re-enable the clocks.
+	 *
+	 * TI CDP code can call constraint_set here.
+	 */
+
+	return 0;
+}
+
+int omap_pm_set_max_sdma_lat(struct device *dev, long t)
+{
+	if (!dev || t < -1) {
+		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+		return -EINVAL;
+	};
+
+	if (t == -1)
+		pr_debug("OMAP PM: remove max DMA latency constraint: "
+			 "dev %s\n", dev_name(dev));
+	else
+		pr_debug("OMAP PM: add max DMA latency constraint: "
+			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+	/*
+	 * For current Linux PM QOS params, this code should scan the
+	 * list of maximum CPU and DMA latencies and select the
+	 * smallest, then set cpu_dma_latency pm_qos_param
+	 * accordingly.
+	 *
+	 * For future Linux PM QOS params, with separate CPU and DMA
+	 * latency params, this code should just set the dma_latency param.
+	 *
+	 * TI CDP code can call constraint_set here.
+	 */
+
+	return 0;
+}
+
+int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
+{
+	if (!dev || !c || r < 0) {
+		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+		return -EINVAL;
+	}
+
+	if (r == 0)
+		pr_debug("OMAP PM: remove min clk rate constraint: "
+			 "dev %s\n", dev_name(dev));
+	else
+		pr_debug("OMAP PM: add min clk rate constraint: "
+			 "dev %s, rate = %ld Hz\n", dev_name(dev), r);
+
+	/*
+	 * Code in a real implementation should keep track of these
+	 * constraints on the clock, and determine the highest minimum
+	 * clock rate.  It should iterate over each OPP and determine
+	 * whether the OPP will result in a clock rate that would
+	 * satisfy this constraint (and any other PM constraint in effect
+	 * at that time).  Once it finds the lowest-voltage OPP that
+	 * meets those conditions, it should switch to it, or return
+	 * an error if the code is not capable of doing so.
+	 */
+
+	return 0;
+}
+
+/*
+ * DSP Bridge-specific constraints
+ */
+
+const struct omap_opp *omap_pm_dsp_get_opp_table(void)
+{
+	pr_debug("OMAP PM: DSP request for OPP table\n");
+
+	/*
+	 * Return DSP frequency table here:  The final item in the
+	 * array should have .rate = .opp_id = 0.
+	 */
+
+	return NULL;
+}
+
+void omap_pm_dsp_set_min_opp(u8 opp_id)
+{
+	if (opp_id == 0) {
+		WARN_ON(1);
+		return;
+	}
+
+	pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id);
+
+	/*
+	 *
+	 * For l-o dev tree, our VDD1 clk is keyed on OPP ID, so we
+	 * can just test to see which is higher, the CPU's desired OPP
+	 * ID or the DSP's desired OPP ID, and use whichever is
+	 * highest.
+	 *
+	 * In CDP12.14+, the VDD1 OPP custom clock that controls the DSP
+	 * rate is keyed on MPU speed, not the OPP ID.  So we need to
+	 * map the OPP ID to the MPU speed for use with clk_set_rate()
+	 * if it is higher than the current OPP clock rate.
+	 *
+	 */
+}
+
+
+u8 omap_pm_dsp_get_opp(void)
+{
+	pr_debug("OMAP PM: DSP requests current DSP OPP ID\n");
+
+	/*
+	 * For l-o dev tree, call clk_get_rate() on VDD1 OPP clock
+	 *
+	 * CDP12.14+:
+	 * Call clk_get_rate() on the OPP custom clock, map that to an
+	 * OPP ID using the tables defined in board-*.c/chip-*.c files.
+	 */
+
+	return 0;
+}
+
+/*
+ * CPUFreq-originated constraint
+ *
+ * In the future, this should be handled by custom OPP clocktype
+ * functions.
+ */
+
+struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void)
+{
+	pr_debug("OMAP PM: CPUFreq request for frequency table\n");
+
+	/*
+	 * Return CPUFreq frequency table here: loop over
+	 * all VDD1 clkrates, pull out the mpu_ck frequencies, build
+	 * table
+	 */
+
+	return NULL;
+}
+
+void omap_pm_cpu_set_freq(unsigned long f)
+{
+	if (f == 0) {
+		WARN_ON(1);
+		return;
+	}
+
+	pr_debug("OMAP PM: CPUFreq requests CPU frequency to be set to %lu\n",
+		 f);
+
+	/*
+	 * For l-o dev tree, determine whether MPU freq or DSP OPP id
+	 * freq is higher.  Find the OPP ID corresponding to the
+	 * higher frequency.  Call clk_round_rate() and clk_set_rate()
+	 * on the OPP custom clock.
+	 *
+	 * CDP should just be able to set the VDD1 OPP clock rate here.
+	 */
+}
+
+unsigned long omap_pm_cpu_get_freq(void)
+{
+	pr_debug("OMAP PM: CPUFreq requests current CPU frequency\n");
+
+	/*
+	 * Call clk_get_rate() on the mpu_ck.
+	 */
+
+	return 0;
+}
+
+/**
+ * omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled
+ *
+ * Intended for use only by OMAP PM core code to notify this layer
+ * that off mode has been enabled.
+ */
+void omap_pm_enable_off_mode(void)
+{
+	off_mode_enabled = true;
+}
+
+/**
+ * omap_pm_disable_off_mode - notify OMAP PM that off-mode is disabled
+ *
+ * Intended for use only by OMAP PM core code to notify this layer
+ * that off mode has been disabled.
+ */
+void omap_pm_disable_off_mode(void)
+{
+	off_mode_enabled = false;
+}
+
+/*
+ * Device context loss tracking
+ */
+
+#ifdef CONFIG_ARCH_OMAP2PLUS
+
+u32 omap_pm_get_dev_context_loss_count(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	u32 count;
+
+	if (WARN_ON(!dev))
+		return 0;
+
+	if (dev->parent == &omap_device_parent) {
+		count = omap_device_get_context_loss_count(pdev);
+	} else {
+		WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context "
+			  "loss counter; device %s should be converted to "
+			  "omap_device", dev_name(dev));
+		if (off_mode_enabled)
+			dummy_context_loss_counter++;
+		count = dummy_context_loss_counter;
+	}
+
+	pr_debug("OMAP PM: context loss count for dev %s = %d\n",
+		 dev_name(dev), count);
+
+	return count;
+}
+
+#else
+
+u32 omap_pm_get_dev_context_loss_count(struct device *dev)
+{
+	return dummy_context_loss_counter;
+}
+
+#endif
+
+/* Should be called before clk framework init */
+int __init omap_pm_if_early_init(void)
+{
+	return 0;
+}
+
+/* Must be called after clock framework is initialized */
+int __init omap_pm_if_init(void)
+{
+	return 0;
+}
+
+void omap_pm_if_exit(void)
+{
+	/* Deallocate CPUFreq frequency table here */
+}
+
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 04/11] OMAP PM: create a PM layer plugin for per-device constraints
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (6 preceding siblings ...)
  2011-06-30 15:11 ` [PATCH 04/11] OMAP PM: create a PM layer plugin for per-device constraints jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` [PATCH 05/11] OMAP PM: early init of the pwrdms states jean.pihet
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

Created arch/arm/plat-omap/omap-pm-constraints.c file from
arch/arm/plat-omap/omap-pm-noop.c and the associated Kconfig option
OMAP_PM_CONSTRAINTS.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/plat-omap/Kconfig               |    7 +
 arch/arm/plat-omap/Makefile              |    1 +
 arch/arm/plat-omap/omap-pm-constraints.c |  363 ++++++++++++++++++++++++++++++
 3 files changed, 371 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-omap/omap-pm-constraints.c

diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 49a4c75..725d942 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -217,6 +217,13 @@ config OMAP_PM_NONE
 config OMAP_PM_NOOP
 	bool "No-op/debug PM layer"
 
+config OMAP_PM_CONSTRAINTS
+	depends on PM
+	bool "Per device constraints"
+	help
+	  Select this option to enable the PM layer plugin for
+	  the per-device constraints support
+
 endchoice
 
 endmenu
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index f0233e6..f2e09f1 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -32,3 +32,4 @@ obj-y += $(i2c-omap-m) $(i2c-omap-y)
 obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
 
 obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
+obj-$(CONFIG_OMAP_PM_CONSTRAINTS) += omap-pm-constraints.o
diff --git a/arch/arm/plat-omap/omap-pm-constraints.c b/arch/arm/plat-omap/omap-pm-constraints.c
new file mode 100644
index 0000000..c8b4e4c
--- /dev/null
+++ b/arch/arm/plat-omap/omap-pm-constraints.c
@@ -0,0 +1,363 @@
+/*
+ * omap-pm.c - OMAP power management interface
+ *
+ * This code implements the OMAP power management interface to
+ * drivers, CPUIdle, CPUFreq, and DSP Bridge.
+ *
+ * Copyright (C) 2008-2009 Texas Instruments, Inc.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Interface developed by (in alphabetical order):
+ * Karthik Dasu, Tony Lindgren, Jean Pihet, Rajendra Nayak, Sakari Poussa,
+ * Veeramanikandan Raju, Anand Sawant, Igor Stoppa, Paul Walmsley,
+ * Richard Woodruff
+ */
+
+#undef DEBUG
+
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
+/* Interface documentation is in mach/omap-pm.h */
+#include <plat/omap-pm.h>
+#include <plat/omap_device.h>
+
+static bool off_mode_enabled;
+static u32 dummy_context_loss_counter;
+
+/*
+ * Device-driver-originated constraints (via board-*.c files)
+ */
+
+int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
+{
+	if (!dev || t < -1) {
+		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+		return -EINVAL;
+	};
+
+	if (t == -1)
+		pr_debug("OMAP PM: remove max MPU wakeup latency constraint: "
+			 "dev %s\n", dev_name(dev));
+	else
+		pr_debug("OMAP PM: add max MPU wakeup latency constraint: "
+			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+	/*
+	 * For current Linux, this needs to map the MPU to a
+	 * powerdomain, then go through the list of current max lat
+	 * constraints on the MPU and find the smallest.  If
+	 * the latency constraint has changed, the code should
+	 * recompute the state to enter for the next powerdomain
+	 * state.
+	 *
+	 * TI CDP code can call constraint_set here.
+	 */
+
+	return 0;
+}
+
+int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
+{
+	if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
+	    agent_id != OCP_TARGET_AGENT)) {
+		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+		return -EINVAL;
+	};
+
+	if (r == 0)
+		pr_debug("OMAP PM: remove min bus tput constraint: "
+			 "dev %s for agent_id %d\n", dev_name(dev), agent_id);
+	else
+		pr_debug("OMAP PM: add min bus tput constraint: "
+			 "dev %s for agent_id %d: rate %ld KiB\n",
+			 dev_name(dev), agent_id, r);
+
+	/*
+	 * This code should model the interconnect and compute the
+	 * required clock frequency, convert that to a VDD2 OPP ID, then
+	 * set the VDD2 OPP appropriately.
+	 *
+	 * TI CDP code can call constraint_set here on the VDD2 OPP.
+	 */
+
+	return 0;
+}
+
+int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
+				   long t)
+{
+	if (!req_dev || !dev || t < -1) {
+		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+		return -EINVAL;
+	};
+
+	if (t == -1)
+		pr_debug("OMAP PM: remove max device latency constraint: "
+			 "dev %s\n", dev_name(dev));
+	else
+		pr_debug("OMAP PM: add max device latency constraint: "
+			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+	/*
+	 * For current Linux, this needs to map the device to a
+	 * powerdomain, then go through the list of current max lat
+	 * constraints on that powerdomain and find the smallest.  If
+	 * the latency constraint has changed, the code should
+	 * recompute the state to enter for the next powerdomain
+	 * state.  Conceivably, this code should also determine
+	 * whether to actually disable the device clocks or not,
+	 * depending on how long it takes to re-enable the clocks.
+	 *
+	 * TI CDP code can call constraint_set here.
+	 */
+
+	return 0;
+}
+
+int omap_pm_set_max_sdma_lat(struct device *dev, long t)
+{
+	if (!dev || t < -1) {
+		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+		return -EINVAL;
+	};
+
+	if (t == -1)
+		pr_debug("OMAP PM: remove max DMA latency constraint: "
+			 "dev %s\n", dev_name(dev));
+	else
+		pr_debug("OMAP PM: add max DMA latency constraint: "
+			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+	/*
+	 * For current Linux PM QOS params, this code should scan the
+	 * list of maximum CPU and DMA latencies and select the
+	 * smallest, then set cpu_dma_latency pm_qos_param
+	 * accordingly.
+	 *
+	 * For future Linux PM QOS params, with separate CPU and DMA
+	 * latency params, this code should just set the dma_latency param.
+	 *
+	 * TI CDP code can call constraint_set here.
+	 */
+
+	return 0;
+}
+
+int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
+{
+	if (!dev || !c || r < 0) {
+		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+		return -EINVAL;
+	}
+
+	if (r == 0)
+		pr_debug("OMAP PM: remove min clk rate constraint: "
+			 "dev %s\n", dev_name(dev));
+	else
+		pr_debug("OMAP PM: add min clk rate constraint: "
+			 "dev %s, rate = %ld Hz\n", dev_name(dev), r);
+
+	/*
+	 * Code in a real implementation should keep track of these
+	 * constraints on the clock, and determine the highest minimum
+	 * clock rate.  It should iterate over each OPP and determine
+	 * whether the OPP will result in a clock rate that would
+	 * satisfy this constraint (and any other PM constraint in effect
+	 * at that time).  Once it finds the lowest-voltage OPP that
+	 * meets those conditions, it should switch to it, or return
+	 * an error if the code is not capable of doing so.
+	 */
+
+	return 0;
+}
+
+/*
+ * DSP Bridge-specific constraints
+ */
+
+const struct omap_opp *omap_pm_dsp_get_opp_table(void)
+{
+	pr_debug("OMAP PM: DSP request for OPP table\n");
+
+	/*
+	 * Return DSP frequency table here:  The final item in the
+	 * array should have .rate = .opp_id = 0.
+	 */
+
+	return NULL;
+}
+
+void omap_pm_dsp_set_min_opp(u8 opp_id)
+{
+	if (opp_id == 0) {
+		WARN_ON(1);
+		return;
+	}
+
+	pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id);
+
+	/*
+	 *
+	 * For l-o dev tree, our VDD1 clk is keyed on OPP ID, so we
+	 * can just test to see which is higher, the CPU's desired OPP
+	 * ID or the DSP's desired OPP ID, and use whichever is
+	 * highest.
+	 *
+	 * In CDP12.14+, the VDD1 OPP custom clock that controls the DSP
+	 * rate is keyed on MPU speed, not the OPP ID.  So we need to
+	 * map the OPP ID to the MPU speed for use with clk_set_rate()
+	 * if it is higher than the current OPP clock rate.
+	 *
+	 */
+}
+
+
+u8 omap_pm_dsp_get_opp(void)
+{
+	pr_debug("OMAP PM: DSP requests current DSP OPP ID\n");
+
+	/*
+	 * For l-o dev tree, call clk_get_rate() on VDD1 OPP clock
+	 *
+	 * CDP12.14+:
+	 * Call clk_get_rate() on the OPP custom clock, map that to an
+	 * OPP ID using the tables defined in board-*.c/chip-*.c files.
+	 */
+
+	return 0;
+}
+
+/*
+ * CPUFreq-originated constraint
+ *
+ * In the future, this should be handled by custom OPP clocktype
+ * functions.
+ */
+
+struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void)
+{
+	pr_debug("OMAP PM: CPUFreq request for frequency table\n");
+
+	/*
+	 * Return CPUFreq frequency table here: loop over
+	 * all VDD1 clkrates, pull out the mpu_ck frequencies, build
+	 * table
+	 */
+
+	return NULL;
+}
+
+void omap_pm_cpu_set_freq(unsigned long f)
+{
+	if (f == 0) {
+		WARN_ON(1);
+		return;
+	}
+
+	pr_debug("OMAP PM: CPUFreq requests CPU frequency to be set to %lu\n",
+		 f);
+
+	/*
+	 * For l-o dev tree, determine whether MPU freq or DSP OPP id
+	 * freq is higher.  Find the OPP ID corresponding to the
+	 * higher frequency.  Call clk_round_rate() and clk_set_rate()
+	 * on the OPP custom clock.
+	 *
+	 * CDP should just be able to set the VDD1 OPP clock rate here.
+	 */
+}
+
+unsigned long omap_pm_cpu_get_freq(void)
+{
+	pr_debug("OMAP PM: CPUFreq requests current CPU frequency\n");
+
+	/*
+	 * Call clk_get_rate() on the mpu_ck.
+	 */
+
+	return 0;
+}
+
+/**
+ * omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled
+ *
+ * Intended for use only by OMAP PM core code to notify this layer
+ * that off mode has been enabled.
+ */
+void omap_pm_enable_off_mode(void)
+{
+	off_mode_enabled = true;
+}
+
+/**
+ * omap_pm_disable_off_mode - notify OMAP PM that off-mode is disabled
+ *
+ * Intended for use only by OMAP PM core code to notify this layer
+ * that off mode has been disabled.
+ */
+void omap_pm_disable_off_mode(void)
+{
+	off_mode_enabled = false;
+}
+
+/*
+ * Device context loss tracking
+ */
+
+#ifdef CONFIG_ARCH_OMAP2PLUS
+
+u32 omap_pm_get_dev_context_loss_count(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	u32 count;
+
+	if (WARN_ON(!dev))
+		return 0;
+
+	if (dev->parent == &omap_device_parent) {
+		count = omap_device_get_context_loss_count(pdev);
+	} else {
+		WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context "
+			  "loss counter; device %s should be converted to "
+			  "omap_device", dev_name(dev));
+		if (off_mode_enabled)
+			dummy_context_loss_counter++;
+		count = dummy_context_loss_counter;
+	}
+
+	pr_debug("OMAP PM: context loss count for dev %s = %d\n",
+		 dev_name(dev), count);
+
+	return count;
+}
+
+#else
+
+u32 omap_pm_get_dev_context_loss_count(struct device *dev)
+{
+	return dummy_context_loss_counter;
+}
+
+#endif
+
+/* Should be called before clk framework init */
+int __init omap_pm_if_early_init(void)
+{
+	return 0;
+}
+
+/* Must be called after clock framework is initialized */
+int __init omap_pm_if_init(void)
+{
+	return 0;
+}
+
+void omap_pm_if_exit(void)
+{
+	/* Deallocate CPUFreq frequency table here */
+}
+
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 05/11] OMAP PM: early init of the pwrdms states
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (8 preceding siblings ...)
  2011-06-30 15:11 ` [PATCH 05/11] OMAP PM: early init of the pwrdms states jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` [PATCH 06/11] OMAP2+: powerdomain: control power domains next state jean.pihet
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

The powerdomains next states are initialized in pwrdms_setup as a
late_initcall. Because the wake-up constraint can be requested
early in the boot sequence, the power domains next states can be
overwritten by pwrdms_setup.

This patch fixes it by initializing the power domains next states
early at boot, so that the constraints can be applied.
Later in the pwrdms_setup function the currently programmed
next states are re-used as next state values.

Applies to OMAP3 and OMAP4.

Tested on OMAP3 Beagleboard and OMAP4 Pandaboard in RET/OFF using
wake-up latency constraints on MPU, CORE and PER.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/pm34xx.c      |    2 +-
 arch/arm/mach-omap2/pm44xx.c      |    2 +-
 arch/arm/mach-omap2/powerdomain.c |    3 +++
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index c155c9d..0b0a842 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -828,7 +828,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 	if (!pwrst)
 		return -ENOMEM;
 	pwrst->pwrdm = pwrdm;
-	pwrst->next_state = PWRDM_POWER_RET;
+	pwrst->next_state = pwrdm_read_next_pwrst(pwrdm);
 	list_add(&pwrst->node, &pwrst_list);
 
 	if (pwrdm_has_hdwr_sar(pwrdm))
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 59a870b..91ede72 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -84,7 +84,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 	if (!pwrst)
 		return -ENOMEM;
 	pwrst->pwrdm = pwrdm;
-	pwrst->next_state = PWRDM_POWER_ON;
+	pwrst->next_state = pwrdm_read_next_pwrst(pwrdm);
 	list_add(&pwrst->node, &pwrst_list);
 
 	return pwrdm_set_next_pwrst(pwrst->pwrdm, pwrst->next_state);
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 9af0847..63c3e7a 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -108,6 +108,9 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
 	pwrdm->state = pwrdm_read_pwrst(pwrdm);
 	pwrdm->state_counter[pwrdm->state] = 1;
 
+	/* Early init of the next power state */
+	pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_RET);
+
 	pr_debug("powerdomain: registered %s\n", pwrdm->name);
 
 	return 0;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 05/11] OMAP PM: early init of the pwrdms states
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (7 preceding siblings ...)
  2011-06-30 15:11 ` jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` jean.pihet
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

The powerdomains next states are initialized in pwrdms_setup as a
late_initcall. Because the wake-up constraint can be requested
early in the boot sequence, the power domains next states can be
overwritten by pwrdms_setup.

This patch fixes it by initializing the power domains next states
early at boot, so that the constraints can be applied.
Later in the pwrdms_setup function the currently programmed
next states are re-used as next state values.

Applies to OMAP3 and OMAP4.

Tested on OMAP3 Beagleboard and OMAP4 Pandaboard in RET/OFF using
wake-up latency constraints on MPU, CORE and PER.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/pm34xx.c      |    2 +-
 arch/arm/mach-omap2/pm44xx.c      |    2 +-
 arch/arm/mach-omap2/powerdomain.c |    3 +++
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index c155c9d..0b0a842 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -828,7 +828,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 	if (!pwrst)
 		return -ENOMEM;
 	pwrst->pwrdm = pwrdm;
-	pwrst->next_state = PWRDM_POWER_RET;
+	pwrst->next_state = pwrdm_read_next_pwrst(pwrdm);
 	list_add(&pwrst->node, &pwrst_list);
 
 	if (pwrdm_has_hdwr_sar(pwrdm))
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 59a870b..91ede72 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -84,7 +84,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 	if (!pwrst)
 		return -ENOMEM;
 	pwrst->pwrdm = pwrdm;
-	pwrst->next_state = PWRDM_POWER_ON;
+	pwrst->next_state = pwrdm_read_next_pwrst(pwrdm);
 	list_add(&pwrst->node, &pwrst_list);
 
 	return pwrdm_set_next_pwrst(pwrst->pwrdm, pwrst->next_state);
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 9af0847..63c3e7a 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -108,6 +108,9 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
 	pwrdm->state = pwrdm_read_pwrst(pwrdm);
 	pwrdm->state_counter[pwrdm->state] = 1;
 
+	/* Early init of the next power state */
+	pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_RET);
+
 	pr_debug("powerdomain: registered %s\n", pwrdm->name);
 
 	return 0;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 06/11] OMAP2+: powerdomain: control power domains next state
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (10 preceding siblings ...)
  2011-06-30 15:11 ` [PATCH 06/11] OMAP2+: powerdomain: control power domains next state jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` [PATCH 07/11] OMAP3: powerdomain data: add wake-up latency figures jean.pihet
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

When a wake-up latency constraint is requested or removed the PM QoS
layer notifies the underlying layer with the updated strongest constraint
value. The constraint is stored in the powerdomain constraints list
and then applied to the corresponding power domain.
The power domains get the next power state programmed directly in the
registers via pwrdm_wakeuplat_update_pwrst.

Tested on OMAP3 Beagleboard and OMAP4 Pandaboard in RET/OFF using
wake-up latency constraints on MPU, CORE and PER.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/powerdomain.c |  187 +++++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/powerdomain.h |   33 ++++++-
 2 files changed, 218 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 63c3e7a..71a4092 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -17,8 +17,10 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/pm_qos_params.h>
 #include <trace/events/power.h>
 
 #include "cm2xxx_3xxx.h"
@@ -104,6 +106,12 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
 	for (i = 0; i < pwrdm->banks; i++)
 		pwrdm->ret_mem_off_counter[i] = 0;
 
+	/* Initialize the per-od wake-up constraints list and spinlock */
+	spin_lock_init(&pwrdm->wkup_lat_plist_lock);
+	plist_head_init(&pwrdm->wkup_lat_plist_head,
+			&pwrdm->wkup_lat_plist_lock);
+
+	/* Initialize the pwrdm state */
 	pwrdm_wait_transition(pwrdm);
 	pwrdm->state = pwrdm_read_pwrst(pwrdm);
 	pwrdm->state_counter[pwrdm->state] = 1;
@@ -194,6 +202,77 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
 	return 0;
 }
 
+/**
+ * pwrdm_wakeuplat_update_pwrst - Update power domain power state if needed
+ * @pwrdm: struct powerdomain * to which requesting device belongs to.
+ * @min_latency: the allowed wake-up latency for the given power domain. A
+ *  value of 0 means 'no constraint' on the pwrdm.
+ *
+ * Finds the power domain next power state that fulfills the constraint.
+ * Programs a new target state if it is different from current power state.
+ * The power domains get the next power state programmed directly in the
+ * registers.
+ *
+ * Returns 0 upon success.
+ */
+static int pwrdm_wakeuplat_update_pwrst(struct powerdomain *pwrdm,
+					long min_latency)
+{
+	int ret = 0, new_state = 0;
+
+	if (!pwrdm) {
+		WARN(1, "powerdomain: %s: invalid parameter(s)", __func__);
+		return -EINVAL;
+	}
+
+	/*
+	 * Apply constraints to power domains by programming
+	 * the pwrdm next power state.
+	 */
+
+	/* Find power state with wakeup latency < minimum constraint */
+	for (new_state = 0x0; new_state < PWRDM_MAX_PWRSTS; new_state++) {
+		if (min_latency == 0 ||
+		    pwrdm->wakeup_lat[new_state] <= min_latency)
+			break;
+	}
+
+	switch (new_state) {
+	case PWRDM_FUNC_PWRST_OFF:
+		new_state = PWRDM_POWER_OFF;
+		break;
+	case PWRDM_FUNC_PWRST_OSWR:
+		pwrdm_set_logic_retst(pwrdm, PWRDM_POWER_OFF);
+		new_state = PWRDM_POWER_RET;
+		break;
+	case PWRDM_FUNC_PWRST_CSWR:
+		pwrdm_set_logic_retst(pwrdm, PWRDM_POWER_RET);
+		new_state = PWRDM_POWER_RET;
+		break;
+	case PWRDM_FUNC_PWRST_INACTIVE:
+		new_state = PWRDM_POWER_INACTIVE;
+		break;
+	case PWRDM_FUNC_PWRST_ON:
+		new_state = PWRDM_POWER_ON;
+		break;
+	default:
+		pr_warn("powerdomain: requested latency constraint not "
+			"supported %s set to ON state\n", pwrdm->name);
+		new_state = PWRDM_POWER_ON;
+		break;
+	}
+
+	if (pwrdm_read_next_pwrst(pwrdm) != new_state)
+		ret = omap_set_pwrdm_state(pwrdm, new_state);
+
+	pr_debug("powerdomain: %s pwrst: curr=%d, prev=%d next=%d "
+		 "min_latency=%ld, set_state=%d\n", pwrdm->name,
+		 pwrdm_read_pwrst(pwrdm), pwrdm_read_prev_pwrst(pwrdm),
+		 pwrdm_read_next_pwrst(pwrdm), min_latency, new_state);
+
+	return ret;
+}
+
 /* Public functions */
 
 /**
@@ -933,6 +1012,114 @@ int pwrdm_post_transition(void)
 	return 0;
 }
 
+/*
+ * pwrdm_set_wkup_lat_constraint - Set/update/remove a powerdomain wakeup
+ *  latency constraint and apply it
+ * @pwrdm: struct powerdomain * which the constraint applies to
+ * @cookie: constraint identifier, used for tracking.
+ * @min_latency: minimum wakeup latency constraint (in microseconds) for
+ *  the given pwrdm. The value of PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE
+ *  removes the constraint.
+ *
+ * Tracks the constraints by @cookie.
+ * Constraint set/update: Adds a new entry to powerdomain's wake-up latency
+ * constraint list.
+ * If the constraint identifier already exists in the list, the old value is
+ * overwritten.
+ * Constraint removal: Removes the identifier's entry from powerdomain's
+ * wakeup latency constraint list.
+ *
+ * Applies the strongest constraint value for the given pwrdm by calling
+ * pwrdm_wakeuplat_update_pwrst.
+ *
+ * Returns 0 upon success or a negative value in case of error.
+ *
+ * The caller must check the validity of the parameters.
+ */
+int pwrdm_set_wkup_lat_constraint(struct powerdomain *pwrdm, void *cookie,
+				  long min_latency)
+{
+	struct pwrdm_wkup_constraints_entry *user = NULL;
+	struct pwrdm_wkup_constraints_entry *tmp_user, *new_user;
+	int ret = 0, free_new_user = 0, free_node = 0;
+	long value = 0;
+	unsigned long flags;
+
+	pr_debug("powerdomain: %s: pwrdm %s, cookie=0x%p, min_latency=%ld\n",
+		 __func__, pwrdm->name, cookie, min_latency);
+
+	new_user = kzalloc(sizeof(struct pwrdm_wkup_constraints_entry),
+			   GFP_KERNEL);
+	if (!new_user) {
+		pr_err("%s: FATAL ERROR: kzalloc failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	spin_lock_irqsave(&pwrdm->wkup_lat_plist_lock, flags);
+
+	/* Check if there already is a constraint for cookie */
+	plist_for_each_entry(tmp_user, &pwrdm->wkup_lat_plist_head, node) {
+		if (tmp_user->cookie == cookie) {
+			user = tmp_user;
+			free_new_user = 1;
+			break;
+		}
+	}
+
+	if (min_latency != PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE) {
+		/* If nothing to update, job done */
+		if (user && (user->node.prio == min_latency))
+			goto exit_ok;
+
+		if (!user) {
+			/* Add new entry to the list */
+			user = new_user;
+			user->cookie = cookie;
+		} else {
+			/* Update existing entry */
+			plist_del(&user->node, &pwrdm->wkup_lat_plist_head);
+		}
+
+		plist_node_init(&user->node, min_latency);
+		plist_add(&user->node, &pwrdm->wkup_lat_plist_head);
+	} else {
+		/* Remove the constraint from the list */
+		if (!user) {
+			pr_err("%s: Error: no prior constraint to release\n",
+			       __func__);
+			ret = -EINVAL;
+			goto exit_error;
+		}
+
+		plist_del(&user->node, &pwrdm->wkup_lat_plist_head);
+		free_node = 1;
+	}
+
+exit_ok:
+	/* Find the strongest constraint from the list */
+	if (!plist_head_empty(&pwrdm->wkup_lat_plist_head))
+		value = plist_first(&pwrdm->wkup_lat_plist_head)->prio;
+
+	spin_unlock_irqrestore(&pwrdm->wkup_lat_plist_lock, flags);
+
+	if (free_node)
+		kfree(user);
+
+	if (free_new_user)
+		kfree(new_user);
+
+	/* Apply the constraint to the pwrdm */
+	pr_debug("powerdomain: %s: pwrdm %s, value=%ld\n",
+		 __func__, pwrdm->name, value);
+	pwrdm_wakeuplat_update_pwrst(pwrdm, value);
+
+	return 0;
+
+exit_error:
+	spin_unlock_irqrestore(&pwrdm->wkup_lat_plist_lock, flags);
+	return ret;
+}
+
 /**
  * pwrdm_get_context_loss_count - get powerdomain's context loss count
  * @pwrdm: struct powerdomain * to wait for
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index d23d979..f2b0ed7 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -19,7 +19,9 @@
 
 #include <linux/types.h>
 #include <linux/list.h>
-
+#include <linux/plist.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
 #include <linux/atomic.h>
 
 #include <plat/cpu.h>
@@ -43,6 +45,16 @@
 #define PWRSTS_RET_ON		(PWRSTS_RET | PWRSTS_ON)
 #define PWRSTS_OFF_RET_ON	(PWRSTS_OFF_RET | PWRSTS_ON)
 
+/* Powerdomain functional power states */
+#define PWRDM_FUNC_PWRST_OFF		0x0
+#define PWRDM_FUNC_PWRST_OSWR		0x1
+#define PWRDM_FUNC_PWRST_CSWR		0x2
+#define PWRDM_FUNC_PWRST_INACTIVE	0x3
+#define PWRDM_FUNC_PWRST_ON		0x4
+
+#define PWRDM_MAX_FUNC_PWRSTS	5
+
+#define UNSUP_STATE		-1
 
 /* Powerdomain flags */
 #define PWRDM_HAS_HDWR_SAR	(1 << 0) /* hardware save-and-restore support */
@@ -93,7 +105,12 @@ struct powerdomain;
  * @state_counter:
  * @timer:
  * @state_timer:
- *
+ * @wakeup_lat: wakeup latencies (in us) for possible powerdomain power states
+ * Note about the wakeup latencies ordering: the values must be sorted
+ *  in decremental order
+ * @wkup_lat_plist_head: pwrdm wake-up latency constraints list
+ * @wkup_lat_plist_lock: spinlock that protects the constraints lists
+ *  domains states
  * @prcm_partition possible values are defined in mach-omap2/prcm44xx.h.
  */
 struct powerdomain {
@@ -118,6 +135,15 @@ struct powerdomain {
 	s64 timer;
 	s64 state_timer[PWRDM_MAX_PWRSTS];
 #endif
+	const u32 wakeup_lat[PWRDM_MAX_FUNC_PWRSTS];
+	struct plist_head wkup_lat_plist_head;
+	spinlock_t wkup_lat_plist_lock;
+};
+
+/* Linked list for the wake-up latency constraints */
+struct pwrdm_wkup_constraints_entry {
+	void			*cookie;
+	struct plist_node	node;
 };
 
 /**
@@ -207,6 +233,9 @@ int pwrdm_clkdm_state_switch(struct clockdomain *clkdm);
 int pwrdm_pre_transition(void);
 int pwrdm_post_transition(void);
 int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
+
+int pwrdm_set_wkup_lat_constraint(struct powerdomain *pwrdm, void *cookie,
+				  long min_latency);
 u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
 bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
 
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 06/11] OMAP2+: powerdomain: control power domains next state
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (9 preceding siblings ...)
  2011-06-30 15:11 ` jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` jean.pihet
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

When a wake-up latency constraint is requested or removed the PM QoS
layer notifies the underlying layer with the updated strongest constraint
value. The constraint is stored in the powerdomain constraints list
and then applied to the corresponding power domain.
The power domains get the next power state programmed directly in the
registers via pwrdm_wakeuplat_update_pwrst.

Tested on OMAP3 Beagleboard and OMAP4 Pandaboard in RET/OFF using
wake-up latency constraints on MPU, CORE and PER.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/powerdomain.c |  187 +++++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/powerdomain.h |   33 ++++++-
 2 files changed, 218 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 63c3e7a..71a4092 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -17,8 +17,10 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/list.h>
+#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/pm_qos_params.h>
 #include <trace/events/power.h>
 
 #include "cm2xxx_3xxx.h"
@@ -104,6 +106,12 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
 	for (i = 0; i < pwrdm->banks; i++)
 		pwrdm->ret_mem_off_counter[i] = 0;
 
+	/* Initialize the per-od wake-up constraints list and spinlock */
+	spin_lock_init(&pwrdm->wkup_lat_plist_lock);
+	plist_head_init(&pwrdm->wkup_lat_plist_head,
+			&pwrdm->wkup_lat_plist_lock);
+
+	/* Initialize the pwrdm state */
 	pwrdm_wait_transition(pwrdm);
 	pwrdm->state = pwrdm_read_pwrst(pwrdm);
 	pwrdm->state_counter[pwrdm->state] = 1;
@@ -194,6 +202,77 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
 	return 0;
 }
 
+/**
+ * pwrdm_wakeuplat_update_pwrst - Update power domain power state if needed
+ * @pwrdm: struct powerdomain * to which requesting device belongs to.
+ * @min_latency: the allowed wake-up latency for the given power domain. A
+ *  value of 0 means 'no constraint' on the pwrdm.
+ *
+ * Finds the power domain next power state that fulfills the constraint.
+ * Programs a new target state if it is different from current power state.
+ * The power domains get the next power state programmed directly in the
+ * registers.
+ *
+ * Returns 0 upon success.
+ */
+static int pwrdm_wakeuplat_update_pwrst(struct powerdomain *pwrdm,
+					long min_latency)
+{
+	int ret = 0, new_state = 0;
+
+	if (!pwrdm) {
+		WARN(1, "powerdomain: %s: invalid parameter(s)", __func__);
+		return -EINVAL;
+	}
+
+	/*
+	 * Apply constraints to power domains by programming
+	 * the pwrdm next power state.
+	 */
+
+	/* Find power state with wakeup latency < minimum constraint */
+	for (new_state = 0x0; new_state < PWRDM_MAX_PWRSTS; new_state++) {
+		if (min_latency == 0 ||
+		    pwrdm->wakeup_lat[new_state] <= min_latency)
+			break;
+	}
+
+	switch (new_state) {
+	case PWRDM_FUNC_PWRST_OFF:
+		new_state = PWRDM_POWER_OFF;
+		break;
+	case PWRDM_FUNC_PWRST_OSWR:
+		pwrdm_set_logic_retst(pwrdm, PWRDM_POWER_OFF);
+		new_state = PWRDM_POWER_RET;
+		break;
+	case PWRDM_FUNC_PWRST_CSWR:
+		pwrdm_set_logic_retst(pwrdm, PWRDM_POWER_RET);
+		new_state = PWRDM_POWER_RET;
+		break;
+	case PWRDM_FUNC_PWRST_INACTIVE:
+		new_state = PWRDM_POWER_INACTIVE;
+		break;
+	case PWRDM_FUNC_PWRST_ON:
+		new_state = PWRDM_POWER_ON;
+		break;
+	default:
+		pr_warn("powerdomain: requested latency constraint not "
+			"supported %s set to ON state\n", pwrdm->name);
+		new_state = PWRDM_POWER_ON;
+		break;
+	}
+
+	if (pwrdm_read_next_pwrst(pwrdm) != new_state)
+		ret = omap_set_pwrdm_state(pwrdm, new_state);
+
+	pr_debug("powerdomain: %s pwrst: curr=%d, prev=%d next=%d "
+		 "min_latency=%ld, set_state=%d\n", pwrdm->name,
+		 pwrdm_read_pwrst(pwrdm), pwrdm_read_prev_pwrst(pwrdm),
+		 pwrdm_read_next_pwrst(pwrdm), min_latency, new_state);
+
+	return ret;
+}
+
 /* Public functions */
 
 /**
@@ -933,6 +1012,114 @@ int pwrdm_post_transition(void)
 	return 0;
 }
 
+/*
+ * pwrdm_set_wkup_lat_constraint - Set/update/remove a powerdomain wakeup
+ *  latency constraint and apply it
+ * @pwrdm: struct powerdomain * which the constraint applies to
+ * @cookie: constraint identifier, used for tracking.
+ * @min_latency: minimum wakeup latency constraint (in microseconds) for
+ *  the given pwrdm. The value of PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE
+ *  removes the constraint.
+ *
+ * Tracks the constraints by @cookie.
+ * Constraint set/update: Adds a new entry to powerdomain's wake-up latency
+ * constraint list.
+ * If the constraint identifier already exists in the list, the old value is
+ * overwritten.
+ * Constraint removal: Removes the identifier's entry from powerdomain's
+ * wakeup latency constraint list.
+ *
+ * Applies the strongest constraint value for the given pwrdm by calling
+ * pwrdm_wakeuplat_update_pwrst.
+ *
+ * Returns 0 upon success or a negative value in case of error.
+ *
+ * The caller must check the validity of the parameters.
+ */
+int pwrdm_set_wkup_lat_constraint(struct powerdomain *pwrdm, void *cookie,
+				  long min_latency)
+{
+	struct pwrdm_wkup_constraints_entry *user = NULL;
+	struct pwrdm_wkup_constraints_entry *tmp_user, *new_user;
+	int ret = 0, free_new_user = 0, free_node = 0;
+	long value = 0;
+	unsigned long flags;
+
+	pr_debug("powerdomain: %s: pwrdm %s, cookie=0x%p, min_latency=%ld\n",
+		 __func__, pwrdm->name, cookie, min_latency);
+
+	new_user = kzalloc(sizeof(struct pwrdm_wkup_constraints_entry),
+			   GFP_KERNEL);
+	if (!new_user) {
+		pr_err("%s: FATAL ERROR: kzalloc failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	spin_lock_irqsave(&pwrdm->wkup_lat_plist_lock, flags);
+
+	/* Check if there already is a constraint for cookie */
+	plist_for_each_entry(tmp_user, &pwrdm->wkup_lat_plist_head, node) {
+		if (tmp_user->cookie == cookie) {
+			user = tmp_user;
+			free_new_user = 1;
+			break;
+		}
+	}
+
+	if (min_latency != PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE) {
+		/* If nothing to update, job done */
+		if (user && (user->node.prio == min_latency))
+			goto exit_ok;
+
+		if (!user) {
+			/* Add new entry to the list */
+			user = new_user;
+			user->cookie = cookie;
+		} else {
+			/* Update existing entry */
+			plist_del(&user->node, &pwrdm->wkup_lat_plist_head);
+		}
+
+		plist_node_init(&user->node, min_latency);
+		plist_add(&user->node, &pwrdm->wkup_lat_plist_head);
+	} else {
+		/* Remove the constraint from the list */
+		if (!user) {
+			pr_err("%s: Error: no prior constraint to release\n",
+			       __func__);
+			ret = -EINVAL;
+			goto exit_error;
+		}
+
+		plist_del(&user->node, &pwrdm->wkup_lat_plist_head);
+		free_node = 1;
+	}
+
+exit_ok:
+	/* Find the strongest constraint from the list */
+	if (!plist_head_empty(&pwrdm->wkup_lat_plist_head))
+		value = plist_first(&pwrdm->wkup_lat_plist_head)->prio;
+
+	spin_unlock_irqrestore(&pwrdm->wkup_lat_plist_lock, flags);
+
+	if (free_node)
+		kfree(user);
+
+	if (free_new_user)
+		kfree(new_user);
+
+	/* Apply the constraint to the pwrdm */
+	pr_debug("powerdomain: %s: pwrdm %s, value=%ld\n",
+		 __func__, pwrdm->name, value);
+	pwrdm_wakeuplat_update_pwrst(pwrdm, value);
+
+	return 0;
+
+exit_error:
+	spin_unlock_irqrestore(&pwrdm->wkup_lat_plist_lock, flags);
+	return ret;
+}
+
 /**
  * pwrdm_get_context_loss_count - get powerdomain's context loss count
  * @pwrdm: struct powerdomain * to wait for
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index d23d979..f2b0ed7 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -19,7 +19,9 @@
 
 #include <linux/types.h>
 #include <linux/list.h>
-
+#include <linux/plist.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
 #include <linux/atomic.h>
 
 #include <plat/cpu.h>
@@ -43,6 +45,16 @@
 #define PWRSTS_RET_ON		(PWRSTS_RET | PWRSTS_ON)
 #define PWRSTS_OFF_RET_ON	(PWRSTS_OFF_RET | PWRSTS_ON)
 
+/* Powerdomain functional power states */
+#define PWRDM_FUNC_PWRST_OFF		0x0
+#define PWRDM_FUNC_PWRST_OSWR		0x1
+#define PWRDM_FUNC_PWRST_CSWR		0x2
+#define PWRDM_FUNC_PWRST_INACTIVE	0x3
+#define PWRDM_FUNC_PWRST_ON		0x4
+
+#define PWRDM_MAX_FUNC_PWRSTS	5
+
+#define UNSUP_STATE		-1
 
 /* Powerdomain flags */
 #define PWRDM_HAS_HDWR_SAR	(1 << 0) /* hardware save-and-restore support */
@@ -93,7 +105,12 @@ struct powerdomain;
  * @state_counter:
  * @timer:
  * @state_timer:
- *
+ * @wakeup_lat: wakeup latencies (in us) for possible powerdomain power states
+ * Note about the wakeup latencies ordering: the values must be sorted
+ *  in decremental order
+ * @wkup_lat_plist_head: pwrdm wake-up latency constraints list
+ * @wkup_lat_plist_lock: spinlock that protects the constraints lists
+ *  domains states
  * @prcm_partition possible values are defined in mach-omap2/prcm44xx.h.
  */
 struct powerdomain {
@@ -118,6 +135,15 @@ struct powerdomain {
 	s64 timer;
 	s64 state_timer[PWRDM_MAX_PWRSTS];
 #endif
+	const u32 wakeup_lat[PWRDM_MAX_FUNC_PWRSTS];
+	struct plist_head wkup_lat_plist_head;
+	spinlock_t wkup_lat_plist_lock;
+};
+
+/* Linked list for the wake-up latency constraints */
+struct pwrdm_wkup_constraints_entry {
+	void			*cookie;
+	struct plist_node	node;
 };
 
 /**
@@ -207,6 +233,9 @@ int pwrdm_clkdm_state_switch(struct clockdomain *clkdm);
 int pwrdm_pre_transition(void);
 int pwrdm_post_transition(void);
 int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
+
+int pwrdm_set_wkup_lat_constraint(struct powerdomain *pwrdm, void *cookie,
+				  long min_latency);
 u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
 bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 07/11] OMAP3: powerdomain data: add wake-up latency figures
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (12 preceding siblings ...)
  2011-06-30 15:11 ` [PATCH 07/11] OMAP3: powerdomain data: add wake-up latency figures jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` [PATCH 08/11] OMAP4: " jean.pihet
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

Figures are added to the power domains structs.

Note: the figures are preliminary figures. More accurate measurements
are needed. Also the conditions of measurements shall be investigated
and described.

Tested on OMAP3 Beagleboard in RET/OFF using wake-up latency constraints
on MPU, CORE and PER.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/powerdomains3xxx_data.c |   77 +++++++++++++++++++++++++++
 1 files changed, 77 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
index 469a920..64446e7 100644
--- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -31,6 +31,13 @@
 
 /*
  * Powerdomains
+ *
+ * The wakeup_lat values are derived from measurements on
+ * the actual target.
+ *
+ * Note: the latency figures are preliminary and only used
+ * for the constraints framework validation.
+ * Actual figures and measurements conditions shall be added.
  */
 
 static struct powerdomain iva2_pwrdm = {
@@ -52,6 +59,13 @@ static struct powerdomain iva2_pwrdm = {
 		[2] = PWRSTS_OFF_ON,
 		[3] = PWRSTS_ON,
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1100,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 350,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain mpu_3xxx_pwrdm = {
@@ -68,6 +82,13 @@ static struct powerdomain mpu_3xxx_pwrdm = {
 	.pwrsts_mem_on	  = {
 		[0] = PWRSTS_OFF_ON,
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 95,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 45,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /*
@@ -98,6 +119,13 @@ static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
 		[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
 		[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 100,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 60,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain core_3xxx_es3_1_pwrdm = {
@@ -121,6 +149,13 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = {
 		[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
 		[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 100,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 60,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain dss_pwrdm = {
@@ -136,6 +171,13 @@ static struct powerdomain dss_pwrdm = {
 	.pwrsts_mem_on	  = {
 		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 70,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 20,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /*
@@ -157,6 +199,13 @@ static struct powerdomain sgx_pwrdm = {
 	.pwrsts_mem_on	  = {
 		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain cam_pwrdm = {
@@ -172,6 +221,13 @@ static struct powerdomain cam_pwrdm = {
 	.pwrsts_mem_on	  = {
 		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 850,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 35,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain per_pwrdm = {
@@ -187,6 +243,13 @@ static struct powerdomain per_pwrdm = {
 	.pwrsts_mem_on	  = {
 		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 200,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 110,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain emu_pwrdm = {
@@ -201,6 +264,13 @@ static struct powerdomain neon_pwrdm = {
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
 	.pwrsts_logic_ret = PWRSTS_RET,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 200,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 35,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain usbhost_pwrdm = {
@@ -223,6 +293,13 @@ static struct powerdomain usbhost_pwrdm = {
 	.pwrsts_mem_on	  = {
 		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 800,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 150,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain dpll1_pwrdm = {
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 07/11] OMAP3: powerdomain data: add wake-up latency figures
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (11 preceding siblings ...)
  2011-06-30 15:11 ` jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` jean.pihet
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

Figures are added to the power domains structs.

Note: the figures are preliminary figures. More accurate measurements
are needed. Also the conditions of measurements shall be investigated
and described.

Tested on OMAP3 Beagleboard in RET/OFF using wake-up latency constraints
on MPU, CORE and PER.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/powerdomains3xxx_data.c |   77 +++++++++++++++++++++++++++
 1 files changed, 77 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
index 469a920..64446e7 100644
--- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -31,6 +31,13 @@
 
 /*
  * Powerdomains
+ *
+ * The wakeup_lat values are derived from measurements on
+ * the actual target.
+ *
+ * Note: the latency figures are preliminary and only used
+ * for the constraints framework validation.
+ * Actual figures and measurements conditions shall be added.
  */
 
 static struct powerdomain iva2_pwrdm = {
@@ -52,6 +59,13 @@ static struct powerdomain iva2_pwrdm = {
 		[2] = PWRSTS_OFF_ON,
 		[3] = PWRSTS_ON,
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1100,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 350,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain mpu_3xxx_pwrdm = {
@@ -68,6 +82,13 @@ static struct powerdomain mpu_3xxx_pwrdm = {
 	.pwrsts_mem_on	  = {
 		[0] = PWRSTS_OFF_ON,
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 95,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 45,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /*
@@ -98,6 +119,13 @@ static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
 		[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
 		[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 100,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 60,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain core_3xxx_es3_1_pwrdm = {
@@ -121,6 +149,13 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = {
 		[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
 		[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 100,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 60,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain dss_pwrdm = {
@@ -136,6 +171,13 @@ static struct powerdomain dss_pwrdm = {
 	.pwrsts_mem_on	  = {
 		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 70,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 20,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /*
@@ -157,6 +199,13 @@ static struct powerdomain sgx_pwrdm = {
 	.pwrsts_mem_on	  = {
 		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain cam_pwrdm = {
@@ -172,6 +221,13 @@ static struct powerdomain cam_pwrdm = {
 	.pwrsts_mem_on	  = {
 		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 850,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 35,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain per_pwrdm = {
@@ -187,6 +243,13 @@ static struct powerdomain per_pwrdm = {
 	.pwrsts_mem_on	  = {
 		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 200,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 110,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain emu_pwrdm = {
@@ -201,6 +264,13 @@ static struct powerdomain neon_pwrdm = {
 	.omap_chip	  = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
 	.pwrsts		  = PWRSTS_OFF_RET_ON,
 	.pwrsts_logic_ret = PWRSTS_RET,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 200,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 35,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain usbhost_pwrdm = {
@@ -223,6 +293,13 @@ static struct powerdomain usbhost_pwrdm = {
 	.pwrsts_mem_on	  = {
 		[0] = PWRSTS_ON,  /* MEMONSTATE */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 800,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 150,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 static struct powerdomain dpll1_pwrdm = {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 08/11] OMAP4: powerdomain data: add wake-up latency figures
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (13 preceding siblings ...)
  2011-06-30 15:11 ` jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` jean.pihet
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Vishwanath BS <vishwanath.bs@ti.com>

This patch adds wake up latency numbers for OMAP4. Note that these are
preliminary numbers and need to be relooked.

Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>

The INACTIVE state is added as unsupported.

Tested on OMAP4 Pandaboard in RET/OFF using wake-up latency constraints on
MPU, CORE and PER.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/powerdomains44xx_data.c |   85 +++++++++++++++++++++++++++
 1 files changed, 85 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c
index c4222c7..9b90d88 100644
--- a/arch/arm/mach-omap2/powerdomains44xx_data.c
+++ b/arch/arm/mach-omap2/powerdomains44xx_data.c
@@ -54,6 +54,13 @@ static struct powerdomain core_44xx_pwrdm = {
 		[4] = PWRSTS_ON,	/* ducati_unicache */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* gfx_44xx_pwrdm: 3D accelerator power domain */
@@ -71,6 +78,13 @@ static struct powerdomain gfx_44xx_pwrdm = {
 		[0] = PWRSTS_ON,	/* gfx_mem */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* abe_44xx_pwrdm: Audio back end power domain */
@@ -91,6 +105,13 @@ static struct powerdomain abe_44xx_pwrdm = {
 		[1] = PWRSTS_ON,	/* periphmem */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* dss_44xx_pwrdm: Display subsystem power domain */
@@ -109,6 +130,13 @@ static struct powerdomain dss_44xx_pwrdm = {
 		[0] = PWRSTS_ON,	/* dss_mem */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* tesla_44xx_pwrdm: Tesla processor power domain */
@@ -131,6 +159,13 @@ static struct powerdomain tesla_44xx_pwrdm = {
 		[2] = PWRSTS_ON,	/* tesla_l2 */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* wkup_44xx_pwrdm: Wake-up power domain */
@@ -164,6 +199,13 @@ static struct powerdomain cpu0_44xx_pwrdm = {
 	.pwrsts_mem_on	= {
 		[0] = PWRSTS_ON,	/* cpu0_l1 */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* cpu1_44xx_pwrdm: MPU1 processor and Neon coprocessor power domain */
@@ -181,6 +223,13 @@ static struct powerdomain cpu1_44xx_pwrdm = {
 	.pwrsts_mem_on	= {
 		[0] = PWRSTS_ON,	/* cpu1_l1 */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* emu_44xx_pwrdm: Emulation power domain */
@@ -218,6 +267,13 @@ static struct powerdomain mpu_44xx_pwrdm = {
 		[1] = PWRSTS_ON,	/* mpu_l2 */
 		[2] = PWRSTS_ON,	/* mpu_ram */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* ivahd_44xx_pwrdm: IVA-HD power domain */
@@ -242,6 +298,13 @@ static struct powerdomain ivahd_44xx_pwrdm = {
 		[3] = PWRSTS_ON,	/* tcm2_mem */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* cam_44xx_pwrdm: Camera subsystem power domain */
@@ -259,6 +322,13 @@ static struct powerdomain cam_44xx_pwrdm = {
 		[0] = PWRSTS_ON,	/* cam_mem */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* l3init_44xx_pwrdm: L3 initators pheripherals power domain  */
@@ -277,6 +347,13 @@ static struct powerdomain l3init_44xx_pwrdm = {
 		[0] = PWRSTS_ON,	/* l3init_bank1 */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* l4per_44xx_pwrdm: Target peripherals power domain */
@@ -297,6 +374,13 @@ static struct powerdomain l4per_44xx_pwrdm = {
 		[1] = PWRSTS_ON,	/* retained_bank */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /*
@@ -353,3 +437,4 @@ void __init omap44xx_powerdomains_init(void)
 {
 	pwrdm_init(powerdomains_omap44xx, &omap4_pwrdm_operations);
 }
+
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 08/11] OMAP4: powerdomain data: add wake-up latency figures
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (14 preceding siblings ...)
  2011-06-30 15:11 ` [PATCH 08/11] OMAP4: " jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` [PATCH 09/11] OMAP2+: omap_hwmod: manage the wake-up latency constraints jean.pihet
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Vishwanath BS, Jean Pihet

From: Vishwanath BS <vishwanath.bs@ti.com>

This patch adds wake up latency numbers for OMAP4. Note that these are
preliminary numbers and need to be relooked.

Signed-off-by: Vishwanath BS <vishwanath.bs@ti.com>

The INACTIVE state is added as unsupported.

Tested on OMAP4 Pandaboard in RET/OFF using wake-up latency constraints on
MPU, CORE and PER.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/powerdomains44xx_data.c |   85 +++++++++++++++++++++++++++
 1 files changed, 85 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c
index c4222c7..9b90d88 100644
--- a/arch/arm/mach-omap2/powerdomains44xx_data.c
+++ b/arch/arm/mach-omap2/powerdomains44xx_data.c
@@ -54,6 +54,13 @@ static struct powerdomain core_44xx_pwrdm = {
 		[4] = PWRSTS_ON,	/* ducati_unicache */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* gfx_44xx_pwrdm: 3D accelerator power domain */
@@ -71,6 +78,13 @@ static struct powerdomain gfx_44xx_pwrdm = {
 		[0] = PWRSTS_ON,	/* gfx_mem */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* abe_44xx_pwrdm: Audio back end power domain */
@@ -91,6 +105,13 @@ static struct powerdomain abe_44xx_pwrdm = {
 		[1] = PWRSTS_ON,	/* periphmem */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* dss_44xx_pwrdm: Display subsystem power domain */
@@ -109,6 +130,13 @@ static struct powerdomain dss_44xx_pwrdm = {
 		[0] = PWRSTS_ON,	/* dss_mem */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* tesla_44xx_pwrdm: Tesla processor power domain */
@@ -131,6 +159,13 @@ static struct powerdomain tesla_44xx_pwrdm = {
 		[2] = PWRSTS_ON,	/* tesla_l2 */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* wkup_44xx_pwrdm: Wake-up power domain */
@@ -164,6 +199,13 @@ static struct powerdomain cpu0_44xx_pwrdm = {
 	.pwrsts_mem_on	= {
 		[0] = PWRSTS_ON,	/* cpu0_l1 */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* cpu1_44xx_pwrdm: MPU1 processor and Neon coprocessor power domain */
@@ -181,6 +223,13 @@ static struct powerdomain cpu1_44xx_pwrdm = {
 	.pwrsts_mem_on	= {
 		[0] = PWRSTS_ON,	/* cpu1_l1 */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* emu_44xx_pwrdm: Emulation power domain */
@@ -218,6 +267,13 @@ static struct powerdomain mpu_44xx_pwrdm = {
 		[1] = PWRSTS_ON,	/* mpu_l2 */
 		[2] = PWRSTS_ON,	/* mpu_ram */
 	},
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* ivahd_44xx_pwrdm: IVA-HD power domain */
@@ -242,6 +298,13 @@ static struct powerdomain ivahd_44xx_pwrdm = {
 		[3] = PWRSTS_ON,	/* tcm2_mem */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* cam_44xx_pwrdm: Camera subsystem power domain */
@@ -259,6 +322,13 @@ static struct powerdomain cam_44xx_pwrdm = {
 		[0] = PWRSTS_ON,	/* cam_mem */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_CSWR] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* l3init_44xx_pwrdm: L3 initators pheripherals power domain  */
@@ -277,6 +347,13 @@ static struct powerdomain l3init_44xx_pwrdm = {
 		[0] = PWRSTS_ON,	/* l3init_bank1 */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = 1000,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /* l4per_44xx_pwrdm: Target peripherals power domain */
@@ -297,6 +374,13 @@ static struct powerdomain l4per_44xx_pwrdm = {
 		[1] = PWRSTS_ON,	/* retained_bank */
 	},
 	.flags		= PWRDM_HAS_LOWPOWERSTATECHANGE,
+	.wakeup_lat = {
+		[PWRDM_FUNC_PWRST_OFF] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_OSWR] = 600,
+		[PWRDM_FUNC_PWRST_CSWR] = 300,
+		[PWRDM_FUNC_PWRST_INACTIVE] = UNSUP_STATE,
+		[PWRDM_FUNC_PWRST_ON] = 0,
+	},
 };
 
 /*
@@ -353,3 +437,4 @@ void __init omap44xx_powerdomains_init(void)
 {
 	pwrdm_init(powerdomains_omap44xx, &omap4_pwrdm_operations);
 }
+
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 09/11] OMAP2+: omap_hwmod: manage the wake-up latency constraints
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (16 preceding siblings ...)
  2011-06-30 15:11 ` [PATCH 09/11] OMAP2+: omap_hwmod: manage the wake-up latency constraints jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` [PATCH 10/11] OMAP: PM CONSTRAINTS: implement the devices " jean.pihet
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

Hwmod is queried from the OMAP_PM layer to manage the power domains
wake-up latency constraints. Hwmod retrieves the correct power domain
and if it exists it calls the corresponding power domain function.

Tested on OMAP3 Beagleboard and OMAP4 Pandaboard in RET/OFF using wake-up
latency constraints on MPU, CORE and PER.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod.c             |   26 +++++++++++++++++++++++++-
 arch/arm/plat-omap/include/plat/omap_hwmod.h |    2 ++
 2 files changed, 27 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 293fa6c..69fa946 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -142,6 +142,7 @@
 #include "powerdomain.h"
 #include <plat/clock.h>
 #include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
 #include <plat/prcm.h>
 
 #include "cm2xxx_3xxx.h"
@@ -2322,11 +2323,34 @@ ohsps_unlock:
 	return ret;
 }
 
+/*
+ * omap_hwmod_set_wkup_constraint- set/release a wake-up latency constraint
+ *
+ * @oh: struct omap_hwmod* to which the target device belongs to.
+ * @cookie: identifier of the constraints list for @oh.
+ * @min_latency: the minimum allowed wake-up latency for @oh.
+ *
+ * Returns 0 upon success.
+ */
+int omap_hwmod_set_wkup_lat_constraint(struct omap_hwmod *oh,
+				       void *cookie, long min_latency)
+{
+	struct powerdomain *pwrdm = omap_hwmod_get_pwrdm(oh);
+
+	if (!pwrdm) {
+		pr_err("%s: Error: could not find powerdomain "
+		       "for %s\n", __func__, oh->name);
+		return -EINVAL;
+	}
+
+	return pwrdm_set_wkup_lat_constraint(pwrdm, cookie, min_latency);
+}
+
 /**
  * omap_hwmod_get_context_loss_count - get lost context count
  * @oh: struct omap_hwmod *
  *
- * Query the powerdomain of of @oh to get the context loss
+ * Query the powerdomain of @oh to get the context loss
  * count for this device.
  *
  * Returns the context loss count of the powerdomain assocated with @oh
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 1adea9c..bf9e81d 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -598,6 +598,8 @@ int omap_hwmod_for_each_by_class(const char *classname,
 				 void *user);
 
 int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state);
+int omap_hwmod_set_wkup_lat_constraint(struct omap_hwmod *oh, void *cookie,
+				       long min_latency);
 u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
 
 int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 09/11] OMAP2+: omap_hwmod: manage the wake-up latency constraints
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (15 preceding siblings ...)
  2011-06-30 15:11 ` jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` jean.pihet
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

Hwmod is queried from the OMAP_PM layer to manage the power domains
wake-up latency constraints. Hwmod retrieves the correct power domain
and if it exists it calls the corresponding power domain function.

Tested on OMAP3 Beagleboard and OMAP4 Pandaboard in RET/OFF using wake-up
latency constraints on MPU, CORE and PER.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod.c             |   26 +++++++++++++++++++++++++-
 arch/arm/plat-omap/include/plat/omap_hwmod.h |    2 ++
 2 files changed, 27 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 293fa6c..69fa946 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -142,6 +142,7 @@
 #include "powerdomain.h"
 #include <plat/clock.h>
 #include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
 #include <plat/prcm.h>
 
 #include "cm2xxx_3xxx.h"
@@ -2322,11 +2323,34 @@ ohsps_unlock:
 	return ret;
 }
 
+/*
+ * omap_hwmod_set_wkup_constraint- set/release a wake-up latency constraint
+ *
+ * @oh: struct omap_hwmod* to which the target device belongs to.
+ * @cookie: identifier of the constraints list for @oh.
+ * @min_latency: the minimum allowed wake-up latency for @oh.
+ *
+ * Returns 0 upon success.
+ */
+int omap_hwmod_set_wkup_lat_constraint(struct omap_hwmod *oh,
+				       void *cookie, long min_latency)
+{
+	struct powerdomain *pwrdm = omap_hwmod_get_pwrdm(oh);
+
+	if (!pwrdm) {
+		pr_err("%s: Error: could not find powerdomain "
+		       "for %s\n", __func__, oh->name);
+		return -EINVAL;
+	}
+
+	return pwrdm_set_wkup_lat_constraint(pwrdm, cookie, min_latency);
+}
+
 /**
  * omap_hwmod_get_context_loss_count - get lost context count
  * @oh: struct omap_hwmod *
  *
- * Query the powerdomain of of @oh to get the context loss
+ * Query the powerdomain of @oh to get the context loss
  * count for this device.
  *
  * Returns the context loss count of the powerdomain assocated with @oh
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 1adea9c..bf9e81d 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -598,6 +598,8 @@ int omap_hwmod_for_each_by_class(const char *classname,
 				 void *user);
 
 int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state);
+int omap_hwmod_set_wkup_lat_constraint(struct omap_hwmod *oh, void *cookie,
+				       long min_latency);
 u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
 
 int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 10/11] OMAP: PM CONSTRAINTS: implement the devices wake-up latency constraints
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (18 preceding siblings ...)
  2011-06-30 15:11 ` [PATCH 10/11] OMAP: PM CONSTRAINTS: implement the devices " jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` [PATCH 11/11] OMAP2+: cpuidle only influences the MPU state jean.pihet
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

Implement the devices wake-up latency constraints using a PM QoS
notification handler which applies the constraints to the
underlying layer by calling the corresponding function at hwmod level.

Note: the bus throughput function is implemented but currently is
a no-op. A new PM QoS class for the bus throughput needs to be
added.

Tested on OMAP3 Beagleboard and OMAP4 Pandaboard in RET/OFF using wake-up
latency constraints on MPU, CORE and PER.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/plat-omap/include/plat/omap-pm.h |  128 ----------------------
 arch/arm/plat-omap/omap-pm-constraints.c  |  169 +++++++++++++----------------
 arch/arm/plat-omap/omap-pm-noop.c         |   89 ---------------
 3 files changed, 75 insertions(+), 311 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
index c0a7520..4318a2d 100644
--- a/arch/arm/plat-omap/include/plat/omap-pm.h
+++ b/arch/arm/plat-omap/include/plat/omap-pm.h
@@ -70,136 +70,8 @@ void omap_pm_if_exit(void);
  * Device-driver-originated constraints (via board-*.c files, platform_data)
  */
 
-
-/**
- * omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency
- * @dev: struct device * requesting the constraint
- * @t: maximum MPU wakeup latency in microseconds
- *
- * Request that the maximum interrupt latency for the MPU to be no
- * greater than @t microseconds. "Interrupt latency" in this case is
- * defined as the elapsed time from the occurrence of a hardware or
- * timer interrupt to the time when the device driver's interrupt
- * service routine has been entered by the MPU.
- *
- * It is intended that underlying PM code will use this information to
- * determine what power state to put the MPU powerdomain into, and
- * possibly the CORE powerdomain as well, since interrupt handling
- * code currently runs from SDRAM.  Advanced PM or board*.c code may
- * also configure interrupt controller priorities, OCP bus priorities,
- * CPU speed(s), etc.
- *
- * This function will not affect device wakeup latency, e.g., time
- * elapsed from when a device driver enables a hardware device with
- * clk_enable(), to when the device is ready for register access or
- * other use.  To control this device wakeup latency, use
- * omap_pm_set_max_dev_wakeup_lat()
- *
- * Multiple calls to omap_pm_set_max_mpu_wakeup_lat() will replace the
- * previous t value.  To remove the latency target for the MPU, call
- * with t = -1.
- *
- * XXX This constraint will be deprecated soon in favor of the more
- * general omap_pm_set_max_dev_wakeup_lat()
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
-int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
-
-
-/**
- * omap_pm_set_min_bus_tput - set minimum bus throughput needed by device
- * @dev: struct device * requesting the constraint
- * @tbus_id: interconnect to operate on (OCP_{INITIATOR,TARGET}_AGENT)
- * @r: minimum throughput (in KiB/s)
- *
- * Request that the minimum data throughput on the OCP interconnect
- * attached to device @dev interconnect agent @tbus_id be no less
- * than @r KiB/s.
- *
- * It is expected that the OMAP PM or bus code will use this
- * information to set the interconnect clock to run at the lowest
- * possible speed that satisfies all current system users.  The PM or
- * bus code will adjust the estimate based on its model of the bus, so
- * device driver authors should attempt to specify an accurate
- * quantity for their device use case, and let the PM or bus code
- * overestimate the numbers as necessary to handle request/response
- * latency, other competing users on the system, etc.  On OMAP2/3, if
- * a driver requests a minimum L4 interconnect speed constraint, the
- * code will also need to add an minimum L3 interconnect speed
- * constraint,
- *
- * Multiple calls to omap_pm_set_min_bus_tput() will replace the
- * previous rate value for this device.  To remove the interconnect
- * throughput restriction for this device, call with r = 0.
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
 int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
 
-
-/**
- * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency
- * @req_dev: struct device * requesting the constraint, or NULL if none
- * @dev: struct device * to set the constraint one
- * @t: maximum device wakeup latency in microseconds
- *
- * Request that the maximum amount of time necessary for a device @dev
- * to become accessible after its clocks are enabled should be no
- * greater than @t microseconds.  Specifically, this represents the
- * time from when a device driver enables device clocks with
- * clk_enable(), to when the register reads and writes on the device
- * will succeed.  This function should be called before clk_disable()
- * is called, since the power state transition decision may be made
- * during clk_disable().
- *
- * It is intended that underlying PM code will use this information to
- * determine what power state to put the powerdomain enclosing this
- * device into.
- *
- * Multiple calls to omap_pm_set_max_dev_wakeup_lat() will replace the
- * previous wakeup latency values for this device.  To remove the
- * wakeup latency restriction for this device, call with t = -1.
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
-int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
-				   long t);
-
-
-/**
- * omap_pm_set_max_sdma_lat - set the maximum system DMA transfer start latency
- * @dev: struct device *
- * @t: maximum DMA transfer start latency in microseconds
- *
- * Request that the maximum system DMA transfer start latency for this
- * device 'dev' should be no greater than 't' microseconds.  "DMA
- * transfer start latency" here is defined as the elapsed time from
- * when a device (e.g., McBSP) requests that a system DMA transfer
- * start or continue, to the time at which data starts to flow into
- * that device from the system DMA controller.
- *
- * It is intended that underlying PM code will use this information to
- * determine what power state to put the CORE powerdomain into.
- *
- * Since system DMA transfers may not involve the MPU, this function
- * will not affect MPU wakeup latency.  Use set_max_cpu_lat() to do
- * so.  Similarly, this function will not affect device wakeup latency
- * -- use set_max_dev_wakeup_lat() to affect that.
- *
- * Multiple calls to set_max_sdma_lat() will replace the previous t
- * value for this device.  To remove the maximum DMA latency for this
- * device, call with t = -1.
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
-int omap_pm_set_max_sdma_lat(struct device *dev, long t);
-
-
 /**
  * omap_pm_set_min_clk_rate - set minimum clock rate requested by @dev
  * @dev: struct device * requesting the constraint
diff --git a/arch/arm/plat-omap/omap-pm-constraints.c b/arch/arm/plat-omap/omap-pm-constraints.c
index c8b4e4c..4b508c4 100644
--- a/arch/arm/plat-omap/omap-pm-constraints.c
+++ b/arch/arm/plat-omap/omap-pm-constraints.c
@@ -17,132 +17,105 @@
 #undef DEBUG
 
 #include <linux/init.h>
+#include <linux/notifier.h>
 #include <linux/cpufreq.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
+#include <linux/pm_qos_params.h>
 
 /* Interface documentation is in mach/omap-pm.h */
 #include <plat/omap-pm.h>
 #include <plat/omap_device.h>
+#include <plat/common.h>
+#include <plat/omap_hwmod.h>
 
 static bool off_mode_enabled;
 static u32 dummy_context_loss_counter;
 
-/*
- * Device-driver-originated constraints (via board-*.c files)
- */
+static int _pm_qos_dev_wakeup_latency_handler(struct notifier_block *,
+					      unsigned long, void *);
+static struct notifier_block _pm_qos_dev_wakeup_latency_notifier = {
+	.notifier_call	= _pm_qos_dev_wakeup_latency_handler,
+};
 
-int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
+
+static int _apply_dev_wakeup_constraint(void *req, unsigned long new_value)
 {
-	if (!dev || t < -1) {
-		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+	struct omap_device *od;
+	struct omap_hwmod *oh;
+	struct platform_device *pdev;
+	struct pm_qos_request_list *pm_qos_req = req;
+
+	/* Look for the platform device for the constraint target device */
+	pdev = to_platform_device(pm_qos_req->dev);
+
+	/* Try to catch non platform devices */
+	if (pdev->name == NULL) {
+		pr_err("%s: Error: platform device for device %s not valid\n",
+		       __func__, dev_name(pm_qos_req->dev));
 		return -EINVAL;
-	};
+	}
 
-	if (t == -1)
-		pr_debug("OMAP PM: remove max MPU wakeup latency constraint: "
-			 "dev %s\n", dev_name(dev));
-	else
-		pr_debug("OMAP PM: add max MPU wakeup latency constraint: "
-			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+	/* Find the associated omap_device for dev */
+	od = container_of(pdev, struct omap_device, pdev);
+	if (od->hwmods_cnt != 1) {
+		pr_err("%s: Error: No unique hwmod for device %s\n",
+		       __func__, dev_name(pm_qos_req->dev));
+		return -EINVAL;
+	}
 
-	/*
-	 * For current Linux, this needs to map the MPU to a
-	 * powerdomain, then go through the list of current max lat
-	 * constraints on the MPU and find the smallest.  If
-	 * the latency constraint has changed, the code should
-	 * recompute the state to enter for the next powerdomain
-	 * state.
-	 *
-	 * TI CDP code can call constraint_set here.
-	 */
+	/* Find the primary omap_hwmod for dev */
+	oh = od->hwmods[0];
 
-	return 0;
+	/* Apply the constraint */
+	return omap_hwmod_set_wkup_lat_constraint(oh, pm_qos_req, new_value);
 }
 
-int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
+/* PM QoS classes handlers */
+static int _pm_qos_dev_wakeup_latency_handler(struct notifier_block *nb,
+					      unsigned long new_value,
+					      void *req)
 {
-	if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
-	    agent_id != OCP_TARGET_AGENT)) {
-		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
-		return -EINVAL;
-	};
-
-	if (r == 0)
-		pr_debug("OMAP PM: remove min bus tput constraint: "
-			 "dev %s for agent_id %d\n", dev_name(dev), agent_id);
-	else
-		pr_debug("OMAP PM: add min bus tput constraint: "
-			 "dev %s for agent_id %d: rate %ld KiB\n",
-			 dev_name(dev), agent_id, r);
-
-	/*
-	 * This code should model the interconnect and compute the
-	 * required clock frequency, convert that to a VDD2 OPP ID, then
-	 * set the VDD2 OPP appropriately.
-	 *
-	 * TI CDP code can call constraint_set here on the VDD2 OPP.
-	 */
-
-	return 0;
+	return _apply_dev_wakeup_constraint(req, new_value);
 }
 
-int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
-				   long t)
+/*
+ * omap_pm_set_min_bus_tput - set/release bus throughput constraints
+ * ToDo: currently is a no-op, to be converted to a PM QoS handler
+ * for the TPUT class
+ */
+int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
 {
-	if (!req_dev || !dev || t < -1) {
+	long t;
+	struct device *req_dev = NULL;
+
+	if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
+	    agent_id != OCP_TARGET_AGENT)) {
 		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
 		return -EINVAL;
 	};
 
-	if (t == -1)
-		pr_debug("OMAP PM: remove max device latency constraint: "
-			 "dev %s\n", dev_name(dev));
-	else
-		pr_debug("OMAP PM: add max device latency constraint: "
-			 "dev %s, t = %ld usec\n", dev_name(dev), t);
-
 	/*
-	 * For current Linux, this needs to map the device to a
-	 * powerdomain, then go through the list of current max lat
-	 * constraints on that powerdomain and find the smallest.  If
-	 * the latency constraint has changed, the code should
-	 * recompute the state to enter for the next powerdomain
-	 * state.  Conceivably, this code should also determine
-	 * whether to actually disable the device clocks or not,
-	 * depending on how long it takes to re-enable the clocks.
-	 *
-	 * TI CDP code can call constraint_set here.
+	 * A value of r == 0 removes the constraint. Convert it to the
+	 * generic _set_dev_constraint convention (-1 for constraint removal)
 	 */
-
-	return 0;
-}
-
-int omap_pm_set_max_sdma_lat(struct device *dev, long t)
-{
-	if (!dev || t < -1) {
-		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
-		return -EINVAL;
-	};
-
-	if (t == -1)
-		pr_debug("OMAP PM: remove max DMA latency constraint: "
-			 "dev %s\n", dev_name(dev));
+	if (r == 0)
+		t = -1;
 	else
-		pr_debug("OMAP PM: add max DMA latency constraint: "
-			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+		t = r;
 
 	/*
-	 * For current Linux PM QOS params, this code should scan the
-	 * list of maximum CPU and DMA latencies and select the
-	 * smallest, then set cpu_dma_latency pm_qos_param
-	 * accordingly.
-	 *
-	 * For future Linux PM QOS params, with separate CPU and DMA
-	 * latency params, this code should just set the dma_latency param.
-	 *
-	 * TI CDP code can call constraint_set here.
+	 * Assign the device for L3 or L4 interconnect to req_dev,
+	 * based on the value of agent_id
 	 */
+	switch (agent_id) {
+	case OCP_INITIATOR_AGENT:
+		req_dev = omap2_get_l3_device();
+		break;
+	case OCP_TARGET_AGENT:
+		/* Fixme: need the device for L4 interconnect */
+		break;
+	}
 
 	return 0;
 }
@@ -353,7 +326,15 @@ int __init omap_pm_if_early_init(void)
 /* Must be called after clock framework is initialized */
 int __init omap_pm_if_init(void)
 {
-	return 0;
+	int ret;
+
+	ret = pm_qos_add_notifier(PM_QOS_DEV_WAKEUP_LATENCY,
+				  &_pm_qos_dev_wakeup_latency_notifier);
+	if (ret)
+		WARN(1, KERN_ERR "Cannot add notifier for "
+			"PM_QOS_DEV_WAKEUP_LATENCY\n");
+
+	return ret;
 }
 
 void omap_pm_if_exit(void)
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
index b0471bb2..8ad902f 100644
--- a/arch/arm/plat-omap/omap-pm-noop.c
+++ b/arch/arm/plat-omap/omap-pm-noop.c
@@ -32,35 +32,6 @@ static u32 dummy_context_loss_counter;
 /*
  * Device-driver-originated constraints (via board-*.c files)
  */
-
-int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
-{
-	if (!dev || t < -1) {
-		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
-		return -EINVAL;
-	};
-
-	if (t == -1)
-		pr_debug("OMAP PM: remove max MPU wakeup latency constraint: "
-			 "dev %s\n", dev_name(dev));
-	else
-		pr_debug("OMAP PM: add max MPU wakeup latency constraint: "
-			 "dev %s, t = %ld usec\n", dev_name(dev), t);
-
-	/*
-	 * For current Linux, this needs to map the MPU to a
-	 * powerdomain, then go through the list of current max lat
-	 * constraints on the MPU and find the smallest.  If
-	 * the latency constraint has changed, the code should
-	 * recompute the state to enter for the next powerdomain
-	 * state.
-	 *
-	 * TI CDP code can call constraint_set here.
-	 */
-
-	return 0;
-}
-
 int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
 {
 	if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
@@ -88,66 +59,6 @@ int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
 	return 0;
 }
 
-int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
-				   long t)
-{
-	if (!req_dev || !dev || t < -1) {
-		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
-		return -EINVAL;
-	};
-
-	if (t == -1)
-		pr_debug("OMAP PM: remove max device latency constraint: "
-			 "dev %s\n", dev_name(dev));
-	else
-		pr_debug("OMAP PM: add max device latency constraint: "
-			 "dev %s, t = %ld usec\n", dev_name(dev), t);
-
-	/*
-	 * For current Linux, this needs to map the device to a
-	 * powerdomain, then go through the list of current max lat
-	 * constraints on that powerdomain and find the smallest.  If
-	 * the latency constraint has changed, the code should
-	 * recompute the state to enter for the next powerdomain
-	 * state.  Conceivably, this code should also determine
-	 * whether to actually disable the device clocks or not,
-	 * depending on how long it takes to re-enable the clocks.
-	 *
-	 * TI CDP code can call constraint_set here.
-	 */
-
-	return 0;
-}
-
-int omap_pm_set_max_sdma_lat(struct device *dev, long t)
-{
-	if (!dev || t < -1) {
-		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
-		return -EINVAL;
-	};
-
-	if (t == -1)
-		pr_debug("OMAP PM: remove max DMA latency constraint: "
-			 "dev %s\n", dev_name(dev));
-	else
-		pr_debug("OMAP PM: add max DMA latency constraint: "
-			 "dev %s, t = %ld usec\n", dev_name(dev), t);
-
-	/*
-	 * For current Linux PM QOS params, this code should scan the
-	 * list of maximum CPU and DMA latencies and select the
-	 * smallest, then set cpu_dma_latency pm_qos_param
-	 * accordingly.
-	 *
-	 * For future Linux PM QOS params, with separate CPU and DMA
-	 * latency params, this code should just set the dma_latency param.
-	 *
-	 * TI CDP code can call constraint_set here.
-	 */
-
-	return 0;
-}
-
 int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
 {
 	if (!dev || !c || r < 0) {
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 10/11] OMAP: PM CONSTRAINTS: implement the devices wake-up latency constraints
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (17 preceding siblings ...)
  2011-06-30 15:11 ` jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` jean.pihet
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

Implement the devices wake-up latency constraints using a PM QoS
notification handler which applies the constraints to the
underlying layer by calling the corresponding function at hwmod level.

Note: the bus throughput function is implemented but currently is
a no-op. A new PM QoS class for the bus throughput needs to be
added.

Tested on OMAP3 Beagleboard and OMAP4 Pandaboard in RET/OFF using wake-up
latency constraints on MPU, CORE and PER.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/plat-omap/include/plat/omap-pm.h |  128 ----------------------
 arch/arm/plat-omap/omap-pm-constraints.c  |  169 +++++++++++++----------------
 arch/arm/plat-omap/omap-pm-noop.c         |   89 ---------------
 3 files changed, 75 insertions(+), 311 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
index c0a7520..4318a2d 100644
--- a/arch/arm/plat-omap/include/plat/omap-pm.h
+++ b/arch/arm/plat-omap/include/plat/omap-pm.h
@@ -70,136 +70,8 @@ void omap_pm_if_exit(void);
  * Device-driver-originated constraints (via board-*.c files, platform_data)
  */
 
-
-/**
- * omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency
- * @dev: struct device * requesting the constraint
- * @t: maximum MPU wakeup latency in microseconds
- *
- * Request that the maximum interrupt latency for the MPU to be no
- * greater than @t microseconds. "Interrupt latency" in this case is
- * defined as the elapsed time from the occurrence of a hardware or
- * timer interrupt to the time when the device driver's interrupt
- * service routine has been entered by the MPU.
- *
- * It is intended that underlying PM code will use this information to
- * determine what power state to put the MPU powerdomain into, and
- * possibly the CORE powerdomain as well, since interrupt handling
- * code currently runs from SDRAM.  Advanced PM or board*.c code may
- * also configure interrupt controller priorities, OCP bus priorities,
- * CPU speed(s), etc.
- *
- * This function will not affect device wakeup latency, e.g., time
- * elapsed from when a device driver enables a hardware device with
- * clk_enable(), to when the device is ready for register access or
- * other use.  To control this device wakeup latency, use
- * omap_pm_set_max_dev_wakeup_lat()
- *
- * Multiple calls to omap_pm_set_max_mpu_wakeup_lat() will replace the
- * previous t value.  To remove the latency target for the MPU, call
- * with t = -1.
- *
- * XXX This constraint will be deprecated soon in favor of the more
- * general omap_pm_set_max_dev_wakeup_lat()
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
-int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
-
-
-/**
- * omap_pm_set_min_bus_tput - set minimum bus throughput needed by device
- * @dev: struct device * requesting the constraint
- * @tbus_id: interconnect to operate on (OCP_{INITIATOR,TARGET}_AGENT)
- * @r: minimum throughput (in KiB/s)
- *
- * Request that the minimum data throughput on the OCP interconnect
- * attached to device @dev interconnect agent @tbus_id be no less
- * than @r KiB/s.
- *
- * It is expected that the OMAP PM or bus code will use this
- * information to set the interconnect clock to run at the lowest
- * possible speed that satisfies all current system users.  The PM or
- * bus code will adjust the estimate based on its model of the bus, so
- * device driver authors should attempt to specify an accurate
- * quantity for their device use case, and let the PM or bus code
- * overestimate the numbers as necessary to handle request/response
- * latency, other competing users on the system, etc.  On OMAP2/3, if
- * a driver requests a minimum L4 interconnect speed constraint, the
- * code will also need to add an minimum L3 interconnect speed
- * constraint,
- *
- * Multiple calls to omap_pm_set_min_bus_tput() will replace the
- * previous rate value for this device.  To remove the interconnect
- * throughput restriction for this device, call with r = 0.
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
 int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
 
-
-/**
- * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency
- * @req_dev: struct device * requesting the constraint, or NULL if none
- * @dev: struct device * to set the constraint one
- * @t: maximum device wakeup latency in microseconds
- *
- * Request that the maximum amount of time necessary for a device @dev
- * to become accessible after its clocks are enabled should be no
- * greater than @t microseconds.  Specifically, this represents the
- * time from when a device driver enables device clocks with
- * clk_enable(), to when the register reads and writes on the device
- * will succeed.  This function should be called before clk_disable()
- * is called, since the power state transition decision may be made
- * during clk_disable().
- *
- * It is intended that underlying PM code will use this information to
- * determine what power state to put the powerdomain enclosing this
- * device into.
- *
- * Multiple calls to omap_pm_set_max_dev_wakeup_lat() will replace the
- * previous wakeup latency values for this device.  To remove the
- * wakeup latency restriction for this device, call with t = -1.
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
-int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
-				   long t);
-
-
-/**
- * omap_pm_set_max_sdma_lat - set the maximum system DMA transfer start latency
- * @dev: struct device *
- * @t: maximum DMA transfer start latency in microseconds
- *
- * Request that the maximum system DMA transfer start latency for this
- * device 'dev' should be no greater than 't' microseconds.  "DMA
- * transfer start latency" here is defined as the elapsed time from
- * when a device (e.g., McBSP) requests that a system DMA transfer
- * start or continue, to the time at which data starts to flow into
- * that device from the system DMA controller.
- *
- * It is intended that underlying PM code will use this information to
- * determine what power state to put the CORE powerdomain into.
- *
- * Since system DMA transfers may not involve the MPU, this function
- * will not affect MPU wakeup latency.  Use set_max_cpu_lat() to do
- * so.  Similarly, this function will not affect device wakeup latency
- * -- use set_max_dev_wakeup_lat() to affect that.
- *
- * Multiple calls to set_max_sdma_lat() will replace the previous t
- * value for this device.  To remove the maximum DMA latency for this
- * device, call with t = -1.
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
-int omap_pm_set_max_sdma_lat(struct device *dev, long t);
-
-
 /**
  * omap_pm_set_min_clk_rate - set minimum clock rate requested by @dev
  * @dev: struct device * requesting the constraint
diff --git a/arch/arm/plat-omap/omap-pm-constraints.c b/arch/arm/plat-omap/omap-pm-constraints.c
index c8b4e4c..4b508c4 100644
--- a/arch/arm/plat-omap/omap-pm-constraints.c
+++ b/arch/arm/plat-omap/omap-pm-constraints.c
@@ -17,132 +17,105 @@
 #undef DEBUG
 
 #include <linux/init.h>
+#include <linux/notifier.h>
 #include <linux/cpufreq.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
+#include <linux/pm_qos_params.h>
 
 /* Interface documentation is in mach/omap-pm.h */
 #include <plat/omap-pm.h>
 #include <plat/omap_device.h>
+#include <plat/common.h>
+#include <plat/omap_hwmod.h>
 
 static bool off_mode_enabled;
 static u32 dummy_context_loss_counter;
 
-/*
- * Device-driver-originated constraints (via board-*.c files)
- */
+static int _pm_qos_dev_wakeup_latency_handler(struct notifier_block *,
+					      unsigned long, void *);
+static struct notifier_block _pm_qos_dev_wakeup_latency_notifier = {
+	.notifier_call	= _pm_qos_dev_wakeup_latency_handler,
+};
 
-int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
+
+static int _apply_dev_wakeup_constraint(void *req, unsigned long new_value)
 {
-	if (!dev || t < -1) {
-		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+	struct omap_device *od;
+	struct omap_hwmod *oh;
+	struct platform_device *pdev;
+	struct pm_qos_request_list *pm_qos_req = req;
+
+	/* Look for the platform device for the constraint target device */
+	pdev = to_platform_device(pm_qos_req->dev);
+
+	/* Try to catch non platform devices */
+	if (pdev->name == NULL) {
+		pr_err("%s: Error: platform device for device %s not valid\n",
+		       __func__, dev_name(pm_qos_req->dev));
 		return -EINVAL;
-	};
+	}
 
-	if (t == -1)
-		pr_debug("OMAP PM: remove max MPU wakeup latency constraint: "
-			 "dev %s\n", dev_name(dev));
-	else
-		pr_debug("OMAP PM: add max MPU wakeup latency constraint: "
-			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+	/* Find the associated omap_device for dev */
+	od = container_of(pdev, struct omap_device, pdev);
+	if (od->hwmods_cnt != 1) {
+		pr_err("%s: Error: No unique hwmod for device %s\n",
+		       __func__, dev_name(pm_qos_req->dev));
+		return -EINVAL;
+	}
 
-	/*
-	 * For current Linux, this needs to map the MPU to a
-	 * powerdomain, then go through the list of current max lat
-	 * constraints on the MPU and find the smallest.  If
-	 * the latency constraint has changed, the code should
-	 * recompute the state to enter for the next powerdomain
-	 * state.
-	 *
-	 * TI CDP code can call constraint_set here.
-	 */
+	/* Find the primary omap_hwmod for dev */
+	oh = od->hwmods[0];
 
-	return 0;
+	/* Apply the constraint */
+	return omap_hwmod_set_wkup_lat_constraint(oh, pm_qos_req, new_value);
 }
 
-int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
+/* PM QoS classes handlers */
+static int _pm_qos_dev_wakeup_latency_handler(struct notifier_block *nb,
+					      unsigned long new_value,
+					      void *req)
 {
-	if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
-	    agent_id != OCP_TARGET_AGENT)) {
-		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
-		return -EINVAL;
-	};
-
-	if (r == 0)
-		pr_debug("OMAP PM: remove min bus tput constraint: "
-			 "dev %s for agent_id %d\n", dev_name(dev), agent_id);
-	else
-		pr_debug("OMAP PM: add min bus tput constraint: "
-			 "dev %s for agent_id %d: rate %ld KiB\n",
-			 dev_name(dev), agent_id, r);
-
-	/*
-	 * This code should model the interconnect and compute the
-	 * required clock frequency, convert that to a VDD2 OPP ID, then
-	 * set the VDD2 OPP appropriately.
-	 *
-	 * TI CDP code can call constraint_set here on the VDD2 OPP.
-	 */
-
-	return 0;
+	return _apply_dev_wakeup_constraint(req, new_value);
 }
 
-int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
-				   long t)
+/*
+ * omap_pm_set_min_bus_tput - set/release bus throughput constraints
+ * ToDo: currently is a no-op, to be converted to a PM QoS handler
+ * for the TPUT class
+ */
+int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
 {
-	if (!req_dev || !dev || t < -1) {
+	long t;
+	struct device *req_dev = NULL;
+
+	if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
+	    agent_id != OCP_TARGET_AGENT)) {
 		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
 		return -EINVAL;
 	};
 
-	if (t == -1)
-		pr_debug("OMAP PM: remove max device latency constraint: "
-			 "dev %s\n", dev_name(dev));
-	else
-		pr_debug("OMAP PM: add max device latency constraint: "
-			 "dev %s, t = %ld usec\n", dev_name(dev), t);
-
 	/*
-	 * For current Linux, this needs to map the device to a
-	 * powerdomain, then go through the list of current max lat
-	 * constraints on that powerdomain and find the smallest.  If
-	 * the latency constraint has changed, the code should
-	 * recompute the state to enter for the next powerdomain
-	 * state.  Conceivably, this code should also determine
-	 * whether to actually disable the device clocks or not,
-	 * depending on how long it takes to re-enable the clocks.
-	 *
-	 * TI CDP code can call constraint_set here.
+	 * A value of r == 0 removes the constraint. Convert it to the
+	 * generic _set_dev_constraint convention (-1 for constraint removal)
 	 */
-
-	return 0;
-}
-
-int omap_pm_set_max_sdma_lat(struct device *dev, long t)
-{
-	if (!dev || t < -1) {
-		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
-		return -EINVAL;
-	};
-
-	if (t == -1)
-		pr_debug("OMAP PM: remove max DMA latency constraint: "
-			 "dev %s\n", dev_name(dev));
+	if (r == 0)
+		t = -1;
 	else
-		pr_debug("OMAP PM: add max DMA latency constraint: "
-			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+		t = r;
 
 	/*
-	 * For current Linux PM QOS params, this code should scan the
-	 * list of maximum CPU and DMA latencies and select the
-	 * smallest, then set cpu_dma_latency pm_qos_param
-	 * accordingly.
-	 *
-	 * For future Linux PM QOS params, with separate CPU and DMA
-	 * latency params, this code should just set the dma_latency param.
-	 *
-	 * TI CDP code can call constraint_set here.
+	 * Assign the device for L3 or L4 interconnect to req_dev,
+	 * based on the value of agent_id
 	 */
+	switch (agent_id) {
+	case OCP_INITIATOR_AGENT:
+		req_dev = omap2_get_l3_device();
+		break;
+	case OCP_TARGET_AGENT:
+		/* Fixme: need the device for L4 interconnect */
+		break;
+	}
 
 	return 0;
 }
@@ -353,7 +326,15 @@ int __init omap_pm_if_early_init(void)
 /* Must be called after clock framework is initialized */
 int __init omap_pm_if_init(void)
 {
-	return 0;
+	int ret;
+
+	ret = pm_qos_add_notifier(PM_QOS_DEV_WAKEUP_LATENCY,
+				  &_pm_qos_dev_wakeup_latency_notifier);
+	if (ret)
+		WARN(1, KERN_ERR "Cannot add notifier for "
+			"PM_QOS_DEV_WAKEUP_LATENCY\n");
+
+	return ret;
 }
 
 void omap_pm_if_exit(void)
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
index b0471bb2..8ad902f 100644
--- a/arch/arm/plat-omap/omap-pm-noop.c
+++ b/arch/arm/plat-omap/omap-pm-noop.c
@@ -32,35 +32,6 @@ static u32 dummy_context_loss_counter;
 /*
  * Device-driver-originated constraints (via board-*.c files)
  */
-
-int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
-{
-	if (!dev || t < -1) {
-		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
-		return -EINVAL;
-	};
-
-	if (t == -1)
-		pr_debug("OMAP PM: remove max MPU wakeup latency constraint: "
-			 "dev %s\n", dev_name(dev));
-	else
-		pr_debug("OMAP PM: add max MPU wakeup latency constraint: "
-			 "dev %s, t = %ld usec\n", dev_name(dev), t);
-
-	/*
-	 * For current Linux, this needs to map the MPU to a
-	 * powerdomain, then go through the list of current max lat
-	 * constraints on the MPU and find the smallest.  If
-	 * the latency constraint has changed, the code should
-	 * recompute the state to enter for the next powerdomain
-	 * state.
-	 *
-	 * TI CDP code can call constraint_set here.
-	 */
-
-	return 0;
-}
-
 int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
 {
 	if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
@@ -88,66 +59,6 @@ int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
 	return 0;
 }
 
-int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
-				   long t)
-{
-	if (!req_dev || !dev || t < -1) {
-		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
-		return -EINVAL;
-	};
-
-	if (t == -1)
-		pr_debug("OMAP PM: remove max device latency constraint: "
-			 "dev %s\n", dev_name(dev));
-	else
-		pr_debug("OMAP PM: add max device latency constraint: "
-			 "dev %s, t = %ld usec\n", dev_name(dev), t);
-
-	/*
-	 * For current Linux, this needs to map the device to a
-	 * powerdomain, then go through the list of current max lat
-	 * constraints on that powerdomain and find the smallest.  If
-	 * the latency constraint has changed, the code should
-	 * recompute the state to enter for the next powerdomain
-	 * state.  Conceivably, this code should also determine
-	 * whether to actually disable the device clocks or not,
-	 * depending on how long it takes to re-enable the clocks.
-	 *
-	 * TI CDP code can call constraint_set here.
-	 */
-
-	return 0;
-}
-
-int omap_pm_set_max_sdma_lat(struct device *dev, long t)
-{
-	if (!dev || t < -1) {
-		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
-		return -EINVAL;
-	};
-
-	if (t == -1)
-		pr_debug("OMAP PM: remove max DMA latency constraint: "
-			 "dev %s\n", dev_name(dev));
-	else
-		pr_debug("OMAP PM: add max DMA latency constraint: "
-			 "dev %s, t = %ld usec\n", dev_name(dev), t);
-
-	/*
-	 * For current Linux PM QOS params, this code should scan the
-	 * list of maximum CPU and DMA latencies and select the
-	 * smallest, then set cpu_dma_latency pm_qos_param
-	 * accordingly.
-	 *
-	 * For future Linux PM QOS params, with separate CPU and DMA
-	 * latency params, this code should just set the dma_latency param.
-	 *
-	 * TI CDP code can call constraint_set here.
-	 */
-
-	return 0;
-}
-
 int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
 {
 	if (!dev || !c || r < 0) {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 11/11] OMAP2+: cpuidle only influences the MPU state
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (20 preceding siblings ...)
  2011-06-30 15:11 ` [PATCH 11/11] OMAP2+: cpuidle only influences the MPU state jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-07-02 19:20 ` [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class Rafael J. Wysocki
  2011-07-02 19:20 ` Rafael J. Wysocki
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

Since cpuidle is a CPU centric framework it decides the MPU
next power state based on the MPU exit_latency and target_residency
figures.

The rest of the power domains get their next power state programmed
from the PM_QOS_DEV_WAKEUP_LATENCY class of the PM QoS framework,
via the device wake-up latency constraints.

Note: the exit_latency and target_residency figures of the MPU
include the MPU itself and the peripherals needed for the MPU to
execute instructions (e.g. main memory, caches, IRQ controller,
MMU etc). Some of those peripherals can belong to other power domains
than the MPU subsystem and so the corresponding latencies must be
included in this figure.

Tested on OMAP3 Beagleboard in RET/OFF using wake-up latency constraints
on MPU, CORE and PER.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/cpuidle34xx.c |   42 +++++++++++-------------------------
 arch/arm/mach-omap2/pm.h          |   17 +++++++++++++-
 2 files changed, 28 insertions(+), 31 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 4bf6e6e..b43d1d2 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -37,26 +37,26 @@
 #ifdef CONFIG_CPU_IDLE
 
 /*
- * The latencies/thresholds for various C states have
+ * The MPU latencies/thresholds for various C states have
  * to be configured from the respective board files.
  * These are some default values (which might not provide
  * the best power savings) used on boards which do not
  * pass these details from the board file.
  */
 static struct cpuidle_params cpuidle_params_table[] = {
-	/* C1 */
+	/* C1 . MPU WFI + Core active */
 	{2 + 2, 5, 1},
-	/* C2 */
+	/* C2 . MPU WFI + Core inactive */
 	{10 + 10, 30, 1},
-	/* C3 */
+	/* C3 . MPU CSWR + Core inactive */
 	{50 + 50, 300, 1},
-	/* C4 */
+	/* C4 . MPU OFF + Core inactive */
 	{1500 + 1800, 4000, 1},
-	/* C5 */
+	/* C5 . MPU RET + Core RET */
 	{2500 + 7500, 12000, 1},
-	/* C6 */
+	/* C6 . MPU OFF + Core RET */
 	{3000 + 8500, 15000, 1},
-	/* C7 */
+	/* C7 . MPU OFF + Core OFF */
 	{10000 + 30000, 300000, 1},
 };
 #define OMAP3_NUM_STATES ARRAY_SIZE(cpuidle_params_table)
@@ -64,7 +64,6 @@ static struct cpuidle_params cpuidle_params_table[] = {
 /* Mach specific information to be recorded in the C-state driver_data */
 struct omap3_idle_statedata {
 	u32 mpu_state;
-	u32 core_state;
 	u8 valid;
 };
 struct omap3_idle_statedata omap3_idle_data[OMAP3_NUM_STATES];
@@ -98,7 +97,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
 {
 	struct omap3_idle_statedata *cx = cpuidle_get_statedata(state);
 	struct timespec ts_preidle, ts_postidle, ts_idle;
-	u32 mpu_state = cx->mpu_state, core_state = cx->core_state;
+	u32 mpu_state = cx->mpu_state;
 
 	/* Used to keep track of the total time in idle */
 	getnstimeofday(&ts_preidle);
@@ -107,7 +106,6 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
 	local_fiq_disable();
 
 	pwrdm_set_next_pwrst(mpu_pd, mpu_state);
-	pwrdm_set_next_pwrst(core_pd, core_state);
 
 	if (omap_irq_pending() || need_resched())
 		goto return_sleep_time;
@@ -156,6 +154,7 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
 	struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr);
 	u32 mpu_deepest_state = PWRDM_POWER_RET;
 	u32 core_deepest_state = PWRDM_POWER_RET;
+	u32 core_next_state = pwrdm_read_next_pwrst(core_pd);
 
 	if (enable_off_mode) {
 		mpu_deepest_state = PWRDM_POWER_OFF;
@@ -171,7 +170,7 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
 	/* Check if current state is valid */
 	if ((cx->valid) &&
 	    (cx->mpu_state >= mpu_deepest_state) &&
-	    (cx->core_state >= core_deepest_state)) {
+	    (core_next_state >= core_deepest_state)) {
 		return curr;
 	} else {
 		int idx = OMAP3_NUM_STATES - 1;
@@ -196,7 +195,7 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
 			cx = cpuidle_get_statedata(&dev->states[idx]);
 			if ((cx->valid) &&
 			    (cx->mpu_state >= mpu_deepest_state) &&
-			    (cx->core_state >= core_deepest_state)) {
+			    (core_next_state >= core_deepest_state)) {
 				next = &dev->states[idx];
 				break;
 			}
@@ -242,19 +241,11 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
 	}
 
 	/*
-	 * FIXME: we currently manage device-specific idle states
-	 *        for PER and CORE in combination with CPU-specific
-	 *        idle states.  This is wrong, and device-specific
-	 *        idle management needs to be separated out into
-	 *        its own code.
-	 */
-
-	/*
 	 * Prevent PER off if CORE is not in retention or off as this
 	 * would disable PER wakeups completely.
 	 */
 	cx = cpuidle_get_statedata(state);
-	core_next_state = cx->core_state;
+	core_next_state = pwrdm_read_next_pwrst(core_pd);
 	per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
 	if ((per_next_state == PWRDM_POWER_OFF) &&
 	    (core_next_state > PWRDM_POWER_RET))
@@ -346,32 +337,26 @@ int __init omap3_idle_init(void)
 	dev->safe_state = &dev->states[0];
 	cx->valid = 1;	/* C1 is always valid */
 	cx->mpu_state = PWRDM_POWER_ON;
-	cx->core_state = PWRDM_POWER_ON;
 
 	/* C2 . MPU WFI + Core inactive */
 	cx = _fill_cstate(dev, 1, "MPU ON + CORE ON");
 	cx->mpu_state = PWRDM_POWER_ON;
-	cx->core_state = PWRDM_POWER_ON;
 
 	/* C3 . MPU CSWR + Core inactive */
 	cx = _fill_cstate(dev, 2, "MPU RET + CORE ON");
 	cx->mpu_state = PWRDM_POWER_RET;
-	cx->core_state = PWRDM_POWER_ON;
 
 	/* C4 . MPU OFF + Core inactive */
 	cx = _fill_cstate(dev, 3, "MPU OFF + CORE ON");
 	cx->mpu_state = PWRDM_POWER_OFF;
-	cx->core_state = PWRDM_POWER_ON;
 
 	/* C5 . MPU RET + Core RET */
 	cx = _fill_cstate(dev, 4, "MPU RET + CORE RET");
 	cx->mpu_state = PWRDM_POWER_RET;
-	cx->core_state = PWRDM_POWER_RET;
 
 	/* C6 . MPU OFF + Core RET */
 	cx = _fill_cstate(dev, 5, "MPU OFF + CORE RET");
 	cx->mpu_state = PWRDM_POWER_OFF;
-	cx->core_state = PWRDM_POWER_RET;
 
 	/* C7 . MPU OFF + Core OFF */
 	cx = _fill_cstate(dev, 6, "MPU OFF + CORE OFF");
@@ -386,7 +371,6 @@ int __init omap3_idle_init(void)
 			__func__);
 	}
 	cx->mpu_state = PWRDM_POWER_OFF;
-	cx->core_state = PWRDM_POWER_OFF;
 
 	dev->state_count = OMAP3_NUM_STATES;
 	if (cpuidle_register_device(dev)) {
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 45bcfce..6fc6128 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -43,9 +43,22 @@ static inline int omap4_opp_init(void)
  * omap3_pm_init_cpuidle
  */
 struct cpuidle_params {
-	u32 exit_latency;	/* exit_latency = sleep + wake-up latencies */
+	/*
+	 * exit_latency = sleep + wake-up latencies of the MPU,
+	 * which include the MPU itself and the peripherals needed
+	 * for the MPU to execute instructions (e.g. main memory,
+	 * caches, IRQ controller, MMU etc). Some of those peripherals
+	 * can belong to other power domains than the MPU subsystem and so
+	 * the corresponding latencies must be included in this figure.
+	 */
+	u32 exit_latency;
+	/*
+	 * target_residency: required amount of time in the C state
+	 * to break even on energy cost
+	 */
 	u32 target_residency;
-	u8 valid;		/* validates the C-state */
+	/* validates the C-state on the given board */
+	u8 valid;
 };
 
 #if defined(CONFIG_PM) && defined(CONFIG_CPU_IDLE)
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 122+ messages in thread

* [PATCH 11/11] OMAP2+: cpuidle only influences the MPU state
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (19 preceding siblings ...)
  2011-06-30 15:11 ` jean.pihet
@ 2011-06-30 15:11 ` jean.pihet
  2011-06-30 15:11 ` jean.pihet
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 122+ messages in thread
From: jean.pihet @ 2011-06-30 15:11 UTC (permalink / raw)
  To: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list
  Cc: Jean Pihet

From: Jean Pihet <j-pihet@ti.com>

Since cpuidle is a CPU centric framework it decides the MPU
next power state based on the MPU exit_latency and target_residency
figures.

The rest of the power domains get their next power state programmed
from the PM_QOS_DEV_WAKEUP_LATENCY class of the PM QoS framework,
via the device wake-up latency constraints.

Note: the exit_latency and target_residency figures of the MPU
include the MPU itself and the peripherals needed for the MPU to
execute instructions (e.g. main memory, caches, IRQ controller,
MMU etc). Some of those peripherals can belong to other power domains
than the MPU subsystem and so the corresponding latencies must be
included in this figure.

Tested on OMAP3 Beagleboard in RET/OFF using wake-up latency constraints
on MPU, CORE and PER.

Signed-off-by: Jean Pihet <j-pihet@ti.com>
---
 arch/arm/mach-omap2/cpuidle34xx.c |   42 +++++++++++-------------------------
 arch/arm/mach-omap2/pm.h          |   17 +++++++++++++-
 2 files changed, 28 insertions(+), 31 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index 4bf6e6e..b43d1d2 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -37,26 +37,26 @@
 #ifdef CONFIG_CPU_IDLE
 
 /*
- * The latencies/thresholds for various C states have
+ * The MPU latencies/thresholds for various C states have
  * to be configured from the respective board files.
  * These are some default values (which might not provide
  * the best power savings) used on boards which do not
  * pass these details from the board file.
  */
 static struct cpuidle_params cpuidle_params_table[] = {
-	/* C1 */
+	/* C1 . MPU WFI + Core active */
 	{2 + 2, 5, 1},
-	/* C2 */
+	/* C2 . MPU WFI + Core inactive */
 	{10 + 10, 30, 1},
-	/* C3 */
+	/* C3 . MPU CSWR + Core inactive */
 	{50 + 50, 300, 1},
-	/* C4 */
+	/* C4 . MPU OFF + Core inactive */
 	{1500 + 1800, 4000, 1},
-	/* C5 */
+	/* C5 . MPU RET + Core RET */
 	{2500 + 7500, 12000, 1},
-	/* C6 */
+	/* C6 . MPU OFF + Core RET */
 	{3000 + 8500, 15000, 1},
-	/* C7 */
+	/* C7 . MPU OFF + Core OFF */
 	{10000 + 30000, 300000, 1},
 };
 #define OMAP3_NUM_STATES ARRAY_SIZE(cpuidle_params_table)
@@ -64,7 +64,6 @@ static struct cpuidle_params cpuidle_params_table[] = {
 /* Mach specific information to be recorded in the C-state driver_data */
 struct omap3_idle_statedata {
 	u32 mpu_state;
-	u32 core_state;
 	u8 valid;
 };
 struct omap3_idle_statedata omap3_idle_data[OMAP3_NUM_STATES];
@@ -98,7 +97,7 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
 {
 	struct omap3_idle_statedata *cx = cpuidle_get_statedata(state);
 	struct timespec ts_preidle, ts_postidle, ts_idle;
-	u32 mpu_state = cx->mpu_state, core_state = cx->core_state;
+	u32 mpu_state = cx->mpu_state;
 
 	/* Used to keep track of the total time in idle */
 	getnstimeofday(&ts_preidle);
@@ -107,7 +106,6 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
 	local_fiq_disable();
 
 	pwrdm_set_next_pwrst(mpu_pd, mpu_state);
-	pwrdm_set_next_pwrst(core_pd, core_state);
 
 	if (omap_irq_pending() || need_resched())
 		goto return_sleep_time;
@@ -156,6 +154,7 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
 	struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr);
 	u32 mpu_deepest_state = PWRDM_POWER_RET;
 	u32 core_deepest_state = PWRDM_POWER_RET;
+	u32 core_next_state = pwrdm_read_next_pwrst(core_pd);
 
 	if (enable_off_mode) {
 		mpu_deepest_state = PWRDM_POWER_OFF;
@@ -171,7 +170,7 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
 	/* Check if current state is valid */
 	if ((cx->valid) &&
 	    (cx->mpu_state >= mpu_deepest_state) &&
-	    (cx->core_state >= core_deepest_state)) {
+	    (core_next_state >= core_deepest_state)) {
 		return curr;
 	} else {
 		int idx = OMAP3_NUM_STATES - 1;
@@ -196,7 +195,7 @@ static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
 			cx = cpuidle_get_statedata(&dev->states[idx]);
 			if ((cx->valid) &&
 			    (cx->mpu_state >= mpu_deepest_state) &&
-			    (cx->core_state >= core_deepest_state)) {
+			    (core_next_state >= core_deepest_state)) {
 				next = &dev->states[idx];
 				break;
 			}
@@ -242,19 +241,11 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
 	}
 
 	/*
-	 * FIXME: we currently manage device-specific idle states
-	 *        for PER and CORE in combination with CPU-specific
-	 *        idle states.  This is wrong, and device-specific
-	 *        idle management needs to be separated out into
-	 *        its own code.
-	 */
-
-	/*
 	 * Prevent PER off if CORE is not in retention or off as this
 	 * would disable PER wakeups completely.
 	 */
 	cx = cpuidle_get_statedata(state);
-	core_next_state = cx->core_state;
+	core_next_state = pwrdm_read_next_pwrst(core_pd);
 	per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
 	if ((per_next_state == PWRDM_POWER_OFF) &&
 	    (core_next_state > PWRDM_POWER_RET))
@@ -346,32 +337,26 @@ int __init omap3_idle_init(void)
 	dev->safe_state = &dev->states[0];
 	cx->valid = 1;	/* C1 is always valid */
 	cx->mpu_state = PWRDM_POWER_ON;
-	cx->core_state = PWRDM_POWER_ON;
 
 	/* C2 . MPU WFI + Core inactive */
 	cx = _fill_cstate(dev, 1, "MPU ON + CORE ON");
 	cx->mpu_state = PWRDM_POWER_ON;
-	cx->core_state = PWRDM_POWER_ON;
 
 	/* C3 . MPU CSWR + Core inactive */
 	cx = _fill_cstate(dev, 2, "MPU RET + CORE ON");
 	cx->mpu_state = PWRDM_POWER_RET;
-	cx->core_state = PWRDM_POWER_ON;
 
 	/* C4 . MPU OFF + Core inactive */
 	cx = _fill_cstate(dev, 3, "MPU OFF + CORE ON");
 	cx->mpu_state = PWRDM_POWER_OFF;
-	cx->core_state = PWRDM_POWER_ON;
 
 	/* C5 . MPU RET + Core RET */
 	cx = _fill_cstate(dev, 4, "MPU RET + CORE RET");
 	cx->mpu_state = PWRDM_POWER_RET;
-	cx->core_state = PWRDM_POWER_RET;
 
 	/* C6 . MPU OFF + Core RET */
 	cx = _fill_cstate(dev, 5, "MPU OFF + CORE RET");
 	cx->mpu_state = PWRDM_POWER_OFF;
-	cx->core_state = PWRDM_POWER_RET;
 
 	/* C7 . MPU OFF + Core OFF */
 	cx = _fill_cstate(dev, 6, "MPU OFF + CORE OFF");
@@ -386,7 +371,6 @@ int __init omap3_idle_init(void)
 			__func__);
 	}
 	cx->mpu_state = PWRDM_POWER_OFF;
-	cx->core_state = PWRDM_POWER_OFF;
 
 	dev->state_count = OMAP3_NUM_STATES;
 	if (cpuidle_register_device(dev)) {
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 45bcfce..6fc6128 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -43,9 +43,22 @@ static inline int omap4_opp_init(void)
  * omap3_pm_init_cpuidle
  */
 struct cpuidle_params {
-	u32 exit_latency;	/* exit_latency = sleep + wake-up latencies */
+	/*
+	 * exit_latency = sleep + wake-up latencies of the MPU,
+	 * which include the MPU itself and the peripherals needed
+	 * for the MPU to execute instructions (e.g. main memory,
+	 * caches, IRQ controller, MMU etc). Some of those peripherals
+	 * can belong to other power domains than the MPU subsystem and so
+	 * the corresponding latencies must be included in this figure.
+	 */
+	u32 exit_latency;
+	/*
+	 * target_residency: required amount of time in the C state
+	 * to break even on energy cost
+	 */
 	u32 target_residency;
-	u8 valid;		/* validates the C-state */
+	/* validates the C-state on the given board */
+	u8 valid;
 };
 
 #if defined(CONFIG_PM) && defined(CONFIG_CPU_IDLE)
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 122+ messages in thread

* Re: [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (21 preceding siblings ...)
  2011-06-30 15:11 ` jean.pihet
@ 2011-07-02 19:20 ` Rafael J. Wysocki
  2011-07-02 19:20 ` Rafael J. Wysocki
  23 siblings, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-07-02 19:20 UTC (permalink / raw)
  To: jean.pihet; +Cc: markgross, Linux PM mailing list, linux-omap, Jean Pihet

Hi,

On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
> From: Jean Pihet <j-pihet@ti.com>
> 
> This patch set is in an RFC state, for review and comments.

First off, I'm sorry I couldn't review the patchset earlier.

> In order to implement the new class in PM QoS the following changes have been
> made:
> 
> 1. Add a new PM QoS class for device wake-up constraints
> (PM_QOS_DEV_WAKEUP_LATENCY).
> Due to the per-device nature of the new class the constraints lists are stored
> inside the device dev_pm_info struct instead of the internal per-class
> constraints lists.
> The new class is only available from kernel drivers and so is not exported to
> user space.

Have you considered a design in which multiple devices may use the same
list of constraints?  It seems plausible that the constraints will be the
same, for example, for all Ethernet adapters in the system, in which case it
will be wasteful to duplicate the list of constraints for each of them.

> 2. Added a notification of device insertion/removal from the device PM framework
> to PM QoS.
> This allows to init/de-init the per-device constraints list upon device insertion
> and removal.
> RFC state for comments and review, barely tested

I need to have a look at the details, but in principle this means that the
per-device lists will be usable only after the devices have been registered.
In particular, this means that it will only be possible to add new constraints
after registering the device, which may be too late for some use cases.

> 3. Make the pm_qos_add_request API more generic by using a
> struct pm_qos_parameters parameter. This allows easy extension in the future.
> 
> 4. Upon a change of the strongest constraint in the PM_QOS_DEV_WAKEUP_LATENCY
> class a notification chain mechanism is used to take action on the system.
> This is the proposed way to have PM QoS and the platform dependant code to
> interact with each other, cf. 4 below.

I guess you mean 5.?

I think we will need something in addition to the notifier here.  For example,
I wouldn't like any core code, like runtime PM or cpuidle, to have to register
a notifier with PM QoS.

> The notification mechanism now passes the constraint request struct ptr in
> order for the notifier callback to have access to the full set of constraint
> data, e.g. the struct device ptr.
> 
> 5. cpuidle interaction with the OMAP3 cpuidle handler
> Since cpuidle is a CPU centric framework it decides the MPU next power state
> based on the MPU exit_latency and target_residency figures.
>     
> The rest of the power domains get their next power state programmed from
> the PM_QOS_DEV_WAKEUP_LATENCY class of the PM QoS framework, via the device
> wake-up latency constraints.
> 
> Note: the exit_latency and target_residency figures of the MPU include the MPU
> itself and the peripherals needed for the MPU to execute instructions (e.g.
> main memory, caches, IRQ controller, MMU etc).
> Some of those peripherals can belong to other power domains than the MPU
> subsystem and so the corresponding latencies must be included in those figures.
> 
> 6. Update the pm_qos_add_request callers to the generic API
> 
> 7. Minor clean-ups and rename of struct fields
> 
> Questions:
> 1. How to retrieve the device ptr from a given device driver in order to add
> a constraint on it?
> 2. The device struct has recently been extended with the power domain
> information. Can this be used to apply the constraints on power domains?

Yes, it can in principle, but that will require some work.

> On-going developments, patches in preparation:
> 1. write Documentation for the new PM QoS class

I'd wait with that until the code has settled.

> 2. validate the constraints framework on OMAP4 HW (done on OMAP3)
> 3. refine the power domains wake-up latency and the cpuidle figures
> 
> Based on the master branch of the linux-omap git tree (3.0.0-rc3). Compile
> tested using OMAP and x86 generic defconfigs.
> Tested on OMAP3 Beagleboard (ES2.x) with full RETention and OFF modes.

More detailed comments will follow.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class
  2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
                   ` (22 preceding siblings ...)
  2011-07-02 19:20 ` [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class Rafael J. Wysocki
@ 2011-07-02 19:20 ` Rafael J. Wysocki
  2011-07-04  7:16   ` Vishwanath Sripathy
                     ` (2 more replies)
  23 siblings, 3 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-07-02 19:20 UTC (permalink / raw)
  To: jean.pihet
  Cc: Paul Walmsley, Kevin Hilman, Magnus Damm, Linux PM mailing list,
	linux-omap, markgross, Jean Pihet

Hi,

On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
> From: Jean Pihet <j-pihet@ti.com>
> 
> This patch set is in an RFC state, for review and comments.

First off, I'm sorry I couldn't review the patchset earlier.

> In order to implement the new class in PM QoS the following changes have been
> made:
> 
> 1. Add a new PM QoS class for device wake-up constraints
> (PM_QOS_DEV_WAKEUP_LATENCY).
> Due to the per-device nature of the new class the constraints lists are stored
> inside the device dev_pm_info struct instead of the internal per-class
> constraints lists.
> The new class is only available from kernel drivers and so is not exported to
> user space.

Have you considered a design in which multiple devices may use the same
list of constraints?  It seems plausible that the constraints will be the
same, for example, for all Ethernet adapters in the system, in which case it
will be wasteful to duplicate the list of constraints for each of them.

> 2. Added a notification of device insertion/removal from the device PM framework
> to PM QoS.
> This allows to init/de-init the per-device constraints list upon device insertion
> and removal.
> RFC state for comments and review, barely tested

I need to have a look at the details, but in principle this means that the
per-device lists will be usable only after the devices have been registered.
In particular, this means that it will only be possible to add new constraints
after registering the device, which may be too late for some use cases.

> 3. Make the pm_qos_add_request API more generic by using a
> struct pm_qos_parameters parameter. This allows easy extension in the future.
> 
> 4. Upon a change of the strongest constraint in the PM_QOS_DEV_WAKEUP_LATENCY
> class a notification chain mechanism is used to take action on the system.
> This is the proposed way to have PM QoS and the platform dependant code to
> interact with each other, cf. 4 below.

I guess you mean 5.?

I think we will need something in addition to the notifier here.  For example,
I wouldn't like any core code, like runtime PM or cpuidle, to have to register
a notifier with PM QoS.

> The notification mechanism now passes the constraint request struct ptr in
> order for the notifier callback to have access to the full set of constraint
> data, e.g. the struct device ptr.
> 
> 5. cpuidle interaction with the OMAP3 cpuidle handler
> Since cpuidle is a CPU centric framework it decides the MPU next power state
> based on the MPU exit_latency and target_residency figures.
>     
> The rest of the power domains get their next power state programmed from
> the PM_QOS_DEV_WAKEUP_LATENCY class of the PM QoS framework, via the device
> wake-up latency constraints.
> 
> Note: the exit_latency and target_residency figures of the MPU include the MPU
> itself and the peripherals needed for the MPU to execute instructions (e.g.
> main memory, caches, IRQ controller, MMU etc).
> Some of those peripherals can belong to other power domains than the MPU
> subsystem and so the corresponding latencies must be included in those figures.
> 
> 6. Update the pm_qos_add_request callers to the generic API
> 
> 7. Minor clean-ups and rename of struct fields
> 
> Questions:
> 1. How to retrieve the device ptr from a given device driver in order to add
> a constraint on it?
> 2. The device struct has recently been extended with the power domain
> information. Can this be used to apply the constraints on power domains?

Yes, it can in principle, but that will require some work.

> On-going developments, patches in preparation:
> 1. write Documentation for the new PM QoS class

I'd wait with that until the code has settled.

> 2. validate the constraints framework on OMAP4 HW (done on OMAP3)
> 3. refine the power domains wake-up latency and the cpuidle figures
> 
> Based on the master branch of the linux-omap git tree (3.0.0-rc3). Compile
> tested using OMAP and x86 generic defconfigs.
> Tested on OMAP3 Beagleboard (ES2.x) with full RETention and OFF modes.

More detailed comments will follow.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 01/11] PM: add a per-device wake-up latency constraints plist
  2011-06-30 15:11 ` jean.pihet
  2011-07-02 19:39   ` Rafael J. Wysocki
@ 2011-07-02 19:39   ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-07-02 19:39 UTC (permalink / raw)
  To: jean.pihet; +Cc: markgross, Linux PM mailing list, linux-omap, Jean Pihet

Hi,

On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
> From: Jean Pihet <j-pihet@ti.com>
> 
> Add the field wakeup_lat_plist_head in the struct dev_pm_info
> and the initialization of the plist in device_pm_init.
> 
> This enables the implementation of per-device constraints in
> PM QoS.
> 
> Signed-off-by: Jean Pihet <j-pihet@ti.com>
> ---
>  drivers/base/power/main.c |    3 +++
>  include/linux/pm.h        |    2 ++
>  2 files changed, 5 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
> index aa632020..b1fd96b 100644
> --- a/drivers/base/power/main.c
> +++ b/drivers/base/power/main.c
> @@ -96,6 +96,8 @@ void device_pm_add(struct device *dev)
>  			dev_name(dev->parent));
>  	list_add_tail(&dev->power.entry, &dpm_list);
>  	mutex_unlock(&dpm_list_mtx);
> +	/* ToDo: call PM QoS to init the per-device wakeup latency constraints */
> +	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
>  }
>  
>  /**
> @@ -106,6 +108,7 @@ void device_pm_remove(struct device *dev)
>  {
>  	pr_debug("PM: Removing info for %s:%s\n",
>  		 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
> +	/* ToDo: call PM QoS to de-init the per-device wakeup latency constraints */
>  	complete_all(&dev->power.completion);
>  	mutex_lock(&dpm_list_mtx);
>  	list_del_init(&dev->power.entry);
> diff --git a/include/linux/pm.h b/include/linux/pm.h
> index 3160648..35fe682 100644
> --- a/include/linux/pm.h
> +++ b/include/linux/pm.h
> @@ -22,6 +22,7 @@
>  #define _LINUX_PM_H
>  
>  #include <linux/list.h>
> +#include <linux/plist.h>
>  #include <linux/workqueue.h>
>  #include <linux/spinlock.h>
>  #include <linux/wait.h>
> @@ -462,6 +463,7 @@ struct dev_pm_info {
>  	unsigned long		accounting_timestamp;
>  	void			*subsys_data;  /* Owned by the subsystem. */
>  #endif
> +	struct plist_head	wakeup_lat_plist_head;
>  };

Please use a better name.  I mean, relly, the type implies that this is a
plist head, so that doesn't need to appear in the field name too.  Also,
the name is confusing, because "wakeup" may mean a couple of different things
and it's not entirely clear what "lat" stands for.  So, I'd prefer something
like

+	struct plist_head	latency_constraints;

or perhaps you can invent something even better.

>  
>  extern void update_pm_runtime_accounting(struct device *dev);
> 

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 01/11] PM: add a per-device wake-up latency constraints plist
  2011-06-30 15:11 ` jean.pihet
@ 2011-07-02 19:39   ` Rafael J. Wysocki
  2011-07-20  8:57     ` Jean Pihet
  2011-07-20  8:57     ` Jean Pihet
  2011-07-02 19:39   ` Rafael J. Wysocki
  1 sibling, 2 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-07-02 19:39 UTC (permalink / raw)
  To: jean.pihet
  Cc: Paul Walmsley, Kevin Hilman, Magnus Damm, Linux PM mailing list,
	linux-omap, markgross, Jean Pihet

Hi,

On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
> From: Jean Pihet <j-pihet@ti.com>
> 
> Add the field wakeup_lat_plist_head in the struct dev_pm_info
> and the initialization of the plist in device_pm_init.
> 
> This enables the implementation of per-device constraints in
> PM QoS.
> 
> Signed-off-by: Jean Pihet <j-pihet@ti.com>
> ---
>  drivers/base/power/main.c |    3 +++
>  include/linux/pm.h        |    2 ++
>  2 files changed, 5 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
> index aa632020..b1fd96b 100644
> --- a/drivers/base/power/main.c
> +++ b/drivers/base/power/main.c
> @@ -96,6 +96,8 @@ void device_pm_add(struct device *dev)
>  			dev_name(dev->parent));
>  	list_add_tail(&dev->power.entry, &dpm_list);
>  	mutex_unlock(&dpm_list_mtx);
> +	/* ToDo: call PM QoS to init the per-device wakeup latency constraints */
> +	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
>  }
>  
>  /**
> @@ -106,6 +108,7 @@ void device_pm_remove(struct device *dev)
>  {
>  	pr_debug("PM: Removing info for %s:%s\n",
>  		 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
> +	/* ToDo: call PM QoS to de-init the per-device wakeup latency constraints */
>  	complete_all(&dev->power.completion);
>  	mutex_lock(&dpm_list_mtx);
>  	list_del_init(&dev->power.entry);
> diff --git a/include/linux/pm.h b/include/linux/pm.h
> index 3160648..35fe682 100644
> --- a/include/linux/pm.h
> +++ b/include/linux/pm.h
> @@ -22,6 +22,7 @@
>  #define _LINUX_PM_H
>  
>  #include <linux/list.h>
> +#include <linux/plist.h>
>  #include <linux/workqueue.h>
>  #include <linux/spinlock.h>
>  #include <linux/wait.h>
> @@ -462,6 +463,7 @@ struct dev_pm_info {
>  	unsigned long		accounting_timestamp;
>  	void			*subsys_data;  /* Owned by the subsystem. */
>  #endif
> +	struct plist_head	wakeup_lat_plist_head;
>  };

Please use a better name.  I mean, relly, the type implies that this is a
plist head, so that doesn't need to appear in the field name too.  Also,
the name is confusing, because "wakeup" may mean a couple of different things
and it's not entirely clear what "lat" stands for.  So, I'd prefer something
like

+	struct plist_head	latency_constraints;

or perhaps you can invent something even better.

>  
>  extern void update_pm_runtime_accounting(struct device *dev);
> 

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-06-30 15:11 ` jean.pihet
  2011-07-02 21:10   ` Rafael J. Wysocki
@ 2011-07-02 21:10   ` Rafael J. Wysocki
  2011-08-26  2:25   ` MyungJoo Ham
  2011-08-26  2:25   ` [linux-pm] " MyungJoo Ham
  3 siblings, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-07-02 21:10 UTC (permalink / raw)
  To: jean.pihet; +Cc: markgross, Linux PM mailing list, linux-omap, Jean Pihet

Hi,

On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
> From: Jean Pihet <j-pihet@ti.com>
> 
> - add a new PM QoS class PM_QOS_DEV_WAKEUP_LATENCY for device wake-up
> constraints. Due to the per-device nature of the new class the constraints
> list is stored inside the device dev_pm_info struct instead of the internal
> per-class constraints lists.

I think PM_QOS_DEV_LATENCY might be a better name.

> The new class is only available from kernel drivers and so is not exported
> to user space.

It should be available to user space, however, because in many cases drivers
simply have no idea what values to use (after all, the use decides if he
wants to trade worse video playback quality for better battery life, for
example).

> The new class is used to put constraints on given devices in the system
> while the existing PM_QOS_CPU_DMA_LATENCY class is used by cpuidle to
> determine the next MPU subsystem state.
> 
> - make the pm_qos_add_request API more generic by using a struct
> pm_qos_parameters parameter
> 
> - the notification mechanism now passes the constraint request struct ptr
> in order for the notifier callback to have access to the full set of
> constraint data, e.g. the struct device ptr
> 
> - update the pm_qos_add_request callers to the generic API
> 
> - minor clean-ups and rename of struct fields
> 
> Signed-off-by: Jean Pihet <j-pihet@ti.com>

Well, I think this patch attempts to do too many things at a time, which
makes it somewhat hard to comprehend at first glance.  I'd stronly suggest
splitting it into a series of patches that first modify the existing API
to make it suitable for the "real" changes and second introduce those
"real" chages in the most straightforward way possible.

> ---
>  arch/arm/plat-omap/i2c.c               |   20 ----
>  drivers/i2c/busses/i2c-omap.c          |   35 ++++---
>  drivers/media/video/via-camera.c       |    5 +-
>  drivers/net/e1000e/netdev.c            |    9 +-
>  drivers/net/wireless/ipw2x00/ipw2100.c |    6 +-
>  include/linux/pm_qos_params.h          |   40 +++++---
>  kernel/pm_qos_params.c                 |  185 +++++++++++++++++++-------------

Hmm.  If you're at it, what about moving pm_qos_params.c to kernel/power
and changing its name to pm_qos.c beforehand?

The header might be called pm_qos.h too, BTW.

>  sound/core/pcm_native.c                |    8 +-
>  8 files changed, 177 insertions(+), 131 deletions(-)
> 
...
> diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
> index a7d87f9..e6e16cb 100644
> --- a/include/linux/pm_qos_params.h
> +++ b/include/linux/pm_qos_params.h
> @@ -8,31 +8,41 @@
>  #include <linux/notifier.h>
>  #include <linux/miscdevice.h>
>  
> -#define PM_QOS_RESERVED 0
> -#define PM_QOS_CPU_DMA_LATENCY 1
> -#define PM_QOS_NETWORK_LATENCY 2
> -#define PM_QOS_NETWORK_THROUGHPUT 3
> +#define	PM_QOS_RESERVED			0
> +#define	PM_QOS_CPU_DMA_LATENCY		1
> +#define	PM_QOS_DEV_WAKEUP_LATENCY	2
> +#define	PM_QOS_NETWORK_LATENCY		3
> +#define	PM_QOS_NETWORK_THROUGHPUT	4
>  
> -#define PM_QOS_NUM_CLASSES 4
> -#define PM_QOS_DEFAULT_VALUE -1
> +#define PM_QOS_NUM_CLASSES		5
> +#define PM_QOS_DEFAULT_VALUE		-1
>  
> -#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
> -#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
> -#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE	0
> +#define	PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
> +#define	PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE	0
> +#define	PM_QOS_NETWORK_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
> +#define	PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE	0
>  
>  struct pm_qos_request_list {
>  	struct plist_node list;
> -	int pm_qos_class;
> +	int class;
> +	struct device *dev;
>  };
>  
> -void pm_qos_add_request(struct pm_qos_request_list *l, int pm_qos_class, s32 value);
> +struct pm_qos_parameters {
> +	int class;
> +	struct device *dev;
> +	s32 value;
> +};
> +
> +void pm_qos_add_request(struct pm_qos_request_list *l,
> +			struct pm_qos_parameters *params);
>  void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
> -		s32 new_value);
> +			   s32 new_value);
>  void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
>  
> -int pm_qos_request(int pm_qos_class);
> -int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
> -int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
> +int pm_qos_request(int class);
> +int pm_qos_add_notifier(int class, struct notifier_block *notifier);
> +int pm_qos_remove_notifier(int class, struct notifier_block *notifier);
>  int pm_qos_request_active(struct pm_qos_request_list *req);
>  
>  #endif
> diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
> index 6824ca7..d61c8e5 100644
> --- a/kernel/pm_qos_params.c
> +++ b/kernel/pm_qos_params.c
> @@ -60,7 +60,7 @@ enum pm_qos_type {
>   * types linux supports for 32 bit quantites
>   */
>  struct pm_qos_object {
> -	struct plist_head requests;
> +	struct plist_head *requests;
>  	struct blocking_notifier_head *notifiers;
>  	struct miscdevice pm_qos_power_miscdev;
>  	char *name;

So, I gather the idea is to have "requests" point to the device's private
list of latency constraints.  [BTW, there seems to be a naming confusion,
because you tend to call those things "constraints" rather that "requests".]
If so, doesn't that mean we'll need a per-device struct pm_qos_object too?
In which case why not to make the device object point to that pm_qos_object
object instead?

> @@ -72,9 +72,12 @@ struct pm_qos_object {
>  static DEFINE_SPINLOCK(pm_qos_lock);
>  
>  static struct pm_qos_object null_pm_qos;
> +
>  static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier);
> +static struct plist_head _cpu_dma_reqs =
> +			PLIST_HEAD_INIT(_cpu_dma_reqs, pm_qos_lock);
>  static struct pm_qos_object cpu_dma_pm_qos = {
> -	.requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock),
> +	.requests = &_cpu_dma_reqs,
>  	.notifiers = &cpu_dma_lat_notifier,
>  	.name = "cpu_dma_latency",
>  	.target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
> @@ -82,9 +85,20 @@ static struct pm_qos_object cpu_dma_pm_qos = {
>  	.type = PM_QOS_MIN,
>  };
>  
> +static BLOCKING_NOTIFIER_HEAD(dev_wakeup_lat_notifier);
> +static struct pm_qos_object dev_wakeup_lat_pm_qos = {
> +	.notifiers = &dev_wakeup_lat_notifier,
> +	.name = "dev_wakeup_latency",
> +	.target_value = PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE,
> +	.default_value = PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE,
> +	.type = PM_QOS_MIN,
> +};
> +
>  static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
> +static struct plist_head _network_lat_reqs =
> +			PLIST_HEAD_INIT(_network_lat_reqs, pm_qos_lock);
>  static struct pm_qos_object network_lat_pm_qos = {
> -	.requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock),
> +	.requests = &_network_lat_reqs,
>  	.notifiers = &network_lat_notifier,
>  	.name = "network_latency",
>  	.target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
> @@ -94,8 +108,10 @@ static struct pm_qos_object network_lat_pm_qos = {
>  
>  
>  static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier);
> +static struct plist_head _network_throughput_reqs =
> +			PLIST_HEAD_INIT(_network_throughput_reqs, pm_qos_lock);
>  static struct pm_qos_object network_throughput_pm_qos = {
> -	.requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock),
> +	.requests = &_network_throughput_reqs,
>  	.notifiers = &network_throughput_notifier,
>  	.name = "network_throughput",
>  	.target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
> @@ -107,6 +123,7 @@ static struct pm_qos_object network_throughput_pm_qos = {
>  static struct pm_qos_object *pm_qos_array[] = {
>  	&null_pm_qos,
>  	&cpu_dma_pm_qos,
> +	&dev_wakeup_lat_pm_qos,
>  	&network_lat_pm_qos,
>  	&network_throughput_pm_qos
>  };
> @@ -129,19 +146,19 @@ static const struct file_operations pm_qos_power_fops = {
>  /* unlocked internal variant */
>  static inline int pm_qos_get_value(struct pm_qos_object *o)
>  {
> -	if (plist_head_empty(&o->requests))
> +	if (plist_head_empty(o->requests))
>  		return o->default_value;
>  
>  	switch (o->type) {
> -	case PM_QOS_MIN:
> -		return plist_first(&o->requests)->prio;
> +		case PM_QOS_MIN:
> +			return plist_first(o->requests)->prio;
>  
> -	case PM_QOS_MAX:
> -		return plist_last(&o->requests)->prio;
> +		case PM_QOS_MAX:
> +			return plist_last(o->requests)->prio;
>  
> -	default:
> -		/* runtime check for not using enum */
> -		BUG();
> +		default:
> +			/* runtime check for not using enum */
> +			BUG();
>  	}
>  }
>  
> @@ -155,13 +172,22 @@ static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value)
>  	o->target_value = value;
>  }
>  
> -static void update_target(struct pm_qos_object *o, struct plist_node *node,
> -			  int del, int value)
> +static void update_target(struct pm_qos_request_list *req, int del, int value)
>  {
>  	unsigned long flags;
>  	int prev_value, curr_value;
> +	struct pm_qos_object *o = pm_qos_array[req->class];
> +	struct plist_node *node = &req->list;
>  
>  	spin_lock_irqsave(&pm_qos_lock, flags);
> +	/*
> +	 * PM_QOS_DEV_WAKEUP_LATENCY:
> +	 * Use the per-device wake-up latency constraints list for
> +	 * constraints storage
> +	 */
> +	if (req->class == PM_QOS_DEV_WAKEUP_LATENCY)
> +		o->requests = &req->dev->power.wakeup_lat_plist_head;

Ah, I see what the idea is and quite frankly I don't like it.

Changing the requests field on the fly in every second (or so) invocation of
update_target() for PM_QOS_DEV_WAKEUP_LATENCY class is beyond ugly.  Moreover,
it makes all devices share the default_value field which I don't think is
correct (the target_value field is shared too, which may lead to all sorts of
problems).

I wouldn't even try to use struct pm_qos_object as it is.  Instead, I'd
introduce something like

struct pm_qos_constraits {
	struct plist_head requests;
	unsigned int current_val;
	unsigned int default_val;
	unsigned int floor_val;  /* for adding new requests */
	unsigned int ceiling_val;  /* ditto */
	enum pm_qos_type type;
};

Where I'm not sure if the "type" field is really necessary, but that should
work out at one point and "unsigned int" is on purpose (it should have been
that way from day one in the first place).  That's what is needed for device
IMO, the other fields in struct pm_qos_object are simply redundant for this
use case.

Now, for the compatibility with the existing code I'd redefine struct
pm_qos_object as:

struct pm_qos_object {
	struct pm_qos_constraints constraints;
	struct blocking_notifier *notifiers;
	struct miscdevice pm_qos_power_miscdev;
	char *name;
};

and I'd change the code to operate on struct pm_qos_constraits in the first
place, with a compatibility layer using struct pm_qos_object on top of that.

Then, each device may have its own struct pm_qos_constraits object that will
be operated on by the PM QoS functions.  [There is the problem of whether or
not those object should be embedded in struct dev_pm_info, it may be better
to use pointers to them.  That may be used for sharing of constraints, for
example, in which case it will be necessary to add a refcount to struct
pm_qos_constraits.]

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-06-30 15:11 ` jean.pihet
@ 2011-07-02 21:10   ` Rafael J. Wysocki
  2011-07-20  9:13     ` Jean Pihet
                       ` (3 more replies)
  2011-07-02 21:10   ` Rafael J. Wysocki
                     ` (2 subsequent siblings)
  3 siblings, 4 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-07-02 21:10 UTC (permalink / raw)
  To: jean.pihet
  Cc: Paul Walmsley, Kevin Hilman, Magnus Damm, Linux PM mailing list,
	linux-omap, markgross, Jean Pihet

Hi,

On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
> From: Jean Pihet <j-pihet@ti.com>
> 
> - add a new PM QoS class PM_QOS_DEV_WAKEUP_LATENCY for device wake-up
> constraints. Due to the per-device nature of the new class the constraints
> list is stored inside the device dev_pm_info struct instead of the internal
> per-class constraints lists.

I think PM_QOS_DEV_LATENCY might be a better name.

> The new class is only available from kernel drivers and so is not exported
> to user space.

It should be available to user space, however, because in many cases drivers
simply have no idea what values to use (after all, the use decides if he
wants to trade worse video playback quality for better battery life, for
example).

> The new class is used to put constraints on given devices in the system
> while the existing PM_QOS_CPU_DMA_LATENCY class is used by cpuidle to
> determine the next MPU subsystem state.
> 
> - make the pm_qos_add_request API more generic by using a struct
> pm_qos_parameters parameter
> 
> - the notification mechanism now passes the constraint request struct ptr
> in order for the notifier callback to have access to the full set of
> constraint data, e.g. the struct device ptr
> 
> - update the pm_qos_add_request callers to the generic API
> 
> - minor clean-ups and rename of struct fields
> 
> Signed-off-by: Jean Pihet <j-pihet@ti.com>

Well, I think this patch attempts to do too many things at a time, which
makes it somewhat hard to comprehend at first glance.  I'd stronly suggest
splitting it into a series of patches that first modify the existing API
to make it suitable for the "real" changes and second introduce those
"real" chages in the most straightforward way possible.

> ---
>  arch/arm/plat-omap/i2c.c               |   20 ----
>  drivers/i2c/busses/i2c-omap.c          |   35 ++++---
>  drivers/media/video/via-camera.c       |    5 +-
>  drivers/net/e1000e/netdev.c            |    9 +-
>  drivers/net/wireless/ipw2x00/ipw2100.c |    6 +-
>  include/linux/pm_qos_params.h          |   40 +++++---
>  kernel/pm_qos_params.c                 |  185 +++++++++++++++++++-------------

Hmm.  If you're at it, what about moving pm_qos_params.c to kernel/power
and changing its name to pm_qos.c beforehand?

The header might be called pm_qos.h too, BTW.

>  sound/core/pcm_native.c                |    8 +-
>  8 files changed, 177 insertions(+), 131 deletions(-)
> 
...
> diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
> index a7d87f9..e6e16cb 100644
> --- a/include/linux/pm_qos_params.h
> +++ b/include/linux/pm_qos_params.h
> @@ -8,31 +8,41 @@
>  #include <linux/notifier.h>
>  #include <linux/miscdevice.h>
>  
> -#define PM_QOS_RESERVED 0
> -#define PM_QOS_CPU_DMA_LATENCY 1
> -#define PM_QOS_NETWORK_LATENCY 2
> -#define PM_QOS_NETWORK_THROUGHPUT 3
> +#define	PM_QOS_RESERVED			0
> +#define	PM_QOS_CPU_DMA_LATENCY		1
> +#define	PM_QOS_DEV_WAKEUP_LATENCY	2
> +#define	PM_QOS_NETWORK_LATENCY		3
> +#define	PM_QOS_NETWORK_THROUGHPUT	4
>  
> -#define PM_QOS_NUM_CLASSES 4
> -#define PM_QOS_DEFAULT_VALUE -1
> +#define PM_QOS_NUM_CLASSES		5
> +#define PM_QOS_DEFAULT_VALUE		-1
>  
> -#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
> -#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
> -#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE	0
> +#define	PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
> +#define	PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE	0
> +#define	PM_QOS_NETWORK_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
> +#define	PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE	0
>  
>  struct pm_qos_request_list {
>  	struct plist_node list;
> -	int pm_qos_class;
> +	int class;
> +	struct device *dev;
>  };
>  
> -void pm_qos_add_request(struct pm_qos_request_list *l, int pm_qos_class, s32 value);
> +struct pm_qos_parameters {
> +	int class;
> +	struct device *dev;
> +	s32 value;
> +};
> +
> +void pm_qos_add_request(struct pm_qos_request_list *l,
> +			struct pm_qos_parameters *params);
>  void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
> -		s32 new_value);
> +			   s32 new_value);
>  void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
>  
> -int pm_qos_request(int pm_qos_class);
> -int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
> -int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
> +int pm_qos_request(int class);
> +int pm_qos_add_notifier(int class, struct notifier_block *notifier);
> +int pm_qos_remove_notifier(int class, struct notifier_block *notifier);
>  int pm_qos_request_active(struct pm_qos_request_list *req);
>  
>  #endif
> diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
> index 6824ca7..d61c8e5 100644
> --- a/kernel/pm_qos_params.c
> +++ b/kernel/pm_qos_params.c
> @@ -60,7 +60,7 @@ enum pm_qos_type {
>   * types linux supports for 32 bit quantites
>   */
>  struct pm_qos_object {
> -	struct plist_head requests;
> +	struct plist_head *requests;
>  	struct blocking_notifier_head *notifiers;
>  	struct miscdevice pm_qos_power_miscdev;
>  	char *name;

So, I gather the idea is to have "requests" point to the device's private
list of latency constraints.  [BTW, there seems to be a naming confusion,
because you tend to call those things "constraints" rather that "requests".]
If so, doesn't that mean we'll need a per-device struct pm_qos_object too?
In which case why not to make the device object point to that pm_qos_object
object instead?

> @@ -72,9 +72,12 @@ struct pm_qos_object {
>  static DEFINE_SPINLOCK(pm_qos_lock);
>  
>  static struct pm_qos_object null_pm_qos;
> +
>  static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier);
> +static struct plist_head _cpu_dma_reqs =
> +			PLIST_HEAD_INIT(_cpu_dma_reqs, pm_qos_lock);
>  static struct pm_qos_object cpu_dma_pm_qos = {
> -	.requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock),
> +	.requests = &_cpu_dma_reqs,
>  	.notifiers = &cpu_dma_lat_notifier,
>  	.name = "cpu_dma_latency",
>  	.target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
> @@ -82,9 +85,20 @@ static struct pm_qos_object cpu_dma_pm_qos = {
>  	.type = PM_QOS_MIN,
>  };
>  
> +static BLOCKING_NOTIFIER_HEAD(dev_wakeup_lat_notifier);
> +static struct pm_qos_object dev_wakeup_lat_pm_qos = {
> +	.notifiers = &dev_wakeup_lat_notifier,
> +	.name = "dev_wakeup_latency",
> +	.target_value = PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE,
> +	.default_value = PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE,
> +	.type = PM_QOS_MIN,
> +};
> +
>  static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
> +static struct plist_head _network_lat_reqs =
> +			PLIST_HEAD_INIT(_network_lat_reqs, pm_qos_lock);
>  static struct pm_qos_object network_lat_pm_qos = {
> -	.requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock),
> +	.requests = &_network_lat_reqs,
>  	.notifiers = &network_lat_notifier,
>  	.name = "network_latency",
>  	.target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
> @@ -94,8 +108,10 @@ static struct pm_qos_object network_lat_pm_qos = {
>  
>  
>  static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier);
> +static struct plist_head _network_throughput_reqs =
> +			PLIST_HEAD_INIT(_network_throughput_reqs, pm_qos_lock);
>  static struct pm_qos_object network_throughput_pm_qos = {
> -	.requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock),
> +	.requests = &_network_throughput_reqs,
>  	.notifiers = &network_throughput_notifier,
>  	.name = "network_throughput",
>  	.target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
> @@ -107,6 +123,7 @@ static struct pm_qos_object network_throughput_pm_qos = {
>  static struct pm_qos_object *pm_qos_array[] = {
>  	&null_pm_qos,
>  	&cpu_dma_pm_qos,
> +	&dev_wakeup_lat_pm_qos,
>  	&network_lat_pm_qos,
>  	&network_throughput_pm_qos
>  };
> @@ -129,19 +146,19 @@ static const struct file_operations pm_qos_power_fops = {
>  /* unlocked internal variant */
>  static inline int pm_qos_get_value(struct pm_qos_object *o)
>  {
> -	if (plist_head_empty(&o->requests))
> +	if (plist_head_empty(o->requests))
>  		return o->default_value;
>  
>  	switch (o->type) {
> -	case PM_QOS_MIN:
> -		return plist_first(&o->requests)->prio;
> +		case PM_QOS_MIN:
> +			return plist_first(o->requests)->prio;
>  
> -	case PM_QOS_MAX:
> -		return plist_last(&o->requests)->prio;
> +		case PM_QOS_MAX:
> +			return plist_last(o->requests)->prio;
>  
> -	default:
> -		/* runtime check for not using enum */
> -		BUG();
> +		default:
> +			/* runtime check for not using enum */
> +			BUG();
>  	}
>  }
>  
> @@ -155,13 +172,22 @@ static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value)
>  	o->target_value = value;
>  }
>  
> -static void update_target(struct pm_qos_object *o, struct plist_node *node,
> -			  int del, int value)
> +static void update_target(struct pm_qos_request_list *req, int del, int value)
>  {
>  	unsigned long flags;
>  	int prev_value, curr_value;
> +	struct pm_qos_object *o = pm_qos_array[req->class];
> +	struct plist_node *node = &req->list;
>  
>  	spin_lock_irqsave(&pm_qos_lock, flags);
> +	/*
> +	 * PM_QOS_DEV_WAKEUP_LATENCY:
> +	 * Use the per-device wake-up latency constraints list for
> +	 * constraints storage
> +	 */
> +	if (req->class == PM_QOS_DEV_WAKEUP_LATENCY)
> +		o->requests = &req->dev->power.wakeup_lat_plist_head;

Ah, I see what the idea is and quite frankly I don't like it.

Changing the requests field on the fly in every second (or so) invocation of
update_target() for PM_QOS_DEV_WAKEUP_LATENCY class is beyond ugly.  Moreover,
it makes all devices share the default_value field which I don't think is
correct (the target_value field is shared too, which may lead to all sorts of
problems).

I wouldn't even try to use struct pm_qos_object as it is.  Instead, I'd
introduce something like

struct pm_qos_constraits {
	struct plist_head requests;
	unsigned int current_val;
	unsigned int default_val;
	unsigned int floor_val;  /* for adding new requests */
	unsigned int ceiling_val;  /* ditto */
	enum pm_qos_type type;
};

Where I'm not sure if the "type" field is really necessary, but that should
work out at one point and "unsigned int" is on purpose (it should have been
that way from day one in the first place).  That's what is needed for device
IMO, the other fields in struct pm_qos_object are simply redundant for this
use case.

Now, for the compatibility with the existing code I'd redefine struct
pm_qos_object as:

struct pm_qos_object {
	struct pm_qos_constraints constraints;
	struct blocking_notifier *notifiers;
	struct miscdevice pm_qos_power_miscdev;
	char *name;
};

and I'd change the code to operate on struct pm_qos_constraits in the first
place, with a compatibility layer using struct pm_qos_object on top of that.

Then, each device may have its own struct pm_qos_constraits object that will
be operated on by the PM QoS functions.  [There is the problem of whether or
not those object should be embedded in struct dev_pm_info, it may be better
to use pointers to them.  That may be used for sharing of constraints, for
example, in which case it will be necessary to add a refcount to struct
pm_qos_constraits.]

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 03/11] PM QoS: support the dynamic devices insertion and removal
  2011-06-30 15:11 ` [PATCH 03/11] PM QoS: support the dynamic devices insertion and removal jean.pihet
@ 2011-07-02 21:14   ` Rafael J. Wysocki
  2011-07-02 21:14   ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-07-02 21:14 UTC (permalink / raw)
  To: jean.pihet; +Cc: markgross, Linux PM mailing list, linux-omap, Jean Pihet

Hi,

On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
> From: Jean Pihet <j-pihet@ti.com>
> 
> The devices wake-up latency constraints class of PM QoS is
> storing the constraints list using the device pm_info struct.
> 
> This patch adds the init and de-init of the per-device constraints
> list in order to support the dynamic insertion and removal
> of the devices in the system.
> 
> Signed-off-by: Jean Pihet <j-pihet@ti.com>

The number of times this patch special cases PM_QOS_DEV_WAKEUP_LATENCY with
respect to the other PM QoS classes indicates a design issue, which kind of
corresponds with my comments on [3/11].

Thanks,
Rafael


> ---
>  drivers/base/power/main.c     |    8 +++--
>  include/linux/pm.h            |    1 +
>  include/linux/pm_qos_params.h |    2 +
>  kernel/pm_qos_params.c        |   70 ++++++++++++++++++++++++++++++++--------
>  4 files changed, 64 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
> index b1fd96b..51f5526 100644
> --- a/drivers/base/power/main.c
> +++ b/drivers/base/power/main.c
> @@ -27,6 +27,7 @@
>  #include <linux/sched.h>
>  #include <linux/async.h>
>  #include <linux/suspend.h>
> +#include <linux/pm_qos_params.h>
>  
>  #include "../base.h"
>  #include "power.h"
> @@ -96,8 +97,8 @@ void device_pm_add(struct device *dev)
>  			dev_name(dev->parent));
>  	list_add_tail(&dev->power.entry, &dpm_list);
>  	mutex_unlock(&dpm_list_mtx);
> -	/* ToDo: call PM QoS to init the per-device wakeup latency constraints */
> -	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
> +	/* Call PM QoS to init the per-device wakeup latency constraints */
> +	pm_qos_dev_wakeup_lat_init(dev);
>  }
>  
>  /**
> @@ -108,7 +109,8 @@ void device_pm_remove(struct device *dev)
>  {
>  	pr_debug("PM: Removing info for %s:%s\n",
>  		 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
> -	/* ToDo: call PM QoS to de-init the per-device wakeup latency constraints */
> +	/* Call PM QoS to de-init the per-device wakeup latency constraints */
> +	pm_qos_dev_wakeup_lat_deinit(dev);
>  	complete_all(&dev->power.completion);
>  	mutex_lock(&dpm_list_mtx);
>  	list_del_init(&dev->power.entry);
> diff --git a/include/linux/pm.h b/include/linux/pm.h
> index 35fe682..d9b6092 100644
> --- a/include/linux/pm.h
> +++ b/include/linux/pm.h
> @@ -464,6 +464,7 @@ struct dev_pm_info {
>  	void			*subsys_data;  /* Owned by the subsystem. */
>  #endif
>  	struct plist_head	wakeup_lat_plist_head;
> +	int			wakeup_lat_init;
>  };
>  
>  extern void update_pm_runtime_accounting(struct device *dev);
> diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
> index e6e16cb..5b6707a 100644
> --- a/include/linux/pm_qos_params.h
> +++ b/include/linux/pm_qos_params.h
> @@ -45,4 +45,6 @@ int pm_qos_add_notifier(int class, struct notifier_block *notifier);
>  int pm_qos_remove_notifier(int class, struct notifier_block *notifier);
>  int pm_qos_request_active(struct pm_qos_request_list *req);
>  
> +void pm_qos_dev_wakeup_lat_init(struct device *dev);
> +void pm_qos_dev_wakeup_lat_deinit(struct device *dev);
>  #endif
> diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
> index d61c8e5..6f25ccb 100644
> --- a/kernel/pm_qos_params.c
> +++ b/kernel/pm_qos_params.c
> @@ -275,11 +275,21 @@ void pm_qos_add_request(struct pm_qos_request_list *pm_qos_req,
>  	struct pm_qos_object *o =  pm_qos_array[pm_qos_params->class];
>  	int new_value;
>  
> -	if ((pm_qos_params->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
> -	    (pm_qos_request_active(pm_qos_req))) {
> -		WARN(1, KERN_ERR "pm_qos_add_request() called for already "
> -		     "added request\n");
> -		return;
> +	if (pm_qos_params->class == PM_QOS_DEV_WAKEUP_LATENCY) {
> +		if (!pm_qos_params->dev) {
> +			WARN(1, KERN_ERR "pm_qos_add_request() called for "
> +				"invalid device\n");
> +			return;
> +		}
> +		/* Silently return if the device is being released */
> +		if (!pm_qos_params->dev->power.wakeup_lat_init)
> +			return;
> +	} else {
> +		if (pm_qos_request_active(pm_qos_req)) {
> +			WARN(1, KERN_ERR "pm_qos_add_request() called for "
> +				"already added request\n");
> +			return;
> +		}
>  	}
>  
>  	if (pm_qos_params->value == PM_QOS_DEFAULT_VALUE)
> @@ -312,11 +322,16 @@ void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
>  	if (!pm_qos_req) /*guard against callers passing in null */
>  		return;
>  
> -	if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
> -	    (!pm_qos_request_active(pm_qos_req))) {
> -		WARN(1, KERN_ERR "pm_qos_update_request() called for unknown "
> -		     "object\n");
> -		return;
> +	if (pm_qos_req->class == PM_QOS_DEV_WAKEUP_LATENCY) {
> +		/* Silently return if the device is being released */
> +		if (!pm_qos_req->dev->power.wakeup_lat_init)
> +			return;
> +	} else {
> +		if (!pm_qos_request_active(pm_qos_req)) {
> +			WARN(1, KERN_ERR "pm_qos_update_request() called "
> +				"for unknown object\n");
> +			return;
> +		}
>  	}
>  
>  	if (new_value == PM_QOS_DEFAULT_VALUE)
> @@ -343,11 +358,16 @@ void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req)
>  		return;
>  		/* silent return to keep pcm code cleaner */
>  
> -	if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
> -	    (!pm_qos_request_active(pm_qos_req))) {
> -		WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown "
> -		     "object\n");
> +	if (pm_qos_req->class == PM_QOS_DEV_WAKEUP_LATENCY) {
> +		/* Silently return if the device is being released */
> +		if (!pm_qos_req->dev->power.wakeup_lat_init)
> +			return;
> +	} else {
> +		if (!pm_qos_request_active(pm_qos_req)) {
> +			WARN(1, KERN_ERR "pm_qos_remove_request() called "
> +				"for unknown object\n");
>  		return;
> +		}
>  	}
>  
>  	update_target(pm_qos_req, 1, PM_QOS_DEFAULT_VALUE);
> @@ -393,6 +413,28 @@ int pm_qos_remove_notifier(int class, struct notifier_block *notifier)
>  }
>  EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
>  
> +/* Called from the device PM subsystem at device init */
> +void pm_qos_dev_wakeup_lat_init(struct device *dev)
> +{
> +	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
> +	dev->power.wakeup_lat_init = 1;
> +}
> +
> +/* Called from the device PM subsystem at device release */
> +void pm_qos_dev_wakeup_lat_deinit(struct device *dev)
> +{
> +	struct pm_qos_request_list *req, *tmp;
> +
> +	dev->power.wakeup_lat_init = 0;
> +
> +	/* Flush the constraints list for the device */
> +	plist_for_each_entry_safe(req, tmp,
> +				  &dev->power.wakeup_lat_plist_head,
> +				  list)
> +		update_target(req, 1, PM_QOS_DEFAULT_VALUE);
> +	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
> +}
> +
>  static int pm_qos_power_open(struct inode *inode, struct file *filp)
>  {
>  	struct pm_qos_parameters pm_qos_params;
> 

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 03/11] PM QoS: support the dynamic devices insertion and removal
  2011-06-30 15:11 ` [PATCH 03/11] PM QoS: support the dynamic devices insertion and removal jean.pihet
  2011-07-02 21:14   ` Rafael J. Wysocki
@ 2011-07-02 21:14   ` Rafael J. Wysocki
  2011-07-20  9:16     ` Jean Pihet
  2011-07-20  9:16     ` Jean Pihet
  1 sibling, 2 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-07-02 21:14 UTC (permalink / raw)
  To: jean.pihet
  Cc: Paul Walmsley, Kevin Hilman, Magnus Damm, Linux PM mailing list,
	linux-omap, markgross, Jean Pihet

Hi,

On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
> From: Jean Pihet <j-pihet@ti.com>
> 
> The devices wake-up latency constraints class of PM QoS is
> storing the constraints list using the device pm_info struct.
> 
> This patch adds the init and de-init of the per-device constraints
> list in order to support the dynamic insertion and removal
> of the devices in the system.
> 
> Signed-off-by: Jean Pihet <j-pihet@ti.com>

The number of times this patch special cases PM_QOS_DEV_WAKEUP_LATENCY with
respect to the other PM QoS classes indicates a design issue, which kind of
corresponds with my comments on [3/11].

Thanks,
Rafael


> ---
>  drivers/base/power/main.c     |    8 +++--
>  include/linux/pm.h            |    1 +
>  include/linux/pm_qos_params.h |    2 +
>  kernel/pm_qos_params.c        |   70 ++++++++++++++++++++++++++++++++--------
>  4 files changed, 64 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
> index b1fd96b..51f5526 100644
> --- a/drivers/base/power/main.c
> +++ b/drivers/base/power/main.c
> @@ -27,6 +27,7 @@
>  #include <linux/sched.h>
>  #include <linux/async.h>
>  #include <linux/suspend.h>
> +#include <linux/pm_qos_params.h>
>  
>  #include "../base.h"
>  #include "power.h"
> @@ -96,8 +97,8 @@ void device_pm_add(struct device *dev)
>  			dev_name(dev->parent));
>  	list_add_tail(&dev->power.entry, &dpm_list);
>  	mutex_unlock(&dpm_list_mtx);
> -	/* ToDo: call PM QoS to init the per-device wakeup latency constraints */
> -	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
> +	/* Call PM QoS to init the per-device wakeup latency constraints */
> +	pm_qos_dev_wakeup_lat_init(dev);
>  }
>  
>  /**
> @@ -108,7 +109,8 @@ void device_pm_remove(struct device *dev)
>  {
>  	pr_debug("PM: Removing info for %s:%s\n",
>  		 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
> -	/* ToDo: call PM QoS to de-init the per-device wakeup latency constraints */
> +	/* Call PM QoS to de-init the per-device wakeup latency constraints */
> +	pm_qos_dev_wakeup_lat_deinit(dev);
>  	complete_all(&dev->power.completion);
>  	mutex_lock(&dpm_list_mtx);
>  	list_del_init(&dev->power.entry);
> diff --git a/include/linux/pm.h b/include/linux/pm.h
> index 35fe682..d9b6092 100644
> --- a/include/linux/pm.h
> +++ b/include/linux/pm.h
> @@ -464,6 +464,7 @@ struct dev_pm_info {
>  	void			*subsys_data;  /* Owned by the subsystem. */
>  #endif
>  	struct plist_head	wakeup_lat_plist_head;
> +	int			wakeup_lat_init;
>  };
>  
>  extern void update_pm_runtime_accounting(struct device *dev);
> diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
> index e6e16cb..5b6707a 100644
> --- a/include/linux/pm_qos_params.h
> +++ b/include/linux/pm_qos_params.h
> @@ -45,4 +45,6 @@ int pm_qos_add_notifier(int class, struct notifier_block *notifier);
>  int pm_qos_remove_notifier(int class, struct notifier_block *notifier);
>  int pm_qos_request_active(struct pm_qos_request_list *req);
>  
> +void pm_qos_dev_wakeup_lat_init(struct device *dev);
> +void pm_qos_dev_wakeup_lat_deinit(struct device *dev);
>  #endif
> diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
> index d61c8e5..6f25ccb 100644
> --- a/kernel/pm_qos_params.c
> +++ b/kernel/pm_qos_params.c
> @@ -275,11 +275,21 @@ void pm_qos_add_request(struct pm_qos_request_list *pm_qos_req,
>  	struct pm_qos_object *o =  pm_qos_array[pm_qos_params->class];
>  	int new_value;
>  
> -	if ((pm_qos_params->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
> -	    (pm_qos_request_active(pm_qos_req))) {
> -		WARN(1, KERN_ERR "pm_qos_add_request() called for already "
> -		     "added request\n");
> -		return;
> +	if (pm_qos_params->class == PM_QOS_DEV_WAKEUP_LATENCY) {
> +		if (!pm_qos_params->dev) {
> +			WARN(1, KERN_ERR "pm_qos_add_request() called for "
> +				"invalid device\n");
> +			return;
> +		}
> +		/* Silently return if the device is being released */
> +		if (!pm_qos_params->dev->power.wakeup_lat_init)
> +			return;
> +	} else {
> +		if (pm_qos_request_active(pm_qos_req)) {
> +			WARN(1, KERN_ERR "pm_qos_add_request() called for "
> +				"already added request\n");
> +			return;
> +		}
>  	}
>  
>  	if (pm_qos_params->value == PM_QOS_DEFAULT_VALUE)
> @@ -312,11 +322,16 @@ void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
>  	if (!pm_qos_req) /*guard against callers passing in null */
>  		return;
>  
> -	if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
> -	    (!pm_qos_request_active(pm_qos_req))) {
> -		WARN(1, KERN_ERR "pm_qos_update_request() called for unknown "
> -		     "object\n");
> -		return;
> +	if (pm_qos_req->class == PM_QOS_DEV_WAKEUP_LATENCY) {
> +		/* Silently return if the device is being released */
> +		if (!pm_qos_req->dev->power.wakeup_lat_init)
> +			return;
> +	} else {
> +		if (!pm_qos_request_active(pm_qos_req)) {
> +			WARN(1, KERN_ERR "pm_qos_update_request() called "
> +				"for unknown object\n");
> +			return;
> +		}
>  	}
>  
>  	if (new_value == PM_QOS_DEFAULT_VALUE)
> @@ -343,11 +358,16 @@ void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req)
>  		return;
>  		/* silent return to keep pcm code cleaner */
>  
> -	if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
> -	    (!pm_qos_request_active(pm_qos_req))) {
> -		WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown "
> -		     "object\n");
> +	if (pm_qos_req->class == PM_QOS_DEV_WAKEUP_LATENCY) {
> +		/* Silently return if the device is being released */
> +		if (!pm_qos_req->dev->power.wakeup_lat_init)
> +			return;
> +	} else {
> +		if (!pm_qos_request_active(pm_qos_req)) {
> +			WARN(1, KERN_ERR "pm_qos_remove_request() called "
> +				"for unknown object\n");
>  		return;
> +		}
>  	}
>  
>  	update_target(pm_qos_req, 1, PM_QOS_DEFAULT_VALUE);
> @@ -393,6 +413,28 @@ int pm_qos_remove_notifier(int class, struct notifier_block *notifier)
>  }
>  EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
>  
> +/* Called from the device PM subsystem at device init */
> +void pm_qos_dev_wakeup_lat_init(struct device *dev)
> +{
> +	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
> +	dev->power.wakeup_lat_init = 1;
> +}
> +
> +/* Called from the device PM subsystem at device release */
> +void pm_qos_dev_wakeup_lat_deinit(struct device *dev)
> +{
> +	struct pm_qos_request_list *req, *tmp;
> +
> +	dev->power.wakeup_lat_init = 0;
> +
> +	/* Flush the constraints list for the device */
> +	plist_for_each_entry_safe(req, tmp,
> +				  &dev->power.wakeup_lat_plist_head,
> +				  list)
> +		update_target(req, 1, PM_QOS_DEFAULT_VALUE);
> +	plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
> +}
> +
>  static int pm_qos_power_open(struct inode *inode, struct file *filp)
>  {
>  	struct pm_qos_parameters pm_qos_params;
> 


^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class
  2011-07-02 19:20 ` Rafael J. Wysocki
@ 2011-07-04  7:16   ` Vishwanath Sripathy
  2011-07-04  8:38     ` Rafael J. Wysocki
  2011-07-04  8:38     ` Rafael J. Wysocki
  2011-07-20  9:26   ` Jean Pihet
  2011-07-20  9:26   ` Jean Pihet
  2 siblings, 2 replies; 122+ messages in thread
From: Vishwanath Sripathy @ 2011-07-04  7:16 UTC (permalink / raw)
  To: Rafael J. Wysocki, jean.pihet
  Cc: markgross, Linux PM mailing list, linux-omap, Jean Pihet-XID

> -----Original Message-----
> From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-
> owner@vger.kernel.org] On Behalf Of Rafael J. Wysocki
> Sent: Sunday, July 03, 2011 12:51 AM
> To: jean.pihet@newoldbits.com
> Cc: Paul Walmsley; Kevin Hilman; Magnus Damm; Linux PM mailing list;
> linux-omap@vger.kernel.org; markgross@thegnar.org; Jean Pihet
> Subject: Re: [PATCH v2 00/11] PM QoS: add a per-device wake-up
> latency constraint class
>
> Hi,
>
> On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
> > From: Jean Pihet <j-pihet@ti.com>
> >
> > This patch set is in an RFC state, for review and comments.
>
> First off, I'm sorry I couldn't review the patchset earlier.
>
> > In order to implement the new class in PM QoS the following
> changes have been
> > made:
> >
> > 1. Add a new PM QoS class for device wake-up constraints
> > (PM_QOS_DEV_WAKEUP_LATENCY).
> > Due to the per-device nature of the new class the constraints
> lists are stored
> > inside the device dev_pm_info struct instead of the internal per-
> class
> > constraints lists.
> > The new class is only available from kernel drivers and so is not
> exported to
> > user space.
>
> Have you considered a design in which multiple devices may use the
> same
> list of constraints?  It seems plausible that the constraints will
> be the
> same, for example, for all Ethernet adapters in the system, in which
> case it
> will be wasteful to duplicate the list of constraints for each of
> them.
>
> > 2. Added a notification of device insertion/removal from the
> device PM framework
> > to PM QoS.
> > This allows to init/de-init the per-device constraints list upon
> device insertion
> > and removal.
> > RFC state for comments and review, barely tested
>
> I need to have a look at the details, but in principle this means
> that the
> per-device lists will be usable only after the devices have been
> registered.
> In particular, this means that it will only be possible to add new
> constraints
> after registering the device, which may be too late for some use
> cases.
>
> > 3. Make the pm_qos_add_request API more generic by using a
> > struct pm_qos_parameters parameter. This allows easy extension in
> the future.
> >
> > 4. Upon a change of the strongest constraint in the
> PM_QOS_DEV_WAKEUP_LATENCY
> > class a notification chain mechanism is used to take action on the
> system.
> > This is the proposed way to have PM QoS and the platform dependant
> code to
> > interact with each other, cf. 4 below.
>
> I guess you mean 5.?
>
> I think we will need something in addition to the notifier here.
> For example,
> I wouldn't like any core code, like runtime PM or cpuidle, to have
> to register
> a notifier with PM QoS.
>
> > The notification mechanism now passes the constraint request
> struct ptr in
> > order for the notifier callback to have access to the full set of
> constraint
> > data, e.g. the struct device ptr.
> >
> > 5. cpuidle interaction with the OMAP3 cpuidle handler
> > Since cpuidle is a CPU centric framework it decides the MPU next
> power state
> > based on the MPU exit_latency and target_residency figures.
> >
> > The rest of the power domains get their next power state
> programmed from
> > the PM_QOS_DEV_WAKEUP_LATENCY class of the PM QoS framework, via
> the device
> > wake-up latency constraints.
> >
> > Note: the exit_latency and target_residency figures of the MPU
> include the MPU
> > itself and the peripherals needed for the MPU to execute
> instructions (e.g.
> > main memory, caches, IRQ controller, MMU etc).
> > Some of those peripherals can belong to other power domains than
> the MPU
> > subsystem and so the corresponding latencies must be included in
> those figures.
> >
> > 6. Update the pm_qos_add_request callers to the generic API
> >
> > 7. Minor clean-ups and rename of struct fields
> >
> > Questions:
> > 1. How to retrieve the device ptr from a given device driver in
> order to add
> > a constraint on it?
> > 2. The device struct has recently been extended with the power
> domain
> > information. Can this be used to apply the constraints on power
> domains?
>
> Yes, it can in principle, but that will require some work.
>
> > On-going developments, patches in preparation:
> > 1. write Documentation for the new PM QoS class
>
> I'd wait with that until the code has settled.
>
> > 2. validate the constraints framework on OMAP4 HW (done on OMAP3)
> > 3. refine the power domains wake-up latency and the cpuidle
> figures
> >
> > Based on the master branch of the linux-omap git tree (3.0.0-rc3).
> Compile
> > tested using OMAP and x86 generic defconfigs.
> > Tested on OMAP3 Beagleboard (ES2.x) with full RETention and OFF
> modes.
>
> More detailed comments will follow.
Thanks Rafael for reviewing the patches. Jean is currently on summer
vacation for 2 weeks and will take this discussion forward once he is back
to work on July 18.

Regards
Vishwa
>
> Thanks,
> Rafael
> --
> To unsubscribe from this list: send the line "unsubscribe linux-
> omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class
  2011-07-04  7:16   ` Vishwanath Sripathy
@ 2011-07-04  8:38     ` Rafael J. Wysocki
  2011-07-04  8:38     ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-07-04  8:38 UTC (permalink / raw)
  To: Vishwanath Sripathy
  Cc: markgross, Linux PM mailing list, linux-omap, Jean Pihet-XID

On Monday, July 04, 2011, Vishwanath Sripathy wrote:
> > -----Original Message-----
> > From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-
> > owner@vger.kernel.org] On Behalf Of Rafael J. Wysocki
> > Sent: Sunday, July 03, 2011 12:51 AM
> > To: jean.pihet@newoldbits.com
> > Cc: Paul Walmsley; Kevin Hilman; Magnus Damm; Linux PM mailing list;
> > linux-omap@vger.kernel.org; markgross@thegnar.org; Jean Pihet
> > Subject: Re: [PATCH v2 00/11] PM QoS: add a per-device wake-up
> > latency constraint class
> >
> > Hi,
> >
> > On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
> > > From: Jean Pihet <j-pihet@ti.com>
> > >
> > > This patch set is in an RFC state, for review and comments.
> >
> > First off, I'm sorry I couldn't review the patchset earlier.
> >
> > > In order to implement the new class in PM QoS the following
> > changes have been
> > > made:
> > >
> > > 1. Add a new PM QoS class for device wake-up constraints
> > > (PM_QOS_DEV_WAKEUP_LATENCY).
> > > Due to the per-device nature of the new class the constraints
> > lists are stored
> > > inside the device dev_pm_info struct instead of the internal per-
> > class
> > > constraints lists.
> > > The new class is only available from kernel drivers and so is not
> > exported to
> > > user space.
> >
> > Have you considered a design in which multiple devices may use the
> > same
> > list of constraints?  It seems plausible that the constraints will
> > be the
> > same, for example, for all Ethernet adapters in the system, in which
> > case it
> > will be wasteful to duplicate the list of constraints for each of
> > them.
> >
> > > 2. Added a notification of device insertion/removal from the
> > device PM framework
> > > to PM QoS.
> > > This allows to init/de-init the per-device constraints list upon
> > device insertion
> > > and removal.
> > > RFC state for comments and review, barely tested
> >
> > I need to have a look at the details, but in principle this means
> > that the
> > per-device lists will be usable only after the devices have been
> > registered.
> > In particular, this means that it will only be possible to add new
> > constraints
> > after registering the device, which may be too late for some use
> > cases.
> >
> > > 3. Make the pm_qos_add_request API more generic by using a
> > > struct pm_qos_parameters parameter. This allows easy extension in
> > the future.
> > >
> > > 4. Upon a change of the strongest constraint in the
> > PM_QOS_DEV_WAKEUP_LATENCY
> > > class a notification chain mechanism is used to take action on the
> > system.
> > > This is the proposed way to have PM QoS and the platform dependant
> > code to
> > > interact with each other, cf. 4 below.
> >
> > I guess you mean 5.?
> >
> > I think we will need something in addition to the notifier here.
> > For example,
> > I wouldn't like any core code, like runtime PM or cpuidle, to have
> > to register
> > a notifier with PM QoS.
> >
> > > The notification mechanism now passes the constraint request
> > struct ptr in
> > > order for the notifier callback to have access to the full set of
> > constraint
> > > data, e.g. the struct device ptr.
> > >
> > > 5. cpuidle interaction with the OMAP3 cpuidle handler
> > > Since cpuidle is a CPU centric framework it decides the MPU next
> > power state
> > > based on the MPU exit_latency and target_residency figures.
> > >
> > > The rest of the power domains get their next power state
> > programmed from
> > > the PM_QOS_DEV_WAKEUP_LATENCY class of the PM QoS framework, via
> > the device
> > > wake-up latency constraints.
> > >
> > > Note: the exit_latency and target_residency figures of the MPU
> > include the MPU
> > > itself and the peripherals needed for the MPU to execute
> > instructions (e.g.
> > > main memory, caches, IRQ controller, MMU etc).
> > > Some of those peripherals can belong to other power domains than
> > the MPU
> > > subsystem and so the corresponding latencies must be included in
> > those figures.
> > >
> > > 6. Update the pm_qos_add_request callers to the generic API
> > >
> > > 7. Minor clean-ups and rename of struct fields
> > >
> > > Questions:
> > > 1. How to retrieve the device ptr from a given device driver in
> > order to add
> > > a constraint on it?
> > > 2. The device struct has recently been extended with the power
> > domain
> > > information. Can this be used to apply the constraints on power
> > domains?
> >
> > Yes, it can in principle, but that will require some work.
> >
> > > On-going developments, patches in preparation:
> > > 1. write Documentation for the new PM QoS class
> >
> > I'd wait with that until the code has settled.
> >
> > > 2. validate the constraints framework on OMAP4 HW (done on OMAP3)
> > > 3. refine the power domains wake-up latency and the cpuidle
> > figures
> > >
> > > Based on the master branch of the linux-omap git tree (3.0.0-rc3).
> > Compile
> > > tested using OMAP and x86 generic defconfigs.
> > > Tested on OMAP3 Beagleboard (ES2.x) with full RETention and OFF
> > modes.
> >
> > More detailed comments will follow.
> Thanks Rafael for reviewing the patches. Jean is currently on summer
> vacation for 2 weeks and will take this discussion forward once he is back
> to work on July 18.

OK, thanks for letting me know.

Regards,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class
  2011-07-04  7:16   ` Vishwanath Sripathy
  2011-07-04  8:38     ` Rafael J. Wysocki
@ 2011-07-04  8:38     ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-07-04  8:38 UTC (permalink / raw)
  To: Vishwanath Sripathy
  Cc: jean.pihet, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list, linux-omap, markgross, Jean Pihet-XID

On Monday, July 04, 2011, Vishwanath Sripathy wrote:
> > -----Original Message-----
> > From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-
> > owner@vger.kernel.org] On Behalf Of Rafael J. Wysocki
> > Sent: Sunday, July 03, 2011 12:51 AM
> > To: jean.pihet@newoldbits.com
> > Cc: Paul Walmsley; Kevin Hilman; Magnus Damm; Linux PM mailing list;
> > linux-omap@vger.kernel.org; markgross@thegnar.org; Jean Pihet
> > Subject: Re: [PATCH v2 00/11] PM QoS: add a per-device wake-up
> > latency constraint class
> >
> > Hi,
> >
> > On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
> > > From: Jean Pihet <j-pihet@ti.com>
> > >
> > > This patch set is in an RFC state, for review and comments.
> >
> > First off, I'm sorry I couldn't review the patchset earlier.
> >
> > > In order to implement the new class in PM QoS the following
> > changes have been
> > > made:
> > >
> > > 1. Add a new PM QoS class for device wake-up constraints
> > > (PM_QOS_DEV_WAKEUP_LATENCY).
> > > Due to the per-device nature of the new class the constraints
> > lists are stored
> > > inside the device dev_pm_info struct instead of the internal per-
> > class
> > > constraints lists.
> > > The new class is only available from kernel drivers and so is not
> > exported to
> > > user space.
> >
> > Have you considered a design in which multiple devices may use the
> > same
> > list of constraints?  It seems plausible that the constraints will
> > be the
> > same, for example, for all Ethernet adapters in the system, in which
> > case it
> > will be wasteful to duplicate the list of constraints for each of
> > them.
> >
> > > 2. Added a notification of device insertion/removal from the
> > device PM framework
> > > to PM QoS.
> > > This allows to init/de-init the per-device constraints list upon
> > device insertion
> > > and removal.
> > > RFC state for comments and review, barely tested
> >
> > I need to have a look at the details, but in principle this means
> > that the
> > per-device lists will be usable only after the devices have been
> > registered.
> > In particular, this means that it will only be possible to add new
> > constraints
> > after registering the device, which may be too late for some use
> > cases.
> >
> > > 3. Make the pm_qos_add_request API more generic by using a
> > > struct pm_qos_parameters parameter. This allows easy extension in
> > the future.
> > >
> > > 4. Upon a change of the strongest constraint in the
> > PM_QOS_DEV_WAKEUP_LATENCY
> > > class a notification chain mechanism is used to take action on the
> > system.
> > > This is the proposed way to have PM QoS and the platform dependant
> > code to
> > > interact with each other, cf. 4 below.
> >
> > I guess you mean 5.?
> >
> > I think we will need something in addition to the notifier here.
> > For example,
> > I wouldn't like any core code, like runtime PM or cpuidle, to have
> > to register
> > a notifier with PM QoS.
> >
> > > The notification mechanism now passes the constraint request
> > struct ptr in
> > > order for the notifier callback to have access to the full set of
> > constraint
> > > data, e.g. the struct device ptr.
> > >
> > > 5. cpuidle interaction with the OMAP3 cpuidle handler
> > > Since cpuidle is a CPU centric framework it decides the MPU next
> > power state
> > > based on the MPU exit_latency and target_residency figures.
> > >
> > > The rest of the power domains get their next power state
> > programmed from
> > > the PM_QOS_DEV_WAKEUP_LATENCY class of the PM QoS framework, via
> > the device
> > > wake-up latency constraints.
> > >
> > > Note: the exit_latency and target_residency figures of the MPU
> > include the MPU
> > > itself and the peripherals needed for the MPU to execute
> > instructions (e.g.
> > > main memory, caches, IRQ controller, MMU etc).
> > > Some of those peripherals can belong to other power domains than
> > the MPU
> > > subsystem and so the corresponding latencies must be included in
> > those figures.
> > >
> > > 6. Update the pm_qos_add_request callers to the generic API
> > >
> > > 7. Minor clean-ups and rename of struct fields
> > >
> > > Questions:
> > > 1. How to retrieve the device ptr from a given device driver in
> > order to add
> > > a constraint on it?
> > > 2. The device struct has recently been extended with the power
> > domain
> > > information. Can this be used to apply the constraints on power
> > domains?
> >
> > Yes, it can in principle, but that will require some work.
> >
> > > On-going developments, patches in preparation:
> > > 1. write Documentation for the new PM QoS class
> >
> > I'd wait with that until the code has settled.
> >
> > > 2. validate the constraints framework on OMAP4 HW (done on OMAP3)
> > > 3. refine the power domains wake-up latency and the cpuidle
> > figures
> > >
> > > Based on the master branch of the linux-omap git tree (3.0.0-rc3).
> > Compile
> > > tested using OMAP and x86 generic defconfigs.
> > > Tested on OMAP3 Beagleboard (ES2.x) with full RETention and OFF
> > modes.
> >
> > More detailed comments will follow.
> Thanks Rafael for reviewing the patches. Jean is currently on summer
> vacation for 2 weeks and will take this discussion forward once he is back
> to work on July 18.

OK, thanks for letting me know.

Regards,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 01/11] PM: add a per-device wake-up latency constraints plist
  2011-07-02 19:39   ` Rafael J. Wysocki
@ 2011-07-20  8:57     ` Jean Pihet
  2011-07-20  8:57     ` Jean Pihet
  1 sibling, 0 replies; 122+ messages in thread
From: Jean Pihet @ 2011-07-20  8:57 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: markgross, Linux PM mailing list, linux-omap, Jean Pihet

Hi Rafael,

2011/7/2 Rafael J. Wysocki <rjw@sisk.pl>:
> Hi,
>
> On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
...

>> @@ -462,6 +463,7 @@ struct dev_pm_info {
>>       unsigned long           accounting_timestamp;
>>       void                    *subsys_data;  /* Owned by the subsystem. */
>>  #endif
>> +     struct plist_head       wakeup_lat_plist_head;
>>  };
>
> Please use a better name.  I mean, relly, the type implies that this is a
> plist head, so that doesn't need to appear in the field name too.  Also,
> the name is confusing, because "wakeup" may mean a couple of different things
> and it's not entirely clear what "lat" stands for.  So, I'd prefer something
> like
>
> +       struct plist_head       latency_constraints;
>
> or perhaps you can invent something even better.
I am OK with your suggestion and I will update the naming.

>
>>
>>  extern void update_pm_runtime_accounting(struct device *dev);
>>
>
> Thanks,
> Rafael

Thanks,
Jean

> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 01/11] PM: add a per-device wake-up latency constraints plist
  2011-07-02 19:39   ` Rafael J. Wysocki
  2011-07-20  8:57     ` Jean Pihet
@ 2011-07-20  8:57     ` Jean Pihet
  1 sibling, 0 replies; 122+ messages in thread
From: Jean Pihet @ 2011-07-20  8:57 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Paul Walmsley, Kevin Hilman, Magnus Damm, Linux PM mailing list,
	linux-omap, markgross, Jean Pihet

Hi Rafael,

2011/7/2 Rafael J. Wysocki <rjw@sisk.pl>:
> Hi,
>
> On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
...

>> @@ -462,6 +463,7 @@ struct dev_pm_info {
>>       unsigned long           accounting_timestamp;
>>       void                    *subsys_data;  /* Owned by the subsystem. */
>>  #endif
>> +     struct plist_head       wakeup_lat_plist_head;
>>  };
>
> Please use a better name.  I mean, relly, the type implies that this is a
> plist head, so that doesn't need to appear in the field name too.  Also,
> the name is confusing, because "wakeup" may mean a couple of different things
> and it's not entirely clear what "lat" stands for.  So, I'd prefer something
> like
>
> +       struct plist_head       latency_constraints;
>
> or perhaps you can invent something even better.
I am OK with your suggestion and I will update the naming.

>
>>
>>  extern void update_pm_runtime_accounting(struct device *dev);
>>
>
> Thanks,
> Rafael

Thanks,
Jean

> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-07-02 21:10   ` Rafael J. Wysocki
@ 2011-07-20  9:13     ` Jean Pihet
  2011-07-20  9:13     ` Jean Pihet
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 122+ messages in thread
From: Jean Pihet @ 2011-07-20  9:13 UTC (permalink / raw)
  To: Rafael J. Wysocki, markgross
  Cc: Linux PM mailing list, linux-omap, Jean Pihet

Hi Rafael, Mark,

- Looping in Mark for the user space API

2011/7/2 Rafael J. Wysocki <rjw@sisk.pl>:
> Hi,
>
> On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
>> From: Jean Pihet <j-pihet@ti.com>
>>
>> - add a new PM QoS class PM_QOS_DEV_WAKEUP_LATENCY for device wake-up
>> constraints. Due to the per-device nature of the new class the constraints
>> list is stored inside the device dev_pm_info struct instead of the internal
>> per-class constraints lists.
>
> I think PM_QOS_DEV_LATENCY might be a better name.
Ok, will update.

>
>> The new class is only available from kernel drivers and so is not exported
>> to user space.
>
> It should be available to user space, however, because in many cases drivers
> simply have no idea what values to use (after all, the use decides if he
> wants to trade worse video playback quality for better battery life, for
> example).
Ok. A per-device sysfs entry can be used as the user space interface.
Multiple users could access the same device constraints entry. Cf. the
existing implementation in kernel/pm_qos_params.c as an example.

Mark,
In a previous e-mail discussion you mentioned some concerns about the
user space API. Can you please give more details about it? Is the
proposed user space API suited?

>
>> The new class is used to put constraints on given devices in the system
>> while the existing PM_QOS_CPU_DMA_LATENCY class is used by cpuidle to
>> determine the next MPU subsystem state.
>>
>> - make the pm_qos_add_request API more generic by using a struct
>> pm_qos_parameters parameter
>>
>> - the notification mechanism now passes the constraint request struct ptr
>> in order for the notifier callback to have access to the full set of
>> constraint data, e.g. the struct device ptr
>>
>> - update the pm_qos_add_request callers to the generic API
>>
>> - minor clean-ups and rename of struct fields
>>
>> Signed-off-by: Jean Pihet <j-pihet@ti.com>
>
> Well, I think this patch attempts to do too many things at a time, which
> makes it somewhat hard to comprehend at first glance.  I'd stronly suggest
> splitting it into a series of patches that first modify the existing API
> to make it suitable for the "real" changes and second introduce those
> "real" chages in the most straightforward way possible.
Ok will split it up in a patch for 'hollow' API changes, then the
implementation itself in a separate patch.

>
>> ---
>>  arch/arm/plat-omap/i2c.c               |   20 ----
>>  drivers/i2c/busses/i2c-omap.c          |   35 ++++---
>>  drivers/media/video/via-camera.c       |    5 +-
>>  drivers/net/e1000e/netdev.c            |    9 +-
>>  drivers/net/wireless/ipw2x00/ipw2100.c |    6 +-
>>  include/linux/pm_qos_params.h          |   40 +++++---
>>  kernel/pm_qos_params.c                 |  185 +++++++++++++++++++-------------
>
> Hmm.  If you're at it, what about moving pm_qos_params.c to kernel/power
> and changing its name to pm_qos.c beforehand?
>
> The header might be called pm_qos.h too, BTW.
Ok, will update it.

>
>>  sound/core/pcm_native.c                |    8 +-
>>  8 files changed, 177 insertions(+), 131 deletions(-)
>>
> ...
>> diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
>> index a7d87f9..e6e16cb 100644
>> --- a/include/linux/pm_qos_params.h
>> +++ b/include/linux/pm_qos_params.h
>> @@ -8,31 +8,41 @@
>>  #include <linux/notifier.h>
>>  #include <linux/miscdevice.h>
>>
>> -#define PM_QOS_RESERVED 0
>> -#define PM_QOS_CPU_DMA_LATENCY 1
>> -#define PM_QOS_NETWORK_LATENCY 2
>> -#define PM_QOS_NETWORK_THROUGHPUT 3
>> +#define      PM_QOS_RESERVED                 0
>> +#define      PM_QOS_CPU_DMA_LATENCY          1
>> +#define      PM_QOS_DEV_WAKEUP_LATENCY       2
>> +#define      PM_QOS_NETWORK_LATENCY          3
>> +#define      PM_QOS_NETWORK_THROUGHPUT       4
>>
>> -#define PM_QOS_NUM_CLASSES 4
>> -#define PM_QOS_DEFAULT_VALUE -1
>> +#define PM_QOS_NUM_CLASSES           5
>> +#define PM_QOS_DEFAULT_VALUE         -1
>>
>> -#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE     (2000 * USEC_PER_SEC)
>> -#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE     (2000 * USEC_PER_SEC)
>> -#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE      0
>> +#define      PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE        (2000 * USEC_PER_SEC)
>> +#define      PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE     0
>> +#define      PM_QOS_NETWORK_LAT_DEFAULT_VALUE        (2000 * USEC_PER_SEC)
>> +#define      PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0
>>
>>  struct pm_qos_request_list {
>>       struct plist_node list;
>> -     int pm_qos_class;
>> +     int class;
>> +     struct device *dev;
>>  };
>>
>> -void pm_qos_add_request(struct pm_qos_request_list *l, int pm_qos_class, s32 value);
>> +struct pm_qos_parameters {
>> +     int class;
>> +     struct device *dev;
>> +     s32 value;
>> +};
>> +
>> +void pm_qos_add_request(struct pm_qos_request_list *l,
>> +                     struct pm_qos_parameters *params);
>>  void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
>> -             s32 new_value);
>> +                        s32 new_value);
>>  void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
>>
>> -int pm_qos_request(int pm_qos_class);
>> -int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
>> -int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
>> +int pm_qos_request(int class);
>> +int pm_qos_add_notifier(int class, struct notifier_block *notifier);
>> +int pm_qos_remove_notifier(int class, struct notifier_block *notifier);
>>  int pm_qos_request_active(struct pm_qos_request_list *req);
>>
>>  #endif
>> diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
>> index 6824ca7..d61c8e5 100644
>> --- a/kernel/pm_qos_params.c
>> +++ b/kernel/pm_qos_params.c
>> @@ -60,7 +60,7 @@ enum pm_qos_type {
>>   * types linux supports for 32 bit quantites
>>   */
>>  struct pm_qos_object {
>> -     struct plist_head requests;
>> +     struct plist_head *requests;
>>       struct blocking_notifier_head *notifiers;
>>       struct miscdevice pm_qos_power_miscdev;
>>       char *name;
>
> So, I gather the idea is to have "requests" point to the device's private
> list of latency constraints.  [BTW, there seems to be a naming confusion,
> because you tend to call those things "constraints" rather that "requests".]
Ok will change the naming.

> If so, doesn't that mean we'll need a per-device struct pm_qos_object too?
> In which case why not to make the device object point to that pm_qos_object
> object instead?
>
>> @@ -72,9 +72,12 @@ struct pm_qos_object {
>>  static DEFINE_SPINLOCK(pm_qos_lock);
>>
>>  static struct pm_qos_object null_pm_qos;
>> +
>>  static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier);
>> +static struct plist_head _cpu_dma_reqs =
>> +                     PLIST_HEAD_INIT(_cpu_dma_reqs, pm_qos_lock);
>>  static struct pm_qos_object cpu_dma_pm_qos = {
>> -     .requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock),
>> +     .requests = &_cpu_dma_reqs,
>>       .notifiers = &cpu_dma_lat_notifier,
>>       .name = "cpu_dma_latency",
>>       .target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
>> @@ -82,9 +85,20 @@ static struct pm_qos_object cpu_dma_pm_qos = {
>>       .type = PM_QOS_MIN,
>>  };
>>
>> +static BLOCKING_NOTIFIER_HEAD(dev_wakeup_lat_notifier);
>> +static struct pm_qos_object dev_wakeup_lat_pm_qos = {
>> +     .notifiers = &dev_wakeup_lat_notifier,
>> +     .name = "dev_wakeup_latency",
>> +     .target_value = PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE,
>> +     .default_value = PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE,
>> +     .type = PM_QOS_MIN,
>> +};
>> +
>>  static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
>> +static struct plist_head _network_lat_reqs =
>> +                     PLIST_HEAD_INIT(_network_lat_reqs, pm_qos_lock);
>>  static struct pm_qos_object network_lat_pm_qos = {
>> -     .requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock),
>> +     .requests = &_network_lat_reqs,
>>       .notifiers = &network_lat_notifier,
>>       .name = "network_latency",
>>       .target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
>> @@ -94,8 +108,10 @@ static struct pm_qos_object network_lat_pm_qos = {
>>
>>
>>  static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier);
>> +static struct plist_head _network_throughput_reqs =
>> +                     PLIST_HEAD_INIT(_network_throughput_reqs, pm_qos_lock);
>>  static struct pm_qos_object network_throughput_pm_qos = {
>> -     .requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock),
>> +     .requests = &_network_throughput_reqs,
>>       .notifiers = &network_throughput_notifier,
>>       .name = "network_throughput",
>>       .target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
>> @@ -107,6 +123,7 @@ static struct pm_qos_object network_throughput_pm_qos = {
>>  static struct pm_qos_object *pm_qos_array[] = {
>>       &null_pm_qos,
>>       &cpu_dma_pm_qos,
>> +     &dev_wakeup_lat_pm_qos,
>>       &network_lat_pm_qos,
>>       &network_throughput_pm_qos
>>  };
>> @@ -129,19 +146,19 @@ static const struct file_operations pm_qos_power_fops = {
>>  /* unlocked internal variant */
>>  static inline int pm_qos_get_value(struct pm_qos_object *o)
>>  {
>> -     if (plist_head_empty(&o->requests))
>> +     if (plist_head_empty(o->requests))
>>               return o->default_value;
>>
>>       switch (o->type) {
>> -     case PM_QOS_MIN:
>> -             return plist_first(&o->requests)->prio;
>> +             case PM_QOS_MIN:
>> +                     return plist_first(o->requests)->prio;
>>
>> -     case PM_QOS_MAX:
>> -             return plist_last(&o->requests)->prio;
>> +             case PM_QOS_MAX:
>> +                     return plist_last(o->requests)->prio;
>>
>> -     default:
>> -             /* runtime check for not using enum */
>> -             BUG();
>> +             default:
>> +                     /* runtime check for not using enum */
>> +                     BUG();
>>       }
>>  }
>>
>> @@ -155,13 +172,22 @@ static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value)
>>       o->target_value = value;
>>  }
>>
>> -static void update_target(struct pm_qos_object *o, struct plist_node *node,
>> -                       int del, int value)
>> +static void update_target(struct pm_qos_request_list *req, int del, int value)
>>  {
>>       unsigned long flags;
>>       int prev_value, curr_value;
>> +     struct pm_qos_object *o = pm_qos_array[req->class];
>> +     struct plist_node *node = &req->list;
>>
>>       spin_lock_irqsave(&pm_qos_lock, flags);
>> +     /*
>> +      * PM_QOS_DEV_WAKEUP_LATENCY:
>> +      * Use the per-device wake-up latency constraints list for
>> +      * constraints storage
>> +      */
>> +     if (req->class == PM_QOS_DEV_WAKEUP_LATENCY)
>> +             o->requests = &req->dev->power.wakeup_lat_plist_head;
>
> Ah, I see what the idea is and quite frankly I don't like it.
>
> Changing the requests field on the fly in every second (or so) invocation of
> update_target() for PM_QOS_DEV_WAKEUP_LATENCY class is beyond ugly.  Moreover,
> it makes all devices share the default_value field which I don't think is
> correct (the target_value field is shared too, which may lead to all sorts of
> problems).
Indeed I had the same concern about the code not being generic enough.

>
> I wouldn't even try to use struct pm_qos_object as it is.  Instead, I'd
> introduce something like
>
> struct pm_qos_constraits {
>        struct plist_head requests;
>        unsigned int current_val;
>        unsigned int default_val;
>        unsigned int floor_val;  /* for adding new requests */
>        unsigned int ceiling_val;  /* ditto */
>        enum pm_qos_type type;
> };
>
> Where I'm not sure if the "type" field is really necessary, but that should
> work out at one point and "unsigned int" is on purpose (it should have been
> that way from day one in the first place).  That's what is needed for device
> IMO, the other fields in struct pm_qos_object are simply redundant for this
> use case.
>
> Now, for the compatibility with the existing code I'd redefine struct
> pm_qos_object as:
>
> struct pm_qos_object {
>        struct pm_qos_constraints constraints;
>        struct blocking_notifier *notifiers;
>        struct miscdevice pm_qos_power_miscdev;
>        char *name;
> };
>
> and I'd change the code to operate on struct pm_qos_constraits in the first
> place, with a compatibility layer using struct pm_qos_object on top of that.

>
> Then, each device may have its own struct pm_qos_constraits object that will
> be operated on by the PM QoS functions.
That makes sense, I am working on an RFC implementation.

> [There is the problem of whether or
> not those object should be embedded in struct dev_pm_info, it may be better
> to use pointers to them.
Should the object be embedded in the device struct instead? If only a
pointer is used when should the struct be allocated (at first use
...)?

> That may be used for sharing of constraints, for
> example, in which case it will be necessary to add a refcount to struct
> pm_qos_constraits.]
More on sharing in the comments for 0/11.

>
> Thanks,
> Rafael
>

Thanks,
Jean

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-07-02 21:10   ` Rafael J. Wysocki
  2011-07-20  9:13     ` Jean Pihet
@ 2011-07-20  9:13     ` Jean Pihet
  2011-08-02 17:49     ` Kevin Hilman
  2011-08-02 17:49     ` Kevin Hilman
  3 siblings, 0 replies; 122+ messages in thread
From: Jean Pihet @ 2011-07-20  9:13 UTC (permalink / raw)
  To: Rafael J. Wysocki, markgross
  Cc: Paul Walmsley, Kevin Hilman, Magnus Damm, Linux PM mailing list,
	linux-omap, Jean Pihet

Hi Rafael, Mark,

- Looping in Mark for the user space API

2011/7/2 Rafael J. Wysocki <rjw@sisk.pl>:
> Hi,
>
> On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
>> From: Jean Pihet <j-pihet@ti.com>
>>
>> - add a new PM QoS class PM_QOS_DEV_WAKEUP_LATENCY for device wake-up
>> constraints. Due to the per-device nature of the new class the constraints
>> list is stored inside the device dev_pm_info struct instead of the internal
>> per-class constraints lists.
>
> I think PM_QOS_DEV_LATENCY might be a better name.
Ok, will update.

>
>> The new class is only available from kernel drivers and so is not exported
>> to user space.
>
> It should be available to user space, however, because in many cases drivers
> simply have no idea what values to use (after all, the use decides if he
> wants to trade worse video playback quality for better battery life, for
> example).
Ok. A per-device sysfs entry can be used as the user space interface.
Multiple users could access the same device constraints entry. Cf. the
existing implementation in kernel/pm_qos_params.c as an example.

Mark,
In a previous e-mail discussion you mentioned some concerns about the
user space API. Can you please give more details about it? Is the
proposed user space API suited?

>
>> The new class is used to put constraints on given devices in the system
>> while the existing PM_QOS_CPU_DMA_LATENCY class is used by cpuidle to
>> determine the next MPU subsystem state.
>>
>> - make the pm_qos_add_request API more generic by using a struct
>> pm_qos_parameters parameter
>>
>> - the notification mechanism now passes the constraint request struct ptr
>> in order for the notifier callback to have access to the full set of
>> constraint data, e.g. the struct device ptr
>>
>> - update the pm_qos_add_request callers to the generic API
>>
>> - minor clean-ups and rename of struct fields
>>
>> Signed-off-by: Jean Pihet <j-pihet@ti.com>
>
> Well, I think this patch attempts to do too many things at a time, which
> makes it somewhat hard to comprehend at first glance.  I'd stronly suggest
> splitting it into a series of patches that first modify the existing API
> to make it suitable for the "real" changes and second introduce those
> "real" chages in the most straightforward way possible.
Ok will split it up in a patch for 'hollow' API changes, then the
implementation itself in a separate patch.

>
>> ---
>>  arch/arm/plat-omap/i2c.c               |   20 ----
>>  drivers/i2c/busses/i2c-omap.c          |   35 ++++---
>>  drivers/media/video/via-camera.c       |    5 +-
>>  drivers/net/e1000e/netdev.c            |    9 +-
>>  drivers/net/wireless/ipw2x00/ipw2100.c |    6 +-
>>  include/linux/pm_qos_params.h          |   40 +++++---
>>  kernel/pm_qos_params.c                 |  185 +++++++++++++++++++-------------
>
> Hmm.  If you're at it, what about moving pm_qos_params.c to kernel/power
> and changing its name to pm_qos.c beforehand?
>
> The header might be called pm_qos.h too, BTW.
Ok, will update it.

>
>>  sound/core/pcm_native.c                |    8 +-
>>  8 files changed, 177 insertions(+), 131 deletions(-)
>>
> ...
>> diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
>> index a7d87f9..e6e16cb 100644
>> --- a/include/linux/pm_qos_params.h
>> +++ b/include/linux/pm_qos_params.h
>> @@ -8,31 +8,41 @@
>>  #include <linux/notifier.h>
>>  #include <linux/miscdevice.h>
>>
>> -#define PM_QOS_RESERVED 0
>> -#define PM_QOS_CPU_DMA_LATENCY 1
>> -#define PM_QOS_NETWORK_LATENCY 2
>> -#define PM_QOS_NETWORK_THROUGHPUT 3
>> +#define      PM_QOS_RESERVED                 0
>> +#define      PM_QOS_CPU_DMA_LATENCY          1
>> +#define      PM_QOS_DEV_WAKEUP_LATENCY       2
>> +#define      PM_QOS_NETWORK_LATENCY          3
>> +#define      PM_QOS_NETWORK_THROUGHPUT       4
>>
>> -#define PM_QOS_NUM_CLASSES 4
>> -#define PM_QOS_DEFAULT_VALUE -1
>> +#define PM_QOS_NUM_CLASSES           5
>> +#define PM_QOS_DEFAULT_VALUE         -1
>>
>> -#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE     (2000 * USEC_PER_SEC)
>> -#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE     (2000 * USEC_PER_SEC)
>> -#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE      0
>> +#define      PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE        (2000 * USEC_PER_SEC)
>> +#define      PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE     0
>> +#define      PM_QOS_NETWORK_LAT_DEFAULT_VALUE        (2000 * USEC_PER_SEC)
>> +#define      PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0
>>
>>  struct pm_qos_request_list {
>>       struct plist_node list;
>> -     int pm_qos_class;
>> +     int class;
>> +     struct device *dev;
>>  };
>>
>> -void pm_qos_add_request(struct pm_qos_request_list *l, int pm_qos_class, s32 value);
>> +struct pm_qos_parameters {
>> +     int class;
>> +     struct device *dev;
>> +     s32 value;
>> +};
>> +
>> +void pm_qos_add_request(struct pm_qos_request_list *l,
>> +                     struct pm_qos_parameters *params);
>>  void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
>> -             s32 new_value);
>> +                        s32 new_value);
>>  void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
>>
>> -int pm_qos_request(int pm_qos_class);
>> -int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier);
>> -int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
>> +int pm_qos_request(int class);
>> +int pm_qos_add_notifier(int class, struct notifier_block *notifier);
>> +int pm_qos_remove_notifier(int class, struct notifier_block *notifier);
>>  int pm_qos_request_active(struct pm_qos_request_list *req);
>>
>>  #endif
>> diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
>> index 6824ca7..d61c8e5 100644
>> --- a/kernel/pm_qos_params.c
>> +++ b/kernel/pm_qos_params.c
>> @@ -60,7 +60,7 @@ enum pm_qos_type {
>>   * types linux supports for 32 bit quantites
>>   */
>>  struct pm_qos_object {
>> -     struct plist_head requests;
>> +     struct plist_head *requests;
>>       struct blocking_notifier_head *notifiers;
>>       struct miscdevice pm_qos_power_miscdev;
>>       char *name;
>
> So, I gather the idea is to have "requests" point to the device's private
> list of latency constraints.  [BTW, there seems to be a naming confusion,
> because you tend to call those things "constraints" rather that "requests".]
Ok will change the naming.

> If so, doesn't that mean we'll need a per-device struct pm_qos_object too?
> In which case why not to make the device object point to that pm_qos_object
> object instead?
>
>> @@ -72,9 +72,12 @@ struct pm_qos_object {
>>  static DEFINE_SPINLOCK(pm_qos_lock);
>>
>>  static struct pm_qos_object null_pm_qos;
>> +
>>  static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier);
>> +static struct plist_head _cpu_dma_reqs =
>> +                     PLIST_HEAD_INIT(_cpu_dma_reqs, pm_qos_lock);
>>  static struct pm_qos_object cpu_dma_pm_qos = {
>> -     .requests = PLIST_HEAD_INIT(cpu_dma_pm_qos.requests, pm_qos_lock),
>> +     .requests = &_cpu_dma_reqs,
>>       .notifiers = &cpu_dma_lat_notifier,
>>       .name = "cpu_dma_latency",
>>       .target_value = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE,
>> @@ -82,9 +85,20 @@ static struct pm_qos_object cpu_dma_pm_qos = {
>>       .type = PM_QOS_MIN,
>>  };
>>
>> +static BLOCKING_NOTIFIER_HEAD(dev_wakeup_lat_notifier);
>> +static struct pm_qos_object dev_wakeup_lat_pm_qos = {
>> +     .notifiers = &dev_wakeup_lat_notifier,
>> +     .name = "dev_wakeup_latency",
>> +     .target_value = PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE,
>> +     .default_value = PM_QOS_DEV_WAKEUP_LAT_DEFAULT_VALUE,
>> +     .type = PM_QOS_MIN,
>> +};
>> +
>>  static BLOCKING_NOTIFIER_HEAD(network_lat_notifier);
>> +static struct plist_head _network_lat_reqs =
>> +                     PLIST_HEAD_INIT(_network_lat_reqs, pm_qos_lock);
>>  static struct pm_qos_object network_lat_pm_qos = {
>> -     .requests = PLIST_HEAD_INIT(network_lat_pm_qos.requests, pm_qos_lock),
>> +     .requests = &_network_lat_reqs,
>>       .notifiers = &network_lat_notifier,
>>       .name = "network_latency",
>>       .target_value = PM_QOS_NETWORK_LAT_DEFAULT_VALUE,
>> @@ -94,8 +108,10 @@ static struct pm_qos_object network_lat_pm_qos = {
>>
>>
>>  static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier);
>> +static struct plist_head _network_throughput_reqs =
>> +                     PLIST_HEAD_INIT(_network_throughput_reqs, pm_qos_lock);
>>  static struct pm_qos_object network_throughput_pm_qos = {
>> -     .requests = PLIST_HEAD_INIT(network_throughput_pm_qos.requests, pm_qos_lock),
>> +     .requests = &_network_throughput_reqs,
>>       .notifiers = &network_throughput_notifier,
>>       .name = "network_throughput",
>>       .target_value = PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE,
>> @@ -107,6 +123,7 @@ static struct pm_qos_object network_throughput_pm_qos = {
>>  static struct pm_qos_object *pm_qos_array[] = {
>>       &null_pm_qos,
>>       &cpu_dma_pm_qos,
>> +     &dev_wakeup_lat_pm_qos,
>>       &network_lat_pm_qos,
>>       &network_throughput_pm_qos
>>  };
>> @@ -129,19 +146,19 @@ static const struct file_operations pm_qos_power_fops = {
>>  /* unlocked internal variant */
>>  static inline int pm_qos_get_value(struct pm_qos_object *o)
>>  {
>> -     if (plist_head_empty(&o->requests))
>> +     if (plist_head_empty(o->requests))
>>               return o->default_value;
>>
>>       switch (o->type) {
>> -     case PM_QOS_MIN:
>> -             return plist_first(&o->requests)->prio;
>> +             case PM_QOS_MIN:
>> +                     return plist_first(o->requests)->prio;
>>
>> -     case PM_QOS_MAX:
>> -             return plist_last(&o->requests)->prio;
>> +             case PM_QOS_MAX:
>> +                     return plist_last(o->requests)->prio;
>>
>> -     default:
>> -             /* runtime check for not using enum */
>> -             BUG();
>> +             default:
>> +                     /* runtime check for not using enum */
>> +                     BUG();
>>       }
>>  }
>>
>> @@ -155,13 +172,22 @@ static inline void pm_qos_set_value(struct pm_qos_object *o, s32 value)
>>       o->target_value = value;
>>  }
>>
>> -static void update_target(struct pm_qos_object *o, struct plist_node *node,
>> -                       int del, int value)
>> +static void update_target(struct pm_qos_request_list *req, int del, int value)
>>  {
>>       unsigned long flags;
>>       int prev_value, curr_value;
>> +     struct pm_qos_object *o = pm_qos_array[req->class];
>> +     struct plist_node *node = &req->list;
>>
>>       spin_lock_irqsave(&pm_qos_lock, flags);
>> +     /*
>> +      * PM_QOS_DEV_WAKEUP_LATENCY:
>> +      * Use the per-device wake-up latency constraints list for
>> +      * constraints storage
>> +      */
>> +     if (req->class == PM_QOS_DEV_WAKEUP_LATENCY)
>> +             o->requests = &req->dev->power.wakeup_lat_plist_head;
>
> Ah, I see what the idea is and quite frankly I don't like it.
>
> Changing the requests field on the fly in every second (or so) invocation of
> update_target() for PM_QOS_DEV_WAKEUP_LATENCY class is beyond ugly.  Moreover,
> it makes all devices share the default_value field which I don't think is
> correct (the target_value field is shared too, which may lead to all sorts of
> problems).
Indeed I had the same concern about the code not being generic enough.

>
> I wouldn't even try to use struct pm_qos_object as it is.  Instead, I'd
> introduce something like
>
> struct pm_qos_constraits {
>        struct plist_head requests;
>        unsigned int current_val;
>        unsigned int default_val;
>        unsigned int floor_val;  /* for adding new requests */
>        unsigned int ceiling_val;  /* ditto */
>        enum pm_qos_type type;
> };
>
> Where I'm not sure if the "type" field is really necessary, but that should
> work out at one point and "unsigned int" is on purpose (it should have been
> that way from day one in the first place).  That's what is needed for device
> IMO, the other fields in struct pm_qos_object are simply redundant for this
> use case.
>
> Now, for the compatibility with the existing code I'd redefine struct
> pm_qos_object as:
>
> struct pm_qos_object {
>        struct pm_qos_constraints constraints;
>        struct blocking_notifier *notifiers;
>        struct miscdevice pm_qos_power_miscdev;
>        char *name;
> };
>
> and I'd change the code to operate on struct pm_qos_constraits in the first
> place, with a compatibility layer using struct pm_qos_object on top of that.

>
> Then, each device may have its own struct pm_qos_constraits object that will
> be operated on by the PM QoS functions.
That makes sense, I am working on an RFC implementation.

> [There is the problem of whether or
> not those object should be embedded in struct dev_pm_info, it may be better
> to use pointers to them.
Should the object be embedded in the device struct instead? If only a
pointer is used when should the struct be allocated (at first use
...)?

> That may be used for sharing of constraints, for
> example, in which case it will be necessary to add a refcount to struct
> pm_qos_constraits.]
More on sharing in the comments for 0/11.

>
> Thanks,
> Rafael
>

Thanks,
Jean
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 03/11] PM QoS: support the dynamic devices insertion and removal
  2011-07-02 21:14   ` Rafael J. Wysocki
@ 2011-07-20  9:16     ` Jean Pihet
  2011-07-20  9:16     ` Jean Pihet
  1 sibling, 0 replies; 122+ messages in thread
From: Jean Pihet @ 2011-07-20  9:16 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: markgross, Linux PM mailing list, linux-omap, Jean Pihet

Hi Rafael,

2011/7/2 Rafael J. Wysocki <rjw@sisk.pl>:
> Hi,
>
> On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
>> From: Jean Pihet <j-pihet@ti.com>
>>
>> The devices wake-up latency constraints class of PM QoS is
>> storing the constraints list using the device pm_info struct.
>>
>> This patch adds the init and de-init of the per-device constraints
>> list in order to support the dynamic insertion and removal
>> of the devices in the system.
>>
>> Signed-off-by: Jean Pihet <j-pihet@ti.com>
>
> The number of times this patch special cases PM_QOS_DEV_WAKEUP_LATENCY with
> respect to the other PM QoS classes indicates a design issue, which kind of
> corresponds with my comments on [3/11].
Do you mean 02/11? Indeed the special cases changes are introduced by
02/11. Re-designing 02/11 will solve those special cases issues.

Thanks,
Jean

>
> Thanks,
> Rafael
>
>
>> ---
>>  drivers/base/power/main.c     |    8 +++--
>>  include/linux/pm.h            |    1 +
>>  include/linux/pm_qos_params.h |    2 +
>>  kernel/pm_qos_params.c        |   70 ++++++++++++++++++++++++++++++++--------
>>  4 files changed, 64 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
>> index b1fd96b..51f5526 100644
>> --- a/drivers/base/power/main.c
>> +++ b/drivers/base/power/main.c
>> @@ -27,6 +27,7 @@
>>  #include <linux/sched.h>
>>  #include <linux/async.h>
>>  #include <linux/suspend.h>
>> +#include <linux/pm_qos_params.h>
>>
>>  #include "../base.h"
>>  #include "power.h"
>> @@ -96,8 +97,8 @@ void device_pm_add(struct device *dev)
>>                       dev_name(dev->parent));
>>       list_add_tail(&dev->power.entry, &dpm_list);
>>       mutex_unlock(&dpm_list_mtx);
>> -     /* ToDo: call PM QoS to init the per-device wakeup latency constraints */
>> -     plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
>> +     /* Call PM QoS to init the per-device wakeup latency constraints */
>> +     pm_qos_dev_wakeup_lat_init(dev);
>>  }
>>
>>  /**
>> @@ -108,7 +109,8 @@ void device_pm_remove(struct device *dev)
>>  {
>>       pr_debug("PM: Removing info for %s:%s\n",
>>                dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
>> -     /* ToDo: call PM QoS to de-init the per-device wakeup latency constraints */
>> +     /* Call PM QoS to de-init the per-device wakeup latency constraints */
>> +     pm_qos_dev_wakeup_lat_deinit(dev);
>>       complete_all(&dev->power.completion);
>>       mutex_lock(&dpm_list_mtx);
>>       list_del_init(&dev->power.entry);
>> diff --git a/include/linux/pm.h b/include/linux/pm.h
>> index 35fe682..d9b6092 100644
>> --- a/include/linux/pm.h
>> +++ b/include/linux/pm.h
>> @@ -464,6 +464,7 @@ struct dev_pm_info {
>>       void                    *subsys_data;  /* Owned by the subsystem. */
>>  #endif
>>       struct plist_head       wakeup_lat_plist_head;
>> +     int                     wakeup_lat_init;
>>  };
>>
>>  extern void update_pm_runtime_accounting(struct device *dev);
>> diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
>> index e6e16cb..5b6707a 100644
>> --- a/include/linux/pm_qos_params.h
>> +++ b/include/linux/pm_qos_params.h
>> @@ -45,4 +45,6 @@ int pm_qos_add_notifier(int class, struct notifier_block *notifier);
>>  int pm_qos_remove_notifier(int class, struct notifier_block *notifier);
>>  int pm_qos_request_active(struct pm_qos_request_list *req);
>>
>> +void pm_qos_dev_wakeup_lat_init(struct device *dev);
>> +void pm_qos_dev_wakeup_lat_deinit(struct device *dev);
>>  #endif
>> diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
>> index d61c8e5..6f25ccb 100644
>> --- a/kernel/pm_qos_params.c
>> +++ b/kernel/pm_qos_params.c
>> @@ -275,11 +275,21 @@ void pm_qos_add_request(struct pm_qos_request_list *pm_qos_req,
>>       struct pm_qos_object *o =  pm_qos_array[pm_qos_params->class];
>>       int new_value;
>>
>> -     if ((pm_qos_params->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
>> -         (pm_qos_request_active(pm_qos_req))) {
>> -             WARN(1, KERN_ERR "pm_qos_add_request() called for already "
>> -                  "added request\n");
>> -             return;
>> +     if (pm_qos_params->class == PM_QOS_DEV_WAKEUP_LATENCY) {
>> +             if (!pm_qos_params->dev) {
>> +                     WARN(1, KERN_ERR "pm_qos_add_request() called for "
>> +                             "invalid device\n");
>> +                     return;
>> +             }
>> +             /* Silently return if the device is being released */
>> +             if (!pm_qos_params->dev->power.wakeup_lat_init)
>> +                     return;
>> +     } else {
>> +             if (pm_qos_request_active(pm_qos_req)) {
>> +                     WARN(1, KERN_ERR "pm_qos_add_request() called for "
>> +                             "already added request\n");
>> +                     return;
>> +             }
>>       }
>>
>>       if (pm_qos_params->value == PM_QOS_DEFAULT_VALUE)
>> @@ -312,11 +322,16 @@ void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
>>       if (!pm_qos_req) /*guard against callers passing in null */
>>               return;
>>
>> -     if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
>> -         (!pm_qos_request_active(pm_qos_req))) {
>> -             WARN(1, KERN_ERR "pm_qos_update_request() called for unknown "
>> -                  "object\n");
>> -             return;
>> +     if (pm_qos_req->class == PM_QOS_DEV_WAKEUP_LATENCY) {
>> +             /* Silently return if the device is being released */
>> +             if (!pm_qos_req->dev->power.wakeup_lat_init)
>> +                     return;
>> +     } else {
>> +             if (!pm_qos_request_active(pm_qos_req)) {
>> +                     WARN(1, KERN_ERR "pm_qos_update_request() called "
>> +                             "for unknown object\n");
>> +                     return;
>> +             }
>>       }
>>
>>       if (new_value == PM_QOS_DEFAULT_VALUE)
>> @@ -343,11 +358,16 @@ void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req)
>>               return;
>>               /* silent return to keep pcm code cleaner */
>>
>> -     if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
>> -         (!pm_qos_request_active(pm_qos_req))) {
>> -             WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown "
>> -                  "object\n");
>> +     if (pm_qos_req->class == PM_QOS_DEV_WAKEUP_LATENCY) {
>> +             /* Silently return if the device is being released */
>> +             if (!pm_qos_req->dev->power.wakeup_lat_init)
>> +                     return;
>> +     } else {
>> +             if (!pm_qos_request_active(pm_qos_req)) {
>> +                     WARN(1, KERN_ERR "pm_qos_remove_request() called "
>> +                             "for unknown object\n");
>>               return;
>> +             }
>>       }
>>
>>       update_target(pm_qos_req, 1, PM_QOS_DEFAULT_VALUE);
>> @@ -393,6 +413,28 @@ int pm_qos_remove_notifier(int class, struct notifier_block *notifier)
>>  }
>>  EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
>>
>> +/* Called from the device PM subsystem at device init */
>> +void pm_qos_dev_wakeup_lat_init(struct device *dev)
>> +{
>> +     plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
>> +     dev->power.wakeup_lat_init = 1;
>> +}
>> +
>> +/* Called from the device PM subsystem at device release */
>> +void pm_qos_dev_wakeup_lat_deinit(struct device *dev)
>> +{
>> +     struct pm_qos_request_list *req, *tmp;
>> +
>> +     dev->power.wakeup_lat_init = 0;
>> +
>> +     /* Flush the constraints list for the device */
>> +     plist_for_each_entry_safe(req, tmp,
>> +                               &dev->power.wakeup_lat_plist_head,
>> +                               list)
>> +             update_target(req, 1, PM_QOS_DEFAULT_VALUE);
>> +     plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
>> +}
>> +
>>  static int pm_qos_power_open(struct inode *inode, struct file *filp)
>>  {
>>       struct pm_qos_parameters pm_qos_params;
>>
>
>

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 03/11] PM QoS: support the dynamic devices insertion and removal
  2011-07-02 21:14   ` Rafael J. Wysocki
  2011-07-20  9:16     ` Jean Pihet
@ 2011-07-20  9:16     ` Jean Pihet
  1 sibling, 0 replies; 122+ messages in thread
From: Jean Pihet @ 2011-07-20  9:16 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Paul Walmsley, Kevin Hilman, Magnus Damm, Linux PM mailing list,
	linux-omap, markgross, Jean Pihet

Hi Rafael,

2011/7/2 Rafael J. Wysocki <rjw@sisk.pl>:
> Hi,
>
> On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
>> From: Jean Pihet <j-pihet@ti.com>
>>
>> The devices wake-up latency constraints class of PM QoS is
>> storing the constraints list using the device pm_info struct.
>>
>> This patch adds the init and de-init of the per-device constraints
>> list in order to support the dynamic insertion and removal
>> of the devices in the system.
>>
>> Signed-off-by: Jean Pihet <j-pihet@ti.com>
>
> The number of times this patch special cases PM_QOS_DEV_WAKEUP_LATENCY with
> respect to the other PM QoS classes indicates a design issue, which kind of
> corresponds with my comments on [3/11].
Do you mean 02/11? Indeed the special cases changes are introduced by
02/11. Re-designing 02/11 will solve those special cases issues.

Thanks,
Jean

>
> Thanks,
> Rafael
>
>
>> ---
>>  drivers/base/power/main.c     |    8 +++--
>>  include/linux/pm.h            |    1 +
>>  include/linux/pm_qos_params.h |    2 +
>>  kernel/pm_qos_params.c        |   70 ++++++++++++++++++++++++++++++++--------
>>  4 files changed, 64 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
>> index b1fd96b..51f5526 100644
>> --- a/drivers/base/power/main.c
>> +++ b/drivers/base/power/main.c
>> @@ -27,6 +27,7 @@
>>  #include <linux/sched.h>
>>  #include <linux/async.h>
>>  #include <linux/suspend.h>
>> +#include <linux/pm_qos_params.h>
>>
>>  #include "../base.h"
>>  #include "power.h"
>> @@ -96,8 +97,8 @@ void device_pm_add(struct device *dev)
>>                       dev_name(dev->parent));
>>       list_add_tail(&dev->power.entry, &dpm_list);
>>       mutex_unlock(&dpm_list_mtx);
>> -     /* ToDo: call PM QoS to init the per-device wakeup latency constraints */
>> -     plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
>> +     /* Call PM QoS to init the per-device wakeup latency constraints */
>> +     pm_qos_dev_wakeup_lat_init(dev);
>>  }
>>
>>  /**
>> @@ -108,7 +109,8 @@ void device_pm_remove(struct device *dev)
>>  {
>>       pr_debug("PM: Removing info for %s:%s\n",
>>                dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
>> -     /* ToDo: call PM QoS to de-init the per-device wakeup latency constraints */
>> +     /* Call PM QoS to de-init the per-device wakeup latency constraints */
>> +     pm_qos_dev_wakeup_lat_deinit(dev);
>>       complete_all(&dev->power.completion);
>>       mutex_lock(&dpm_list_mtx);
>>       list_del_init(&dev->power.entry);
>> diff --git a/include/linux/pm.h b/include/linux/pm.h
>> index 35fe682..d9b6092 100644
>> --- a/include/linux/pm.h
>> +++ b/include/linux/pm.h
>> @@ -464,6 +464,7 @@ struct dev_pm_info {
>>       void                    *subsys_data;  /* Owned by the subsystem. */
>>  #endif
>>       struct plist_head       wakeup_lat_plist_head;
>> +     int                     wakeup_lat_init;
>>  };
>>
>>  extern void update_pm_runtime_accounting(struct device *dev);
>> diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
>> index e6e16cb..5b6707a 100644
>> --- a/include/linux/pm_qos_params.h
>> +++ b/include/linux/pm_qos_params.h
>> @@ -45,4 +45,6 @@ int pm_qos_add_notifier(int class, struct notifier_block *notifier);
>>  int pm_qos_remove_notifier(int class, struct notifier_block *notifier);
>>  int pm_qos_request_active(struct pm_qos_request_list *req);
>>
>> +void pm_qos_dev_wakeup_lat_init(struct device *dev);
>> +void pm_qos_dev_wakeup_lat_deinit(struct device *dev);
>>  #endif
>> diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c
>> index d61c8e5..6f25ccb 100644
>> --- a/kernel/pm_qos_params.c
>> +++ b/kernel/pm_qos_params.c
>> @@ -275,11 +275,21 @@ void pm_qos_add_request(struct pm_qos_request_list *pm_qos_req,
>>       struct pm_qos_object *o =  pm_qos_array[pm_qos_params->class];
>>       int new_value;
>>
>> -     if ((pm_qos_params->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
>> -         (pm_qos_request_active(pm_qos_req))) {
>> -             WARN(1, KERN_ERR "pm_qos_add_request() called for already "
>> -                  "added request\n");
>> -             return;
>> +     if (pm_qos_params->class == PM_QOS_DEV_WAKEUP_LATENCY) {
>> +             if (!pm_qos_params->dev) {
>> +                     WARN(1, KERN_ERR "pm_qos_add_request() called for "
>> +                             "invalid device\n");
>> +                     return;
>> +             }
>> +             /* Silently return if the device is being released */
>> +             if (!pm_qos_params->dev->power.wakeup_lat_init)
>> +                     return;
>> +     } else {
>> +             if (pm_qos_request_active(pm_qos_req)) {
>> +                     WARN(1, KERN_ERR "pm_qos_add_request() called for "
>> +                             "already added request\n");
>> +                     return;
>> +             }
>>       }
>>
>>       if (pm_qos_params->value == PM_QOS_DEFAULT_VALUE)
>> @@ -312,11 +322,16 @@ void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req,
>>       if (!pm_qos_req) /*guard against callers passing in null */
>>               return;
>>
>> -     if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
>> -         (!pm_qos_request_active(pm_qos_req))) {
>> -             WARN(1, KERN_ERR "pm_qos_update_request() called for unknown "
>> -                  "object\n");
>> -             return;
>> +     if (pm_qos_req->class == PM_QOS_DEV_WAKEUP_LATENCY) {
>> +             /* Silently return if the device is being released */
>> +             if (!pm_qos_req->dev->power.wakeup_lat_init)
>> +                     return;
>> +     } else {
>> +             if (!pm_qos_request_active(pm_qos_req)) {
>> +                     WARN(1, KERN_ERR "pm_qos_update_request() called "
>> +                             "for unknown object\n");
>> +                     return;
>> +             }
>>       }
>>
>>       if (new_value == PM_QOS_DEFAULT_VALUE)
>> @@ -343,11 +358,16 @@ void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req)
>>               return;
>>               /* silent return to keep pcm code cleaner */
>>
>> -     if ((pm_qos_req->class != PM_QOS_DEV_WAKEUP_LATENCY) &&
>> -         (!pm_qos_request_active(pm_qos_req))) {
>> -             WARN(1, KERN_ERR "pm_qos_remove_request() called for unknown "
>> -                  "object\n");
>> +     if (pm_qos_req->class == PM_QOS_DEV_WAKEUP_LATENCY) {
>> +             /* Silently return if the device is being released */
>> +             if (!pm_qos_req->dev->power.wakeup_lat_init)
>> +                     return;
>> +     } else {
>> +             if (!pm_qos_request_active(pm_qos_req)) {
>> +                     WARN(1, KERN_ERR "pm_qos_remove_request() called "
>> +                             "for unknown object\n");
>>               return;
>> +             }
>>       }
>>
>>       update_target(pm_qos_req, 1, PM_QOS_DEFAULT_VALUE);
>> @@ -393,6 +413,28 @@ int pm_qos_remove_notifier(int class, struct notifier_block *notifier)
>>  }
>>  EXPORT_SYMBOL_GPL(pm_qos_remove_notifier);
>>
>> +/* Called from the device PM subsystem at device init */
>> +void pm_qos_dev_wakeup_lat_init(struct device *dev)
>> +{
>> +     plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
>> +     dev->power.wakeup_lat_init = 1;
>> +}
>> +
>> +/* Called from the device PM subsystem at device release */
>> +void pm_qos_dev_wakeup_lat_deinit(struct device *dev)
>> +{
>> +     struct pm_qos_request_list *req, *tmp;
>> +
>> +     dev->power.wakeup_lat_init = 0;
>> +
>> +     /* Flush the constraints list for the device */
>> +     plist_for_each_entry_safe(req, tmp,
>> +                               &dev->power.wakeup_lat_plist_head,
>> +                               list)
>> +             update_target(req, 1, PM_QOS_DEFAULT_VALUE);
>> +     plist_head_init(&dev->power.wakeup_lat_plist_head, &dev->power.lock);
>> +}
>> +
>>  static int pm_qos_power_open(struct inode *inode, struct file *filp)
>>  {
>>       struct pm_qos_parameters pm_qos_params;
>>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class
  2011-07-02 19:20 ` Rafael J. Wysocki
  2011-07-04  7:16   ` Vishwanath Sripathy
  2011-07-20  9:26   ` Jean Pihet
@ 2011-07-20  9:26   ` Jean Pihet
  2 siblings, 0 replies; 122+ messages in thread
From: Jean Pihet @ 2011-07-20  9:26 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: markgross, Linux PM mailing list, linux-omap, Jean Pihet

Hi Rafael,

2011/7/2 Rafael J. Wysocki <rjw@sisk.pl>:
> Hi,
>
> On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
>> From: Jean Pihet <j-pihet@ti.com>
>>
>> This patch set is in an RFC state, for review and comments.
>
> First off, I'm sorry I couldn't review the patchset earlier.
Thank you very much for reviewing the patches!

>
>> In order to implement the new class in PM QoS the following changes have been
>> made:
>>
>> 1. Add a new PM QoS class for device wake-up constraints
>> (PM_QOS_DEV_WAKEUP_LATENCY).
>> Due to the per-device nature of the new class the constraints lists are stored
>> inside the device dev_pm_info struct instead of the internal per-class
>> constraints lists.
>> The new class is only available from kernel drivers and so is not exported to
>> user space.
>
> Have you considered a design in which multiple devices may use the same
> list of constraints?  It seems plausible that the constraints will be the
> same, for example, for all Ethernet adapters in the system, in which case it
> will be wasteful to duplicate the list of constraints for each of them.
How would the devices be grouped together? Today it looks like the
network throughput constraints from the device drivers are not used at
all but rather use the CPU_DMA latency API.

>
>> 2. Added a notification of device insertion/removal from the device PM framework
>> to PM QoS.
>> This allows to init/de-init the per-device constraints list upon device insertion
>> and removal.
>> RFC state for comments and review, barely tested
>
> I need to have a look at the details, but in principle this means that the
> per-device lists will be usable only after the devices have been registered.
> In particular, this means that it will only be possible to add new constraints
> after registering the device, which may be too late for some use cases.
Hmm I wonder how to solve this issue. How to manage constraints for a
non-present (not yet present or already removed) device? The CPU_DMA
latency constraint API might be used in those cases.

>
>> 3. Make the pm_qos_add_request API more generic by using a
>> struct pm_qos_parameters parameter. This allows easy extension in the future.
>>
>> 4. Upon a change of the strongest constraint in the PM_QOS_DEV_WAKEUP_LATENCY
>> class a notification chain mechanism is used to take action on the system.
>> This is the proposed way to have PM QoS and the platform dependant code to
>> interact with each other, cf. 4 below.
>
> I guess you mean 5.?
Yes

>
> I think we will need something in addition to the notifier here.  For example,
> I wouldn't like any core code, like runtime PM or cpuidle, to have to register
> a notifier with PM QoS.
I am not following this. Can you elaborate a bit?

>
>> The notification mechanism now passes the constraint request struct ptr in
>> order for the notifier callback to have access to the full set of constraint
>> data, e.g. the struct device ptr.
>>
>> 5. cpuidle interaction with the OMAP3 cpuidle handler
>> Since cpuidle is a CPU centric framework it decides the MPU next power state
>> based on the MPU exit_latency and target_residency figures.
>>
>> The rest of the power domains get their next power state programmed from
>> the PM_QOS_DEV_WAKEUP_LATENCY class of the PM QoS framework, via the device
>> wake-up latency constraints.
>>
>> Note: the exit_latency and target_residency figures of the MPU include the MPU
>> itself and the peripherals needed for the MPU to execute instructions (e.g.
>> main memory, caches, IRQ controller, MMU etc).
>> Some of those peripherals can belong to other power domains than the MPU
>> subsystem and so the corresponding latencies must be included in those figures.
>>
>> 6. Update the pm_qos_add_request callers to the generic API
>>
>> 7. Minor clean-ups and rename of struct fields
>>
>> Questions:
>> 1. How to retrieve the device ptr from a given device driver in order to add
>> a constraint on it?
>> 2. The device struct has recently been extended with the power domain
>> information. Can this be used to apply the constraints on power domains?
>
> Yes, it can in principle, but that will require some work.
>
>> On-going developments, patches in preparation:
>> 1. write Documentation for the new PM QoS class
>
> I'd wait with that until the code has settled.
Ok that was the intention to write the doc once for good.

>
>> 2. validate the constraints framework on OMAP4 HW (done on OMAP3)
>> 3. refine the power domains wake-up latency and the cpuidle figures
>>
>> Based on the master branch of the linux-omap git tree (3.0.0-rc3). Compile
>> tested using OMAP and x86 generic defconfigs.
>> Tested on OMAP3 Beagleboard (ES2.x) with full RETention and OFF modes.
>
> More detailed comments will follow.
>
> Thanks,
> Rafael
>

Thanks a lot,
Jean

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class
  2011-07-02 19:20 ` Rafael J. Wysocki
  2011-07-04  7:16   ` Vishwanath Sripathy
@ 2011-07-20  9:26   ` Jean Pihet
  2011-07-20 13:22     ` mark gross
  2011-07-20 13:22     ` mark gross
  2011-07-20  9:26   ` Jean Pihet
  2 siblings, 2 replies; 122+ messages in thread
From: Jean Pihet @ 2011-07-20  9:26 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Paul Walmsley, Kevin Hilman, Magnus Damm, Linux PM mailing list,
	linux-omap, markgross, Jean Pihet

Hi Rafael,

2011/7/2 Rafael J. Wysocki <rjw@sisk.pl>:
> Hi,
>
> On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
>> From: Jean Pihet <j-pihet@ti.com>
>>
>> This patch set is in an RFC state, for review and comments.
>
> First off, I'm sorry I couldn't review the patchset earlier.
Thank you very much for reviewing the patches!

>
>> In order to implement the new class in PM QoS the following changes have been
>> made:
>>
>> 1. Add a new PM QoS class for device wake-up constraints
>> (PM_QOS_DEV_WAKEUP_LATENCY).
>> Due to the per-device nature of the new class the constraints lists are stored
>> inside the device dev_pm_info struct instead of the internal per-class
>> constraints lists.
>> The new class is only available from kernel drivers and so is not exported to
>> user space.
>
> Have you considered a design in which multiple devices may use the same
> list of constraints?  It seems plausible that the constraints will be the
> same, for example, for all Ethernet adapters in the system, in which case it
> will be wasteful to duplicate the list of constraints for each of them.
How would the devices be grouped together? Today it looks like the
network throughput constraints from the device drivers are not used at
all but rather use the CPU_DMA latency API.

>
>> 2. Added a notification of device insertion/removal from the device PM framework
>> to PM QoS.
>> This allows to init/de-init the per-device constraints list upon device insertion
>> and removal.
>> RFC state for comments and review, barely tested
>
> I need to have a look at the details, but in principle this means that the
> per-device lists will be usable only after the devices have been registered.
> In particular, this means that it will only be possible to add new constraints
> after registering the device, which may be too late for some use cases.
Hmm I wonder how to solve this issue. How to manage constraints for a
non-present (not yet present or already removed) device? The CPU_DMA
latency constraint API might be used in those cases.

>
>> 3. Make the pm_qos_add_request API more generic by using a
>> struct pm_qos_parameters parameter. This allows easy extension in the future.
>>
>> 4. Upon a change of the strongest constraint in the PM_QOS_DEV_WAKEUP_LATENCY
>> class a notification chain mechanism is used to take action on the system.
>> This is the proposed way to have PM QoS and the platform dependant code to
>> interact with each other, cf. 4 below.
>
> I guess you mean 5.?
Yes

>
> I think we will need something in addition to the notifier here.  For example,
> I wouldn't like any core code, like runtime PM or cpuidle, to have to register
> a notifier with PM QoS.
I am not following this. Can you elaborate a bit?

>
>> The notification mechanism now passes the constraint request struct ptr in
>> order for the notifier callback to have access to the full set of constraint
>> data, e.g. the struct device ptr.
>>
>> 5. cpuidle interaction with the OMAP3 cpuidle handler
>> Since cpuidle is a CPU centric framework it decides the MPU next power state
>> based on the MPU exit_latency and target_residency figures.
>>
>> The rest of the power domains get their next power state programmed from
>> the PM_QOS_DEV_WAKEUP_LATENCY class of the PM QoS framework, via the device
>> wake-up latency constraints.
>>
>> Note: the exit_latency and target_residency figures of the MPU include the MPU
>> itself and the peripherals needed for the MPU to execute instructions (e.g.
>> main memory, caches, IRQ controller, MMU etc).
>> Some of those peripherals can belong to other power domains than the MPU
>> subsystem and so the corresponding latencies must be included in those figures.
>>
>> 6. Update the pm_qos_add_request callers to the generic API
>>
>> 7. Minor clean-ups and rename of struct fields
>>
>> Questions:
>> 1. How to retrieve the device ptr from a given device driver in order to add
>> a constraint on it?
>> 2. The device struct has recently been extended with the power domain
>> information. Can this be used to apply the constraints on power domains?
>
> Yes, it can in principle, but that will require some work.
>
>> On-going developments, patches in preparation:
>> 1. write Documentation for the new PM QoS class
>
> I'd wait with that until the code has settled.
Ok that was the intention to write the doc once for good.

>
>> 2. validate the constraints framework on OMAP4 HW (done on OMAP3)
>> 3. refine the power domains wake-up latency and the cpuidle figures
>>
>> Based on the master branch of the linux-omap git tree (3.0.0-rc3). Compile
>> tested using OMAP and x86 generic defconfigs.
>> Tested on OMAP3 Beagleboard (ES2.x) with full RETention and OFF modes.
>
> More detailed comments will follow.
>
> Thanks,
> Rafael
>

Thanks a lot,
Jean
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class
  2011-07-20  9:26   ` Jean Pihet
@ 2011-07-20 13:22     ` mark gross
  2011-07-20 13:22     ` mark gross
  1 sibling, 0 replies; 122+ messages in thread
From: mark gross @ 2011-07-20 13:22 UTC (permalink / raw)
  To: Jean Pihet; +Cc: markgross, Linux PM mailing list, linux-omap, Jean Pihet

On Wed, Jul 20, 2011 at 11:26:13AM +0200, Jean Pihet wrote:
> Hi Rafael,
> 
> 2011/7/2 Rafael J. Wysocki <rjw@sisk.pl>:
> > Hi,
> >
> > On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
> >> From: Jean Pihet <j-pihet@ti.com>
> >>
> >> This patch set is in an RFC state, for review and comments.
> >
> > First off, I'm sorry I couldn't review the patchset earlier.
> Thank you very much for reviewing the patches!
> 
> >
> >> In order to implement the new class in PM QoS the following changes have been
> >> made:
> >>
> >> 1. Add a new PM QoS class for device wake-up constraints
> >> (PM_QOS_DEV_WAKEUP_LATENCY).
> >> Due to the per-device nature of the new class the constraints lists are stored
> >> inside the device dev_pm_info struct instead of the internal per-class
> >> constraints lists.
> >> The new class is only available from kernel drivers and so is not exported to
> >> user space.
> >
> > Have you considered a design in which multiple devices may use the same
> > list of constraints?  It seems plausible that the constraints will be the
> > same, for example, for all Ethernet adapters in the system, in which case it
> > will be wasteful to duplicate the list of constraints for each of them.
> How would the devices be grouped together? Today it looks like the
> network throughput constraints from the device drivers are not used at
> all but rather use the CPU_DMA latency API.

This is a challenge.  Over the pats 2 years I've see basically 2 types of
PM_QoS applications.  Global or subsystem qos requests and local or
device qos requests.

Global are things like use cpu_dma_latency to block C-states or Network
latency to shape traffic into more bursty bundles.  (let the modem
sleep more).

Local are things like a spi modem or camera falls over if the clock gets
gated for more than 400uS during some critical section.

Further there is an API gap in the ability to express things like
Network latency where multiple NIC's are present and you want different
latencies for each NIC.  (note: I can see such a need coming for
multi-core CPUs someday as well.  cpu0 needs to stay hot but the others
can have infinite latency--or something like that)

BTW: I don't have any good ideas for this API gap at this time.

Part of me feels that every "bus" driver should include an implicit
governor infrastructure (like CPU freq or cpu idle, perhaps both one for
throughput and one for latency) and a QoS like list that is taken into
account on Runtime PM operations.  This would be ok for the local users
of pm_qos.


FWIW I think it should be baked into runtime pm.



> >
> >> 2. Added a notification of device insertion/removal from the device PM framework
> >> to PM QoS.
> >> This allows to init/de-init the per-device constraints list upon device insertion
> >> and removal.
> >> RFC state for comments and review, barely tested
> >
> > I need to have a look at the details, but in principle this means that the
> > per-device lists will be usable only after the devices have been registered.
> > In particular, this means that it will only be possible to add new constraints
> > after registering the device, which may be too late for some use cases.
> Hmm I wonder how to solve this issue. How to manage constraints for a
> non-present (not yet present or already removed) device? The CPU_DMA
> latency constraint API might be used in those cases.

Bus drivers would tend to be always loaded so such constraints could be
pre-registered there.


--mark


> >
> >> 3. Make the pm_qos_add_request API more generic by using a
> >> struct pm_qos_parameters parameter. This allows easy extension in the future.
> >>
> >> 4. Upon a change of the strongest constraint in the PM_QOS_DEV_WAKEUP_LATENCY
> >> class a notification chain mechanism is used to take action on the system.
> >> This is the proposed way to have PM QoS and the platform dependant code to
> >> interact with each other, cf. 4 below.
> >
> > I guess you mean 5.?
> Yes
> 
> >
> > I think we will need something in addition to the notifier here.  For example,
> > I wouldn't like any core code, like runtime PM or cpuidle, to have to register
> > a notifier with PM QoS.
> I am not following this. Can you elaborate a bit?
> 
> >
> >> The notification mechanism now passes the constraint request struct ptr in
> >> order for the notifier callback to have access to the full set of constraint
> >> data, e.g. the struct device ptr.
> >>
> >> 5. cpuidle interaction with the OMAP3 cpuidle handler
> >> Since cpuidle is a CPU centric framework it decides the MPU next power state
> >> based on the MPU exit_latency and target_residency figures.
> >>
> >> The rest of the power domains get their next power state programmed from
> >> the PM_QOS_DEV_WAKEUP_LATENCY class of the PM QoS framework, via the device
> >> wake-up latency constraints.
> >>
> >> Note: the exit_latency and target_residency figures of the MPU include the MPU
> >> itself and the peripherals needed for the MPU to execute instructions (e.g.
> >> main memory, caches, IRQ controller, MMU etc).
> >> Some of those peripherals can belong to other power domains than the MPU
> >> subsystem and so the corresponding latencies must be included in those figures.
> >>
> >> 6. Update the pm_qos_add_request callers to the generic API
> >>
> >> 7. Minor clean-ups and rename of struct fields
> >>
> >> Questions:
> >> 1. How to retrieve the device ptr from a given device driver in order to add
> >> a constraint on it?
> >> 2. The device struct has recently been extended with the power domain
> >> information. Can this be used to apply the constraints on power domains?
> >
> > Yes, it can in principle, but that will require some work.
> >
> >> On-going developments, patches in preparation:
> >> 1. write Documentation for the new PM QoS class
> >
> > I'd wait with that until the code has settled.
> Ok that was the intention to write the doc once for good.
> 
> >
> >> 2. validate the constraints framework on OMAP4 HW (done on OMAP3)
> >> 3. refine the power domains wake-up latency and the cpuidle figures
> >>
> >> Based on the master branch of the linux-omap git tree (3.0.0-rc3). Compile
> >> tested using OMAP and x86 generic defconfigs.
> >> Tested on OMAP3 Beagleboard (ES2.x) with full RETention and OFF modes.
> >
> > More detailed comments will follow.
> >
> > Thanks,
> > Rafael
> >
> 
> Thanks a lot,
> Jean

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class
  2011-07-20  9:26   ` Jean Pihet
  2011-07-20 13:22     ` mark gross
@ 2011-07-20 13:22     ` mark gross
  1 sibling, 0 replies; 122+ messages in thread
From: mark gross @ 2011-07-20 13:22 UTC (permalink / raw)
  To: Jean Pihet
  Cc: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list, linux-omap, markgross, Jean Pihet

On Wed, Jul 20, 2011 at 11:26:13AM +0200, Jean Pihet wrote:
> Hi Rafael,
> 
> 2011/7/2 Rafael J. Wysocki <rjw@sisk.pl>:
> > Hi,
> >
> > On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
> >> From: Jean Pihet <j-pihet@ti.com>
> >>
> >> This patch set is in an RFC state, for review and comments.
> >
> > First off, I'm sorry I couldn't review the patchset earlier.
> Thank you very much for reviewing the patches!
> 
> >
> >> In order to implement the new class in PM QoS the following changes have been
> >> made:
> >>
> >> 1. Add a new PM QoS class for device wake-up constraints
> >> (PM_QOS_DEV_WAKEUP_LATENCY).
> >> Due to the per-device nature of the new class the constraints lists are stored
> >> inside the device dev_pm_info struct instead of the internal per-class
> >> constraints lists.
> >> The new class is only available from kernel drivers and so is not exported to
> >> user space.
> >
> > Have you considered a design in which multiple devices may use the same
> > list of constraints?  It seems plausible that the constraints will be the
> > same, for example, for all Ethernet adapters in the system, in which case it
> > will be wasteful to duplicate the list of constraints for each of them.
> How would the devices be grouped together? Today it looks like the
> network throughput constraints from the device drivers are not used at
> all but rather use the CPU_DMA latency API.

This is a challenge.  Over the pats 2 years I've see basically 2 types of
PM_QoS applications.  Global or subsystem qos requests and local or
device qos requests.

Global are things like use cpu_dma_latency to block C-states or Network
latency to shape traffic into more bursty bundles.  (let the modem
sleep more).

Local are things like a spi modem or camera falls over if the clock gets
gated for more than 400uS during some critical section.

Further there is an API gap in the ability to express things like
Network latency where multiple NIC's are present and you want different
latencies for each NIC.  (note: I can see such a need coming for
multi-core CPUs someday as well.  cpu0 needs to stay hot but the others
can have infinite latency--or something like that)

BTW: I don't have any good ideas for this API gap at this time.

Part of me feels that every "bus" driver should include an implicit
governor infrastructure (like CPU freq or cpu idle, perhaps both one for
throughput and one for latency) and a QoS like list that is taken into
account on Runtime PM operations.  This would be ok for the local users
of pm_qos.


FWIW I think it should be baked into runtime pm.



> >
> >> 2. Added a notification of device insertion/removal from the device PM framework
> >> to PM QoS.
> >> This allows to init/de-init the per-device constraints list upon device insertion
> >> and removal.
> >> RFC state for comments and review, barely tested
> >
> > I need to have a look at the details, but in principle this means that the
> > per-device lists will be usable only after the devices have been registered.
> > In particular, this means that it will only be possible to add new constraints
> > after registering the device, which may be too late for some use cases.
> Hmm I wonder how to solve this issue. How to manage constraints for a
> non-present (not yet present or already removed) device? The CPU_DMA
> latency constraint API might be used in those cases.

Bus drivers would tend to be always loaded so such constraints could be
pre-registered there.


--mark


> >
> >> 3. Make the pm_qos_add_request API more generic by using a
> >> struct pm_qos_parameters parameter. This allows easy extension in the future.
> >>
> >> 4. Upon a change of the strongest constraint in the PM_QOS_DEV_WAKEUP_LATENCY
> >> class a notification chain mechanism is used to take action on the system.
> >> This is the proposed way to have PM QoS and the platform dependant code to
> >> interact with each other, cf. 4 below.
> >
> > I guess you mean 5.?
> Yes
> 
> >
> > I think we will need something in addition to the notifier here.  For example,
> > I wouldn't like any core code, like runtime PM or cpuidle, to have to register
> > a notifier with PM QoS.
> I am not following this. Can you elaborate a bit?
> 
> >
> >> The notification mechanism now passes the constraint request struct ptr in
> >> order for the notifier callback to have access to the full set of constraint
> >> data, e.g. the struct device ptr.
> >>
> >> 5. cpuidle interaction with the OMAP3 cpuidle handler
> >> Since cpuidle is a CPU centric framework it decides the MPU next power state
> >> based on the MPU exit_latency and target_residency figures.
> >>
> >> The rest of the power domains get their next power state programmed from
> >> the PM_QOS_DEV_WAKEUP_LATENCY class of the PM QoS framework, via the device
> >> wake-up latency constraints.
> >>
> >> Note: the exit_latency and target_residency figures of the MPU include the MPU
> >> itself and the peripherals needed for the MPU to execute instructions (e.g.
> >> main memory, caches, IRQ controller, MMU etc).
> >> Some of those peripherals can belong to other power domains than the MPU
> >> subsystem and so the corresponding latencies must be included in those figures.
> >>
> >> 6. Update the pm_qos_add_request callers to the generic API
> >>
> >> 7. Minor clean-ups and rename of struct fields
> >>
> >> Questions:
> >> 1. How to retrieve the device ptr from a given device driver in order to add
> >> a constraint on it?
> >> 2. The device struct has recently been extended with the power domain
> >> information. Can this be used to apply the constraints on power domains?
> >
> > Yes, it can in principle, but that will require some work.
> >
> >> On-going developments, patches in preparation:
> >> 1. write Documentation for the new PM QoS class
> >
> > I'd wait with that until the code has settled.
> Ok that was the intention to write the doc once for good.
> 
> >
> >> 2. validate the constraints framework on OMAP4 HW (done on OMAP3)
> >> 3. refine the power domains wake-up latency and the cpuidle figures
> >>
> >> Based on the master branch of the linux-omap git tree (3.0.0-rc3). Compile
> >> tested using OMAP and x86 generic defconfigs.
> >> Tested on OMAP3 Beagleboard (ES2.x) with full RETention and OFF modes.
> >
> > More detailed comments will follow.
> >
> > Thanks,
> > Rafael
> >
> 
> Thanks a lot,
> Jean
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-07-02 21:10   ` Rafael J. Wysocki
                       ` (2 preceding siblings ...)
  2011-08-02 17:49     ` Kevin Hilman
@ 2011-08-02 17:49     ` Kevin Hilman
  3 siblings, 0 replies; 122+ messages in thread
From: Kevin Hilman @ 2011-08-02 17:49 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: markgross, Linux PM mailing list, linux-omap, Jean Pihet

"Rafael J. Wysocki" <rjw@sisk.pl> writes:

> Hi,
>
> On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
>> From: Jean Pihet <j-pihet@ti.com>
>> 
>> - add a new PM QoS class PM_QOS_DEV_WAKEUP_LATENCY for device wake-up
>> constraints. Due to the per-device nature of the new class the constraints
>> list is stored inside the device dev_pm_info struct instead of the internal
>> per-class constraints lists.
>
> I think PM_QOS_DEV_LATENCY might be a better name.
>
>> The new class is only available from kernel drivers and so is not exported
>> to user space.
>
> It should be available to user space, however, because in many cases drivers
> simply have no idea what values to use (after all, the use decides if he
> wants to trade worse video playback quality for better battery life, for
> example).
>

FWIW, I think it's wrong to expose the raw per-device constraints
directly to userspace.

I think it's the responsibility of the subsystems (video, audio, input,
etc.) to expose QoS knobs to userspace as they see fit and now allow
userspace to tinker directly with QoS constraints.

Kevin

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-07-02 21:10   ` Rafael J. Wysocki
  2011-07-20  9:13     ` Jean Pihet
  2011-07-20  9:13     ` Jean Pihet
@ 2011-08-02 17:49     ` Kevin Hilman
  2011-08-02 20:19       ` Rafael J. Wysocki
  2011-08-02 20:19       ` Rafael J. Wysocki
  2011-08-02 17:49     ` Kevin Hilman
  3 siblings, 2 replies; 122+ messages in thread
From: Kevin Hilman @ 2011-08-02 17:49 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: jean.pihet, Paul Walmsley, Magnus Damm, Linux PM mailing list,
	linux-omap, markgross, Jean Pihet

"Rafael J. Wysocki" <rjw@sisk.pl> writes:

> Hi,
>
> On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
>> From: Jean Pihet <j-pihet@ti.com>
>> 
>> - add a new PM QoS class PM_QOS_DEV_WAKEUP_LATENCY for device wake-up
>> constraints. Due to the per-device nature of the new class the constraints
>> list is stored inside the device dev_pm_info struct instead of the internal
>> per-class constraints lists.
>
> I think PM_QOS_DEV_LATENCY might be a better name.
>
>> The new class is only available from kernel drivers and so is not exported
>> to user space.
>
> It should be available to user space, however, because in many cases drivers
> simply have no idea what values to use (after all, the use decides if he
> wants to trade worse video playback quality for better battery life, for
> example).
>

FWIW, I think it's wrong to expose the raw per-device constraints
directly to userspace.

I think it's the responsibility of the subsystems (video, audio, input,
etc.) to expose QoS knobs to userspace as they see fit and now allow
userspace to tinker directly with QoS constraints.

Kevin


^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-02 17:49     ` Kevin Hilman
@ 2011-08-02 20:19       ` Rafael J. Wysocki
  2011-08-02 20:19       ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-02 20:19 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: markgross, Linux PM mailing list, linux-omap, Jean Pihet

On Tuesday, August 02, 2011, Kevin Hilman wrote:
> "Rafael J. Wysocki" <rjw@sisk.pl> writes:
> 
> > Hi,
> >
> > On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
> >> From: Jean Pihet <j-pihet@ti.com>
> >> 
> >> - add a new PM QoS class PM_QOS_DEV_WAKEUP_LATENCY for device wake-up
> >> constraints. Due to the per-device nature of the new class the constraints
> >> list is stored inside the device dev_pm_info struct instead of the internal
> >> per-class constraints lists.
> >
> > I think PM_QOS_DEV_LATENCY might be a better name.
> >
> >> The new class is only available from kernel drivers and so is not exported
> >> to user space.
> >
> > It should be available to user space, however, because in many cases drivers
> > simply have no idea what values to use (after all, the use decides if he
> > wants to trade worse video playback quality for better battery life, for
> > example).
> >
> 
> FWIW, I think it's wrong to expose the raw per-device constraints
> directly to userspace.
> 
> I think it's the responsibility of the subsystems (video, audio, input,
> etc.) to expose QoS knobs to userspace as they see fit and now allow
> userspace to tinker directly with QoS constraints.

This assumes that those "subsystems" or rather "frameworks" (a bus type or
a device class is a subsystem in the terminology used throughout the PM
documentation) will (a) know about PM QoS and (b) will care to handle it.
Both (a) and (b) seem to be unrealistic IMHO.

We already export wakeup and runtime PM knobs per device via sysfs and
I'm not so sure why PM QoS is different in that respect.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-02 17:49     ` Kevin Hilman
  2011-08-02 20:19       ` Rafael J. Wysocki
@ 2011-08-02 20:19       ` Rafael J. Wysocki
  2011-08-02 21:23         ` Kevin Hilman
  2011-08-02 21:23         ` Kevin Hilman
  1 sibling, 2 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-02 20:19 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: jean.pihet, Paul Walmsley, Magnus Damm, Linux PM mailing list,
	linux-omap, markgross, Jean Pihet

On Tuesday, August 02, 2011, Kevin Hilman wrote:
> "Rafael J. Wysocki" <rjw@sisk.pl> writes:
> 
> > Hi,
> >
> > On Thursday, June 30, 2011, jean.pihet@newoldbits.com wrote:
> >> From: Jean Pihet <j-pihet@ti.com>
> >> 
> >> - add a new PM QoS class PM_QOS_DEV_WAKEUP_LATENCY for device wake-up
> >> constraints. Due to the per-device nature of the new class the constraints
> >> list is stored inside the device dev_pm_info struct instead of the internal
> >> per-class constraints lists.
> >
> > I think PM_QOS_DEV_LATENCY might be a better name.
> >
> >> The new class is only available from kernel drivers and so is not exported
> >> to user space.
> >
> > It should be available to user space, however, because in many cases drivers
> > simply have no idea what values to use (after all, the use decides if he
> > wants to trade worse video playback quality for better battery life, for
> > example).
> >
> 
> FWIW, I think it's wrong to expose the raw per-device constraints
> directly to userspace.
> 
> I think it's the responsibility of the subsystems (video, audio, input,
> etc.) to expose QoS knobs to userspace as they see fit and now allow
> userspace to tinker directly with QoS constraints.

This assumes that those "subsystems" or rather "frameworks" (a bus type or
a device class is a subsystem in the terminology used throughout the PM
documentation) will (a) know about PM QoS and (b) will care to handle it.
Both (a) and (b) seem to be unrealistic IMHO.

We already export wakeup and runtime PM knobs per device via sysfs and
I'm not so sure why PM QoS is different in that respect.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-02 20:19       ` Rafael J. Wysocki
  2011-08-02 21:23         ` Kevin Hilman
@ 2011-08-02 21:23         ` Kevin Hilman
  1 sibling, 0 replies; 122+ messages in thread
From: Kevin Hilman @ 2011-08-02 21:23 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: markgross, Mark Brown, Linux PM mailing list, linux-omap, Jean Pihet

[adding Mark Brown as we discussed similar topics a couple plumbers ago]

"Rafael J. Wysocki" <rjw@sisk.pl> writes:

[...]

>> >> The new class is only available from kernel drivers and so is not exported
>> >> to user space.
>> >
>> > It should be available to user space, however, because in many cases drivers
>> > simply have no idea what values to use (after all, the use decides if he
>> > wants to trade worse video playback quality for better battery life, for
>> > example).
>> >
>> 
>> FWIW, I think it's wrong to expose the raw per-device constraints
>> directly to userspace.
>> 
>> I think it's the responsibility of the subsystems (video, audio, input,
>> etc.) to expose QoS knobs to userspace as they see fit and now allow
>> userspace to tinker directly with QoS constraints.
>
> This assumes that those "subsystems" or rather "frameworks" (a bus type or
> a device class is a subsystem in the terminology used throughout the PM
> documentation) will (a) know about PM QoS and (b) will care to handle it.
> Both (a) and (b) seem to be unrealistic IMHO.

I disagree and think that both are quite realistic (mainly because they
exist today, albiet mostly out of tree because no generic QoS framework
exist.  e.g. on OMAP, we have OMAP-specific *kernel* APIs for requesting
per-device wakeup latencies, and drivers and frameworks are using them.)

Most of these frameworks already have QoS constraints/requirements but
have no generic way to express them.  That's why we're pushing for a
generic constraints framework.

Consider video for example.  It's the kernel-side drivers, not user
space apps, that know about the latency or throughput constraints based
on e.g. frame rate, bytes/pixel, double/triple buffering, PIP, multiple
displays, etc. etc.   

In this case, the video framework (V4L2) might not want any knobs
exposed to userspace because userspace simply doesn't have the knowledge
to set appropriate constraints.  I'm less familiar with audio, but I
believe audio would be similar (sample rate, number of channels, mixing
with other concurrent audio streams, etc. etc. are all known by the
kernel-side code.)

On the other hand, consider touchscreen.  Touchscreens have a
configurable sample rate which allows a trade-off between power savings
and accuracy.  For example, low accuracy (and thus low power) would be
fine for a UI which is only taking finger gestures, but if the
application was doing handwriting recognition with a stylus, it would
likely want higher accuracy (and consume more power.)

In this case, the kernel driver has no way of knowing what the
application is doing, so some way for touchscreen apps to request this
kind of constraint would be required.

My point is it should be up to each framework (audio, video,
input/touchscreen) to expose a userspace interface to their users that
makes sense for the *specific needs* of the framework.

Using the above examples, audio and video might not need (or want) to
expose anything to userspace, where touchscreen would.  IMO, it would be
much more obvious for a touchscreen app to use a new API in tslib (which
it is already using) to set its constraints rather than having to use
tslib for most things but a sysfs file for QoS.

> We already export wakeup and runtime PM knobs per device via sysfs and
> I'm not so sure why PM QoS is different in that respect.

As stated above, because for many frameworks userspace simply does not
have all (or any) of the knowledge to set the right constraints.

Kevin

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-02 20:19       ` Rafael J. Wysocki
@ 2011-08-02 21:23         ` Kevin Hilman
  2011-08-02 22:16           ` Rafael J. Wysocki
  2011-08-02 21:23         ` Kevin Hilman
  1 sibling, 1 reply; 122+ messages in thread
From: Kevin Hilman @ 2011-08-02 21:23 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: jean.pihet, Paul Walmsley, Magnus Damm, Linux PM mailing list,
	linux-omap, markgross, Jean Pihet, Mark Brown

[adding Mark Brown as we discussed similar topics a couple plumbers ago]

"Rafael J. Wysocki" <rjw@sisk.pl> writes:

[...]

>> >> The new class is only available from kernel drivers and so is not exported
>> >> to user space.
>> >
>> > It should be available to user space, however, because in many cases drivers
>> > simply have no idea what values to use (after all, the use decides if he
>> > wants to trade worse video playback quality for better battery life, for
>> > example).
>> >
>> 
>> FWIW, I think it's wrong to expose the raw per-device constraints
>> directly to userspace.
>> 
>> I think it's the responsibility of the subsystems (video, audio, input,
>> etc.) to expose QoS knobs to userspace as they see fit and now allow
>> userspace to tinker directly with QoS constraints.
>
> This assumes that those "subsystems" or rather "frameworks" (a bus type or
> a device class is a subsystem in the terminology used throughout the PM
> documentation) will (a) know about PM QoS and (b) will care to handle it.
> Both (a) and (b) seem to be unrealistic IMHO.

I disagree and think that both are quite realistic (mainly because they
exist today, albiet mostly out of tree because no generic QoS framework
exist.  e.g. on OMAP, we have OMAP-specific *kernel* APIs for requesting
per-device wakeup latencies, and drivers and frameworks are using them.)

Most of these frameworks already have QoS constraints/requirements but
have no generic way to express them.  That's why we're pushing for a
generic constraints framework.

Consider video for example.  It's the kernel-side drivers, not user
space apps, that know about the latency or throughput constraints based
on e.g. frame rate, bytes/pixel, double/triple buffering, PIP, multiple
displays, etc. etc.   

In this case, the video framework (V4L2) might not want any knobs
exposed to userspace because userspace simply doesn't have the knowledge
to set appropriate constraints.  I'm less familiar with audio, but I
believe audio would be similar (sample rate, number of channels, mixing
with other concurrent audio streams, etc. etc. are all known by the
kernel-side code.)

On the other hand, consider touchscreen.  Touchscreens have a
configurable sample rate which allows a trade-off between power savings
and accuracy.  For example, low accuracy (and thus low power) would be
fine for a UI which is only taking finger gestures, but if the
application was doing handwriting recognition with a stylus, it would
likely want higher accuracy (and consume more power.)

In this case, the kernel driver has no way of knowing what the
application is doing, so some way for touchscreen apps to request this
kind of constraint would be required.

My point is it should be up to each framework (audio, video,
input/touchscreen) to expose a userspace interface to their users that
makes sense for the *specific needs* of the framework.

Using the above examples, audio and video might not need (or want) to
expose anything to userspace, where touchscreen would.  IMO, it would be
much more obvious for a touchscreen app to use a new API in tslib (which
it is already using) to set its constraints rather than having to use
tslib for most things but a sysfs file for QoS.

> We already export wakeup and runtime PM knobs per device via sysfs and
> I'm not so sure why PM QoS is different in that respect.

As stated above, because for many frameworks userspace simply does not
have all (or any) of the knowledge to set the right constraints.

Kevin

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-02 21:23         ` Kevin Hilman
@ 2011-08-02 22:16           ` Rafael J. Wysocki
  2011-08-04 13:24             ` [linux-pm] " Mark Brown
  2011-08-04 13:24             ` Mark Brown
  0 siblings, 2 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-02 22:16 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: markgross, Mark Brown, Linux PM mailing list, linux-omap, Jean Pihet

On Tuesday, August 02, 2011, Kevin Hilman wrote:
> [adding Mark Brown as we discussed similar topics a couple plumbers ago]
> 
> "Rafael J. Wysocki" <rjw@sisk.pl> writes:
> 
> [...]
> 
> >> >> The new class is only available from kernel drivers and so is not exported
> >> >> to user space.
> >> >
> >> > It should be available to user space, however, because in many cases drivers
> >> > simply have no idea what values to use (after all, the use decides if he
> >> > wants to trade worse video playback quality for better battery life, for
> >> > example).
> >> >
> >> 
> >> FWIW, I think it's wrong to expose the raw per-device constraints
> >> directly to userspace.
> >> 
> >> I think it's the responsibility of the subsystems (video, audio, input,
> >> etc.) to expose QoS knobs to userspace as they see fit and now allow
> >> userspace to tinker directly with QoS constraints.
> >
> > This assumes that those "subsystems" or rather "frameworks" (a bus type or
> > a device class is a subsystem in the terminology used throughout the PM
> > documentation) will (a) know about PM QoS and (b) will care to handle it.
> > Both (a) and (b) seem to be unrealistic IMHO.
> 
> I disagree and think that both are quite realistic (mainly because they
> exist today, albiet mostly out of tree because no generic QoS framework
> exist.  e.g. on OMAP, we have OMAP-specific *kernel* APIs for requesting
> per-device wakeup latencies, and drivers and frameworks are using them.)

I'm sure there are frameworks using such things.  I'm also sure there
are frameworks that don't.  BTW, the "we have it out of the tree" argument is
not very useful, so I'd appreciate it if you didn't use it.

> Most of these frameworks already have QoS constraints/requirements but
> have no generic way to express them.  That's why we're pushing for a
> generic constraints framework.
> 
> Consider video for example.  It's the kernel-side drivers, not user
> space apps, that know about the latency or throughput constraints based
> on e.g. frame rate, bytes/pixel, double/triple buffering, PIP, multiple
> displays, etc. etc.   
> 
> In this case, the video framework (V4L2) might not want any knobs
> exposed to userspace because userspace simply doesn't have the knowledge
> to set appropriate constraints.  I'm less familiar with audio, but I
> believe audio would be similar (sample rate, number of channels, mixing
> with other concurrent audio streams, etc. etc. are all known by the
> kernel-side code.)
> 
> On the other hand, consider touchscreen.  Touchscreens have a
> configurable sample rate which allows a trade-off between power savings
> and accuracy.  For example, low accuracy (and thus low power) would be
> fine for a UI which is only taking finger gestures, but if the
> application was doing handwriting recognition with a stylus, it would
> likely want higher accuracy (and consume more power.)
> 
> In this case, the kernel driver has no way of knowing what the
> application is doing, so some way for touchscreen apps to request this
> kind of constraint would be required.
> 
> My point is it should be up to each framework (audio, video,
> input/touchscreen) to expose a userspace interface to their users that
> makes sense for the *specific needs* of the framework.
> 
> Using the above examples, audio and video might not need (or want) to
> expose anything to userspace, where touchscreen would.  IMO, it would be
> much more obvious for a touchscreen app to use a new API in tslib (which
> it is already using) to set its constraints rather than having to use
> tslib for most things but a sysfs file for QoS.
> 
> > We already export wakeup and runtime PM knobs per device via sysfs and
> > I'm not so sure why PM QoS is different in that respect.
> 
> As stated above, because for many frameworks userspace simply does not
> have all (or any) of the knowledge to set the right constraints.

I still don't understand what's wrong with allowing user space to _add_
requirements.  The will only override the drivers' or frameworks' requirements
if they are stronger, so the functionality shouldn't be hurt.  They may cause
some more energy to be used, but if user space wants that, it's pretty much
fine by me.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-02 22:16           ` Rafael J. Wysocki
  2011-08-04 13:24             ` [linux-pm] " Mark Brown
@ 2011-08-04 13:24             ` Mark Brown
  1 sibling, 0 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-04 13:24 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Wed, Aug 03, 2011 at 12:16:17AM +0200, Rafael J. Wysocki wrote:
> On Tuesday, August 02, 2011, Kevin Hilman wrote:

> > I disagree and think that both are quite realistic (mainly because they
> > exist today, albiet mostly out of tree because no generic QoS framework
> > exist.  e.g. on OMAP, we have OMAP-specific *kernel* APIs for requesting
> > per-device wakeup latencies, and drivers and frameworks are using them.)
> 
> I'm sure there are frameworks using such things.  I'm also sure there
> are frameworks that don't.  BTW, the "we have it out of the tree" argument is
> not very useful, so I'd appreciate it if you didn't use it.

It's useful to know if people have tried things; it doesn't mean it's
going to be OK for mainline but it is a data point.

> > In this case, the video framework (V4L2) might not want any knobs
> > exposed to userspace because userspace simply doesn't have the knowledge
> > to set appropriate constraints.  I'm less familiar with audio, but I
> > believe audio would be similar (sample rate, number of channels, mixing
> > with other concurrent audio streams, etc. etc. are all known by the
> > kernel-side code.)

Yeah, that sort of stuff and also data like wakeup latencies required to
service interrupts.

> I still don't understand what's wrong with allowing user space to _add_
> requirements.  The will only override the drivers' or frameworks' requirements
> if they are stronger, so the functionality shouldn't be hurt.  They may cause
> some more energy to be used, but if user space wants that, it's pretty much
> fine by me.

On the one hand that's true.  On the other hand that just seems like
going down a bad road where we have drivers that only work when run with
a magic userspace that may or may not be published which is just going
to make people miserable.  I'm not sure there are many people who would
choose to use more power without wanting some functional change so
presumably any users would be seeking to work around some kernel problem
and adding the user interface seems to be saying that this is OK,
expected and a natural part of power optimization.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-02 22:16           ` Rafael J. Wysocki
@ 2011-08-04 13:24             ` Mark Brown
  2011-08-04 19:15               ` Rafael J. Wysocki
  2011-08-04 19:15               ` Rafael J. Wysocki
  2011-08-04 13:24             ` Mark Brown
  1 sibling, 2 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-04 13:24 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Kevin Hilman, markgross, Linux PM mailing list, linux-omap, Jean Pihet

On Wed, Aug 03, 2011 at 12:16:17AM +0200, Rafael J. Wysocki wrote:
> On Tuesday, August 02, 2011, Kevin Hilman wrote:

> > I disagree and think that both are quite realistic (mainly because they
> > exist today, albiet mostly out of tree because no generic QoS framework
> > exist.  e.g. on OMAP, we have OMAP-specific *kernel* APIs for requesting
> > per-device wakeup latencies, and drivers and frameworks are using them.)
> 
> I'm sure there are frameworks using such things.  I'm also sure there
> are frameworks that don't.  BTW, the "we have it out of the tree" argument is
> not very useful, so I'd appreciate it if you didn't use it.

It's useful to know if people have tried things; it doesn't mean it's
going to be OK for mainline but it is a data point.

> > In this case, the video framework (V4L2) might not want any knobs
> > exposed to userspace because userspace simply doesn't have the knowledge
> > to set appropriate constraints.  I'm less familiar with audio, but I
> > believe audio would be similar (sample rate, number of channels, mixing
> > with other concurrent audio streams, etc. etc. are all known by the
> > kernel-side code.)

Yeah, that sort of stuff and also data like wakeup latencies required to
service interrupts.

> I still don't understand what's wrong with allowing user space to _add_
> requirements.  The will only override the drivers' or frameworks' requirements
> if they are stronger, so the functionality shouldn't be hurt.  They may cause
> some more energy to be used, but if user space wants that, it's pretty much
> fine by me.

On the one hand that's true.  On the other hand that just seems like
going down a bad road where we have drivers that only work when run with
a magic userspace that may or may not be published which is just going
to make people miserable.  I'm not sure there are many people who would
choose to use more power without wanting some functional change so
presumably any users would be seeking to work around some kernel problem
and adding the user interface seems to be saying that this is OK,
expected and a natural part of power optimization.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-04 13:24             ` [linux-pm] " Mark Brown
  2011-08-04 19:15               ` Rafael J. Wysocki
@ 2011-08-04 19:15               ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-04 19:15 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Thursday, August 04, 2011, Mark Brown wrote:
> On Wed, Aug 03, 2011 at 12:16:17AM +0200, Rafael J. Wysocki wrote:
> > On Tuesday, August 02, 2011, Kevin Hilman wrote:
> 
> > > I disagree and think that both are quite realistic (mainly because they
> > > exist today, albiet mostly out of tree because no generic QoS framework
> > > exist.  e.g. on OMAP, we have OMAP-specific *kernel* APIs for requesting
> > > per-device wakeup latencies, and drivers and frameworks are using them.)
> > 
> > I'm sure there are frameworks using such things.  I'm also sure there
> > are frameworks that don't.  BTW, the "we have it out of the tree" argument is
> > not very useful, so I'd appreciate it if you didn't use it.
> 
> It's useful to know if people have tried things; it doesn't mean it's
> going to be OK for mainline but it is a data point.
> 
> > > In this case, the video framework (V4L2) might not want any knobs
> > > exposed to userspace because userspace simply doesn't have the knowledge
> > > to set appropriate constraints.  I'm less familiar with audio, but I
> > > believe audio would be similar (sample rate, number of channels, mixing
> > > with other concurrent audio streams, etc. etc. are all known by the
> > > kernel-side code.)
> 
> Yeah, that sort of stuff and also data like wakeup latencies required to
> service interrupts.
> 
> > I still don't understand what's wrong with allowing user space to _add_
> > requirements.  The will only override the drivers' or frameworks' requirements
> > if they are stronger, so the functionality shouldn't be hurt.  They may cause
> > some more energy to be used, but if user space wants that, it's pretty much
> > fine by me.
> 
> On the one hand that's true.  On the other hand that just seems like
> going down a bad road where we have drivers that only work when run with
> a magic userspace that may or may not be published which is just going
> to make people miserable.  I'm not sure there are many people who would
> choose to use more power without wanting some functional change so
> presumably any users would be seeking to work around some kernel problem
> and adding the user interface seems to be saying that this is OK,
> expected and a natural part of power optimization.

First off, we're doing this already (user space can block runtime PM, for
one example, because there are systems where runtime PM doesn't work
although it works on other systems with analogous hardware and pretty
much the same set of drivers).

Second, I think there are valid use cases in which user space _really_ knows
better than the kernel.  I'm opposed to the idea that users shouldn't be given
control of their systems, because they may not know what they're doing.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-04 13:24             ` [linux-pm] " Mark Brown
@ 2011-08-04 19:15               ` Rafael J. Wysocki
  2011-08-05 15:29                 ` mark gross
                                   ` (3 more replies)
  2011-08-04 19:15               ` Rafael J. Wysocki
  1 sibling, 4 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-04 19:15 UTC (permalink / raw)
  To: Mark Brown
  Cc: Kevin Hilman, markgross, Linux PM mailing list, linux-omap, Jean Pihet

On Thursday, August 04, 2011, Mark Brown wrote:
> On Wed, Aug 03, 2011 at 12:16:17AM +0200, Rafael J. Wysocki wrote:
> > On Tuesday, August 02, 2011, Kevin Hilman wrote:
> 
> > > I disagree and think that both are quite realistic (mainly because they
> > > exist today, albiet mostly out of tree because no generic QoS framework
> > > exist.  e.g. on OMAP, we have OMAP-specific *kernel* APIs for requesting
> > > per-device wakeup latencies, and drivers and frameworks are using them.)
> > 
> > I'm sure there are frameworks using such things.  I'm also sure there
> > are frameworks that don't.  BTW, the "we have it out of the tree" argument is
> > not very useful, so I'd appreciate it if you didn't use it.
> 
> It's useful to know if people have tried things; it doesn't mean it's
> going to be OK for mainline but it is a data point.
> 
> > > In this case, the video framework (V4L2) might not want any knobs
> > > exposed to userspace because userspace simply doesn't have the knowledge
> > > to set appropriate constraints.  I'm less familiar with audio, but I
> > > believe audio would be similar (sample rate, number of channels, mixing
> > > with other concurrent audio streams, etc. etc. are all known by the
> > > kernel-side code.)
> 
> Yeah, that sort of stuff and also data like wakeup latencies required to
> service interrupts.
> 
> > I still don't understand what's wrong with allowing user space to _add_
> > requirements.  The will only override the drivers' or frameworks' requirements
> > if they are stronger, so the functionality shouldn't be hurt.  They may cause
> > some more energy to be used, but if user space wants that, it's pretty much
> > fine by me.
> 
> On the one hand that's true.  On the other hand that just seems like
> going down a bad road where we have drivers that only work when run with
> a magic userspace that may or may not be published which is just going
> to make people miserable.  I'm not sure there are many people who would
> choose to use more power without wanting some functional change so
> presumably any users would be seeking to work around some kernel problem
> and adding the user interface seems to be saying that this is OK,
> expected and a natural part of power optimization.

First off, we're doing this already (user space can block runtime PM, for
one example, because there are systems where runtime PM doesn't work
although it works on other systems with analogous hardware and pretty
much the same set of drivers).

Second, I think there are valid use cases in which user space _really_ knows
better than the kernel.  I'm opposed to the idea that users shouldn't be given
control of their systems, because they may not know what they're doing.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-04 19:15               ` Rafael J. Wysocki
  2011-08-05 15:29                 ` mark gross
@ 2011-08-05 15:29                 ` mark gross
  2011-08-05 16:11                 ` Mark Brown
  2011-08-05 16:11                 ` [linux-pm] " Mark Brown
  3 siblings, 0 replies; 122+ messages in thread
From: mark gross @ 2011-08-05 15:29 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, Mark Brown, markgross, Jean Pihet, linux-omap

On Thu, Aug 04, 2011 at 09:15:30PM +0200, Rafael J. Wysocki wrote:
> On Thursday, August 04, 2011, Mark Brown wrote:
> > On Wed, Aug 03, 2011 at 12:16:17AM +0200, Rafael J. Wysocki wrote:
> > > On Tuesday, August 02, 2011, Kevin Hilman wrote:
> > 
> > > > I disagree and think that both are quite realistic (mainly because they
> > > > exist today, albiet mostly out of tree because no generic QoS framework
> > > > exist.  e.g. on OMAP, we have OMAP-specific *kernel* APIs for requesting
> > > > per-device wakeup latencies, and drivers and frameworks are using them.)
> > > 
> > > I'm sure there are frameworks using such things.  I'm also sure there
> > > are frameworks that don't.  BTW, the "we have it out of the tree" argument is
> > > not very useful, so I'd appreciate it if you didn't use it.
> > 
> > It's useful to know if people have tried things; it doesn't mean it's
> > going to be OK for mainline but it is a data point.
> > 
> > > > In this case, the video framework (V4L2) might not want any knobs
> > > > exposed to userspace because userspace simply doesn't have the knowledge
> > > > to set appropriate constraints.  I'm less familiar with audio, but I
> > > > believe audio would be similar (sample rate, number of channels, mixing
> > > > with other concurrent audio streams, etc. etc. are all known by the
> > > > kernel-side code.)
> > 
> > Yeah, that sort of stuff and also data like wakeup latencies required to
> > service interrupts.
> > 
> > > I still don't understand what's wrong with allowing user space to _add_
> > > requirements.  The will only override the drivers' or frameworks' requirements
> > > if they are stronger, so the functionality shouldn't be hurt.  They may cause
> > > some more energy to be used, but if user space wants that, it's pretty much
> > > fine by me.
> > 
> > On the one hand that's true.  On the other hand that just seems like
> > going down a bad road where we have drivers that only work when run with
> > a magic userspace that may or may not be published which is just going
> > to make people miserable.  I'm not sure there are many people who would
> > choose to use more power without wanting some functional change so
> > presumably any users would be seeking to work around some kernel problem
> > and adding the user interface seems to be saying that this is OK,
> > expected and a natural part of power optimization.
> 
> First off, we're doing this already (user space can block runtime PM, for
> one example, because there are systems where runtime PM doesn't work
> although it works on other systems with analogous hardware and pretty
> much the same set of drivers).
> 
> Second, I think there are valid use cases in which user space _really_ knows
> better than the kernel.  I'm opposed to the idea that users shouldn't be given
> control of their systems, because they may not know what they're doing.
>
Ok, I can see the point.  The challenge is how do we expose ABI's and
abstractions that result in drivers and PM implementations that are
somewhat portable between ISA's and platforms?  Simply exporting the low
level knobs of whatever drivers are loaded into memory, if used in user
mode, could result in a tight coupling or even a reverse dependency on a
proper user mode for the kernel to do the right things.

I'm sensitive to becoming blocked on doing kernel a update just because
we can't update the user mode code at the same time.  Its quite
annoying.

IMO to make it easy reuse TI SoC drivers in Intel SoC's (and
visa-versa) I would rather have these low level PM-QoS constraint
details abstracted in some sane and consistent way.  Through subsystem
API's if possible or, at a bus level if we must. 


--mark
Ps I also am worried I'm over thinking about this an Rafael may be right
and we would be better off just exposing the abstractions of "latency"
and "throughput" uniformly and focus more on the missing bus and
subsystem level governors that need to interpret and coordinate the qos
requests.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-04 19:15               ` Rafael J. Wysocki
@ 2011-08-05 15:29                 ` mark gross
  2011-08-05 15:29                 ` mark gross
                                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 122+ messages in thread
From: mark gross @ 2011-08-05 15:29 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mark Brown, Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Thu, Aug 04, 2011 at 09:15:30PM +0200, Rafael J. Wysocki wrote:
> On Thursday, August 04, 2011, Mark Brown wrote:
> > On Wed, Aug 03, 2011 at 12:16:17AM +0200, Rafael J. Wysocki wrote:
> > > On Tuesday, August 02, 2011, Kevin Hilman wrote:
> > 
> > > > I disagree and think that both are quite realistic (mainly because they
> > > > exist today, albiet mostly out of tree because no generic QoS framework
> > > > exist.  e.g. on OMAP, we have OMAP-specific *kernel* APIs for requesting
> > > > per-device wakeup latencies, and drivers and frameworks are using them.)
> > > 
> > > I'm sure there are frameworks using such things.  I'm also sure there
> > > are frameworks that don't.  BTW, the "we have it out of the tree" argument is
> > > not very useful, so I'd appreciate it if you didn't use it.
> > 
> > It's useful to know if people have tried things; it doesn't mean it's
> > going to be OK for mainline but it is a data point.
> > 
> > > > In this case, the video framework (V4L2) might not want any knobs
> > > > exposed to userspace because userspace simply doesn't have the knowledge
> > > > to set appropriate constraints.  I'm less familiar with audio, but I
> > > > believe audio would be similar (sample rate, number of channels, mixing
> > > > with other concurrent audio streams, etc. etc. are all known by the
> > > > kernel-side code.)
> > 
> > Yeah, that sort of stuff and also data like wakeup latencies required to
> > service interrupts.
> > 
> > > I still don't understand what's wrong with allowing user space to _add_
> > > requirements.  The will only override the drivers' or frameworks' requirements
> > > if they are stronger, so the functionality shouldn't be hurt.  They may cause
> > > some more energy to be used, but if user space wants that, it's pretty much
> > > fine by me.
> > 
> > On the one hand that's true.  On the other hand that just seems like
> > going down a bad road where we have drivers that only work when run with
> > a magic userspace that may or may not be published which is just going
> > to make people miserable.  I'm not sure there are many people who would
> > choose to use more power without wanting some functional change so
> > presumably any users would be seeking to work around some kernel problem
> > and adding the user interface seems to be saying that this is OK,
> > expected and a natural part of power optimization.
> 
> First off, we're doing this already (user space can block runtime PM, for
> one example, because there are systems where runtime PM doesn't work
> although it works on other systems with analogous hardware and pretty
> much the same set of drivers).
> 
> Second, I think there are valid use cases in which user space _really_ knows
> better than the kernel.  I'm opposed to the idea that users shouldn't be given
> control of their systems, because they may not know what they're doing.
>
Ok, I can see the point.  The challenge is how do we expose ABI's and
abstractions that result in drivers and PM implementations that are
somewhat portable between ISA's and platforms?  Simply exporting the low
level knobs of whatever drivers are loaded into memory, if used in user
mode, could result in a tight coupling or even a reverse dependency on a
proper user mode for the kernel to do the right things.

I'm sensitive to becoming blocked on doing kernel a update just because
we can't update the user mode code at the same time.  Its quite
annoying.

IMO to make it easy reuse TI SoC drivers in Intel SoC's (and
visa-versa) I would rather have these low level PM-QoS constraint
details abstracted in some sane and consistent way.  Through subsystem
API's if possible or, at a bus level if we must. 


--mark
Ps I also am worried I'm over thinking about this an Rafael may be right
and we would be better off just exposing the abstractions of "latency"
and "throughput" uniformly and focus more on the missing bus and
subsystem level governors that need to interpret and coordinate the qos
requests.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-04 19:15               ` Rafael J. Wysocki
  2011-08-05 15:29                 ` mark gross
  2011-08-05 15:29                 ` mark gross
@ 2011-08-05 16:11                 ` Mark Brown
  2011-08-05 16:11                 ` [linux-pm] " Mark Brown
  3 siblings, 0 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-05 16:11 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Thu, Aug 04, 2011 at 09:15:30PM +0200, Rafael J. Wysocki wrote:
> On Thursday, August 04, 2011, Mark Brown wrote:

> > On the one hand that's true.  On the other hand that just seems like
> > going down a bad road where we have drivers that only work when run with
> > a magic userspace that may or may not be published which is just going

> First off, we're doing this already (user space can block runtime PM, for
> one example, because there are systems where runtime PM doesn't work
> although it works on other systems with analogous hardware and pretty
> much the same set of drivers).

Yeah, I've never been terribly convinced about that and for the things
that drivers need to manualy implement (like wake configuration) it's
widely ignored.

> Second, I think there are valid use cases in which user space _really_ knows
> better than the kernel.  I'm opposed to the idea that users shouldn't be given
> control of their systems, because they may not know what they're doing.

Do you have any examples of this that aren't better expressed in device
specific terms?  It's not that users don't know what they're doing, it's
that working around system integration and stability issues in userspace
isn't really progressing things well or helping with maintainability.
Generally if the user has sufficient access to be able to do anything
with this stuff they've got just as much access to the kernel as to
userspace.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-04 19:15               ` Rafael J. Wysocki
                                   ` (2 preceding siblings ...)
  2011-08-05 16:11                 ` Mark Brown
@ 2011-08-05 16:11                 ` Mark Brown
  2011-08-05 19:37                   ` Rafael J. Wysocki
  2011-08-05 19:37                   ` [linux-pm] " Rafael J. Wysocki
  3 siblings, 2 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-05 16:11 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Kevin Hilman, markgross, Linux PM mailing list, linux-omap, Jean Pihet

On Thu, Aug 04, 2011 at 09:15:30PM +0200, Rafael J. Wysocki wrote:
> On Thursday, August 04, 2011, Mark Brown wrote:

> > On the one hand that's true.  On the other hand that just seems like
> > going down a bad road where we have drivers that only work when run with
> > a magic userspace that may or may not be published which is just going

> First off, we're doing this already (user space can block runtime PM, for
> one example, because there are systems where runtime PM doesn't work
> although it works on other systems with analogous hardware and pretty
> much the same set of drivers).

Yeah, I've never been terribly convinced about that and for the things
that drivers need to manualy implement (like wake configuration) it's
widely ignored.

> Second, I think there are valid use cases in which user space _really_ knows
> better than the kernel.  I'm opposed to the idea that users shouldn't be given
> control of their systems, because they may not know what they're doing.

Do you have any examples of this that aren't better expressed in device
specific terms?  It's not that users don't know what they're doing, it's
that working around system integration and stability issues in userspace
isn't really progressing things well or helping with maintainability.
Generally if the user has sufficient access to be able to do anything
with this stuff they've got just as much access to the kernel as to
userspace.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-05 16:11                 ` [linux-pm] " Mark Brown
@ 2011-08-05 19:37                   ` Rafael J. Wysocki
  2011-08-05 19:37                   ` [linux-pm] " Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-05 19:37 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Friday, August 05, 2011, Mark Brown wrote:
> On Thu, Aug 04, 2011 at 09:15:30PM +0200, Rafael J. Wysocki wrote:
> > On Thursday, August 04, 2011, Mark Brown wrote:
> 
> > > On the one hand that's true.  On the other hand that just seems like
> > > going down a bad road where we have drivers that only work when run with
> > > a magic userspace that may or may not be published which is just going
> 
> > First off, we're doing this already (user space can block runtime PM, for
> > one example, because there are systems where runtime PM doesn't work
> > although it works on other systems with analogous hardware and pretty
> > much the same set of drivers).
> 
> Yeah, I've never been terribly convinced about that and for the things
> that drivers need to manualy implement (like wake configuration) it's
> widely ignored.
> 
> > Second, I think there are valid use cases in which user space _really_ knows
> > better than the kernel.  I'm opposed to the idea that users shouldn't be given
> > control of their systems, because they may not know what they're doing.
> 
> Do you have any examples of this that aren't better expressed in device
> specific terms?

I'm not sure what you mean exactly, but if you take two PC-like systems
with similar hardware configurations, but different BIOS-es and motherboard
layouts, it's very likely that on one of them PCI PME won't be routed
correctly, for example.  In that case the kernel has no way to figure out
that that system is broken, the problem can only be worked around from user
space by diabling runtime PM on the affected PCI devices.  I expect similar
problems to appear for the PM QoS settings.

> It's not that users don't know what they're doing, it's
> that working around system integration and stability issues in userspace
> isn't really progressing things well or helping with maintainability.

No, it's not, but sometimes we simply don't have the choice.  Besides,
in the particular case of PM QoS, the constraints set by user space will
simply be added to the constraints set by kernel subsystems.  Thus they
won't prevent any kernel subsystem from specifying its own constraints,
but they will give user space the option to override the constraints
originating from the kernel.

> Generally if the user has sufficient access to be able to do anything
> with this stuff they've got just as much access to the kernel as to
> userspace.

Do you mean they may rebuild the kernel?  That isn't always possible.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-05 16:11                 ` [linux-pm] " Mark Brown
  2011-08-05 19:37                   ` Rafael J. Wysocki
@ 2011-08-05 19:37                   ` Rafael J. Wysocki
  2011-08-06  3:37                     ` Mark Brown
  2011-08-06  3:37                     ` Mark Brown
  1 sibling, 2 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-05 19:37 UTC (permalink / raw)
  To: Mark Brown
  Cc: Kevin Hilman, markgross, Linux PM mailing list, linux-omap, Jean Pihet

On Friday, August 05, 2011, Mark Brown wrote:
> On Thu, Aug 04, 2011 at 09:15:30PM +0200, Rafael J. Wysocki wrote:
> > On Thursday, August 04, 2011, Mark Brown wrote:
> 
> > > On the one hand that's true.  On the other hand that just seems like
> > > going down a bad road where we have drivers that only work when run with
> > > a magic userspace that may or may not be published which is just going
> 
> > First off, we're doing this already (user space can block runtime PM, for
> > one example, because there are systems where runtime PM doesn't work
> > although it works on other systems with analogous hardware and pretty
> > much the same set of drivers).
> 
> Yeah, I've never been terribly convinced about that and for the things
> that drivers need to manualy implement (like wake configuration) it's
> widely ignored.
> 
> > Second, I think there are valid use cases in which user space _really_ knows
> > better than the kernel.  I'm opposed to the idea that users shouldn't be given
> > control of their systems, because they may not know what they're doing.
> 
> Do you have any examples of this that aren't better expressed in device
> specific terms?

I'm not sure what you mean exactly, but if you take two PC-like systems
with similar hardware configurations, but different BIOS-es and motherboard
layouts, it's very likely that on one of them PCI PME won't be routed
correctly, for example.  In that case the kernel has no way to figure out
that that system is broken, the problem can only be worked around from user
space by diabling runtime PM on the affected PCI devices.  I expect similar
problems to appear for the PM QoS settings.

> It's not that users don't know what they're doing, it's
> that working around system integration and stability issues in userspace
> isn't really progressing things well or helping with maintainability.

No, it's not, but sometimes we simply don't have the choice.  Besides,
in the particular case of PM QoS, the constraints set by user space will
simply be added to the constraints set by kernel subsystems.  Thus they
won't prevent any kernel subsystem from specifying its own constraints,
but they will give user space the option to override the constraints
originating from the kernel.

> Generally if the user has sufficient access to be able to do anything
> with this stuff they've got just as much access to the kernel as to
> userspace.

Do you mean they may rebuild the kernel?  That isn't always possible.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-05 19:37                   ` [linux-pm] " Rafael J. Wysocki
  2011-08-06  3:37                     ` Mark Brown
@ 2011-08-06  3:37                     ` Mark Brown
  1 sibling, 0 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-06  3:37 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Fri, Aug 05, 2011 at 09:37:36PM +0200, Rafael J. Wysocki wrote:
> On Friday, August 05, 2011, Mark Brown wrote:

> > Do you have any examples of this that aren't better expressed in device
> > specific terms?

> I'm not sure what you mean exactly, but if you take two PC-like systems
> with similar hardware configurations, but different BIOS-es and motherboard
> layouts, it's very likely that on one of them PCI PME won't be routed
> correctly, for example.  In that case the kernel has no way to figure out
> that that system is broken, the problem can only be worked around from user
> space by diabling runtime PM on the affected PCI devices.  I expect similar
> problems to appear for the PM QoS settings.

I wouldn't say we've got to rely on userspace here - it seems like we
ought to be able to use DMI or other system data to identify the
affected systems and activate the workarounds.

> > It's not that users don't know what they're doing, it's
> > that working around system integration and stability issues in userspace
> > isn't really progressing things well or helping with maintainability.

> No, it's not, but sometimes we simply don't have the choice.  Besides,
> in the particular case of PM QoS, the constraints set by user space will
> simply be added to the constraints set by kernel subsystems.  Thus they
> won't prevent any kernel subsystem from specifying its own constraints,
> but they will give user space the option to override the constraints
> originating from the kernel.

You're right that it doesn't stop the kernel doing anything, the concern
is that people just won't bother making the kernel work properly and
will just do their power management in userspace and not bother fixing
the kernel.  Punting to userspace seems like it is creating the
expectation that we can't make the kernel work and isn't great from a
usability perspective since users shouldn't really be worrying about bus
performance or so on, it's not something that's visible at the level
applications work at.

> > Generally if the user has sufficient access to be able to do anything
> > with this stuff they've got just as much access to the kernel as to
> > userspace.

> Do you mean they may rebuild the kernel?  That isn't always possible.

I'm not sure I can see a lot of cases where you'd have root access and
not be able to do kernel updates if required?  Having stuff in debugfs
for diagnostics doesn't strike me as a problem if that's the issue.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-05 19:37                   ` [linux-pm] " Rafael J. Wysocki
@ 2011-08-06  3:37                     ` Mark Brown
  2011-08-06 19:46                       ` Rafael J. Wysocki
  2011-08-06  3:37                     ` Mark Brown
  1 sibling, 1 reply; 122+ messages in thread
From: Mark Brown @ 2011-08-06  3:37 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Kevin Hilman, markgross, Linux PM mailing list, linux-omap, Jean Pihet

On Fri, Aug 05, 2011 at 09:37:36PM +0200, Rafael J. Wysocki wrote:
> On Friday, August 05, 2011, Mark Brown wrote:

> > Do you have any examples of this that aren't better expressed in device
> > specific terms?

> I'm not sure what you mean exactly, but if you take two PC-like systems
> with similar hardware configurations, but different BIOS-es and motherboard
> layouts, it's very likely that on one of them PCI PME won't be routed
> correctly, for example.  In that case the kernel has no way to figure out
> that that system is broken, the problem can only be worked around from user
> space by diabling runtime PM on the affected PCI devices.  I expect similar
> problems to appear for the PM QoS settings.

I wouldn't say we've got to rely on userspace here - it seems like we
ought to be able to use DMI or other system data to identify the
affected systems and activate the workarounds.

> > It's not that users don't know what they're doing, it's
> > that working around system integration and stability issues in userspace
> > isn't really progressing things well or helping with maintainability.

> No, it's not, but sometimes we simply don't have the choice.  Besides,
> in the particular case of PM QoS, the constraints set by user space will
> simply be added to the constraints set by kernel subsystems.  Thus they
> won't prevent any kernel subsystem from specifying its own constraints,
> but they will give user space the option to override the constraints
> originating from the kernel.

You're right that it doesn't stop the kernel doing anything, the concern
is that people just won't bother making the kernel work properly and
will just do their power management in userspace and not bother fixing
the kernel.  Punting to userspace seems like it is creating the
expectation that we can't make the kernel work and isn't great from a
usability perspective since users shouldn't really be worrying about bus
performance or so on, it's not something that's visible at the level
applications work at.

> > Generally if the user has sufficient access to be able to do anything
> > with this stuff they've got just as much access to the kernel as to
> > userspace.

> Do you mean they may rebuild the kernel?  That isn't always possible.

I'm not sure I can see a lot of cases where you'd have root access and
not be able to do kernel updates if required?  Having stuff in debugfs
for diagnostics doesn't strike me as a problem if that's the issue.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-06  3:37                     ` Mark Brown
@ 2011-08-06 19:46                       ` Rafael J. Wysocki
  2011-08-07  2:47                         ` Mark Brown
  2011-08-07  2:47                         ` [linux-pm] " Mark Brown
  0 siblings, 2 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-06 19:46 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Saturday, August 06, 2011, Mark Brown wrote:
> On Fri, Aug 05, 2011 at 09:37:36PM +0200, Rafael J. Wysocki wrote:
> > On Friday, August 05, 2011, Mark Brown wrote:
> 
> > > Do you have any examples of this that aren't better expressed in device
> > > specific terms?
> 
> > I'm not sure what you mean exactly, but if you take two PC-like systems
> > with similar hardware configurations, but different BIOS-es and motherboard
> > layouts, it's very likely that on one of them PCI PME won't be routed
> > correctly, for example.  In that case the kernel has no way to figure out
> > that that system is broken, the problem can only be worked around from user
> > space by diabling runtime PM on the affected PCI devices.  I expect similar
> > problems to appear for the PM QoS settings.
> 
> I wouldn't say we've got to rely on userspace here - it seems like we
> ought to be able to use DMI or other system data to identify the
> affected systems and activate the workarounds.

That's only practical on systems where the kernel can be rebuilt.
Moreover, if that affects individual devices, using DMI-based blacklists
is not really practical at all.

> > > It's not that users don't know what they're doing, it's
> > > that working around system integration and stability issues in userspace
> > > isn't really progressing things well or helping with maintainability.
> 
> > No, it's not, but sometimes we simply don't have the choice.  Besides,
> > in the particular case of PM QoS, the constraints set by user space will
> > simply be added to the constraints set by kernel subsystems.  Thus they
> > won't prevent any kernel subsystem from specifying its own constraints,
> > but they will give user space the option to override the constraints
> > originating from the kernel.
> 
> You're right that it doesn't stop the kernel doing anything, the concern
> is that people just won't bother making the kernel work properly and
> will just do their power management in userspace and not bother fixing
> the kernel.

I wouldn't call it "fixing the kernel".  I'd rather say "putting workarounds
into the kernel", which I'm not sure is the right thing to at least in some
cases.

> Punting to userspace seems like it is creating the
> expectation that we can't make the kernel work and isn't great from a
> usability perspective since users shouldn't really be worrying about bus
> performance or so on, it's not something that's visible at the level
> applications work at.

However, platform builders may want to fine tuned things and I'm not sure
we should require them to patch the kernel for this purpose.

> > > Generally if the user has sufficient access to be able to do anything
> > > with this stuff they've got just as much access to the kernel as to
> > > userspace.
> 
> > Do you mean they may rebuild the kernel?  That isn't always possible.
> 
> I'm not sure I can see a lot of cases where you'd have root access and
> not be able to do kernel updates if required?  Having stuff in debugfs
> for diagnostics doesn't strike me as a problem if that's the issue.

Root access doesn't necessarily mean you have all of the requisite
tools (like compilers etc.) and installing them isn't always trivial
(think of systems like phones etc.), let alone building the kernel from
sources (where you don't necessarily know the original .config used for
building your device's kernel).

IOW, I don't buy the "you can always rebuild the kernel if necessary"
argument.  It simply is not true in general.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-06 19:46                       ` Rafael J. Wysocki
@ 2011-08-07  2:47                         ` Mark Brown
  2011-08-07  2:47                         ` [linux-pm] " Mark Brown
  1 sibling, 0 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-07  2:47 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sat, Aug 06, 2011 at 09:46:20PM +0200, Rafael J. Wysocki wrote:
> On Saturday, August 06, 2011, Mark Brown wrote:

> > I wouldn't say we've got to rely on userspace here - it seems like we
> > ought to be able to use DMI or other system data to identify the
> > affected systems and activate the workarounds.

> That's only practical on systems where the kernel can be rebuilt.
> Moreover, if that affects individual devices, using DMI-based blacklists
> is not really practical at all.

OK, so this does sound like there's probably a genuine issue on PCs due
to limitations in the environment.  Is it possible to expose these
things to userspace in a way that's limited to the affected platforms?

> > You're right that it doesn't stop the kernel doing anything, the concern
> > is that people just won't bother making the kernel work properly and
> > will just do their power management in userspace and not bother fixing
> > the kernel.

> I wouldn't call it "fixing the kernel".  I'd rather say "putting workarounds
> into the kernel", which I'm not sure is the right thing to at least in some
> cases.

That does sound like a fair characterization for PCs.  For embedded
systems where we have a *much* better knowledge of the hardware we're
running on you're just working with the basics of what the hardware
needs to run - the hardware needs whatever it needs and no matter what
you think of the quality of the hardware there's an expectation that the
kernel is ging to be able to work.

> > Punting to userspace seems like it is creating the
> > expectation that we can't make the kernel work and isn't great from a
> > usability perspective since users shouldn't really be worrying about bus
> > performance or so on, it's not something that's visible at the level
> > applications work at.

> However, platform builders may want to fine tuned things and I'm not sure
> we should require them to patch the kernel for this purpose.

As I've said it's not the fine tuning that I'm worried about, it's the
specific mechanism that's being suggested.  Being able to tune things in
a way that's relevant to the device being tuned seems entirely sensible.

> > I'm not sure I can see a lot of cases where you'd have root access and
> > not be able to do kernel updates if required?  Having stuff in debugfs
> > for diagnostics doesn't strike me as a problem if that's the issue.

> Root access doesn't necessarily mean you have all of the requisite
> tools (like compilers etc.) and installing them isn't always trivial
> (think of systems like phones etc.), let alone building the kernel from
> sources (where you don't necessarily know the original .config used for
> building your device's kernel).

Phones are exactly the sort of case I'm primarily concerned with here.

Realistically if you're in a position where you need to work at this
very low level on an embedded device you can replace the entire firmware
on the device.  We don't want to end up in the situation where we've got
kernel support for a device and the only way to get it to actually run
sensibly is to install the silicon vendor's proprietary userspace, and
we especially don't want to end up in the situation where that userspace
is using standard and supported kernel interfaces to do its thing.

> IOW, I don't buy the "you can always rebuild the kernel if necessary"
> argument.  It simply is not true in general.

You can push that argument to extremes, of course.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-06 19:46                       ` Rafael J. Wysocki
  2011-08-07  2:47                         ` Mark Brown
@ 2011-08-07  2:47                         ` Mark Brown
  2011-08-08 21:31                           ` Rafael J. Wysocki
  2011-08-08 21:31                           ` Rafael J. Wysocki
  1 sibling, 2 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-07  2:47 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Kevin Hilman, markgross, Linux PM mailing list, linux-omap, Jean Pihet

On Sat, Aug 06, 2011 at 09:46:20PM +0200, Rafael J. Wysocki wrote:
> On Saturday, August 06, 2011, Mark Brown wrote:

> > I wouldn't say we've got to rely on userspace here - it seems like we
> > ought to be able to use DMI or other system data to identify the
> > affected systems and activate the workarounds.

> That's only practical on systems where the kernel can be rebuilt.
> Moreover, if that affects individual devices, using DMI-based blacklists
> is not really practical at all.

OK, so this does sound like there's probably a genuine issue on PCs due
to limitations in the environment.  Is it possible to expose these
things to userspace in a way that's limited to the affected platforms?

> > You're right that it doesn't stop the kernel doing anything, the concern
> > is that people just won't bother making the kernel work properly and
> > will just do their power management in userspace and not bother fixing
> > the kernel.

> I wouldn't call it "fixing the kernel".  I'd rather say "putting workarounds
> into the kernel", which I'm not sure is the right thing to at least in some
> cases.

That does sound like a fair characterization for PCs.  For embedded
systems where we have a *much* better knowledge of the hardware we're
running on you're just working with the basics of what the hardware
needs to run - the hardware needs whatever it needs and no matter what
you think of the quality of the hardware there's an expectation that the
kernel is ging to be able to work.

> > Punting to userspace seems like it is creating the
> > expectation that we can't make the kernel work and isn't great from a
> > usability perspective since users shouldn't really be worrying about bus
> > performance or so on, it's not something that's visible at the level
> > applications work at.

> However, platform builders may want to fine tuned things and I'm not sure
> we should require them to patch the kernel for this purpose.

As I've said it's not the fine tuning that I'm worried about, it's the
specific mechanism that's being suggested.  Being able to tune things in
a way that's relevant to the device being tuned seems entirely sensible.

> > I'm not sure I can see a lot of cases where you'd have root access and
> > not be able to do kernel updates if required?  Having stuff in debugfs
> > for diagnostics doesn't strike me as a problem if that's the issue.

> Root access doesn't necessarily mean you have all of the requisite
> tools (like compilers etc.) and installing them isn't always trivial
> (think of systems like phones etc.), let alone building the kernel from
> sources (where you don't necessarily know the original .config used for
> building your device's kernel).

Phones are exactly the sort of case I'm primarily concerned with here.

Realistically if you're in a position where you need to work at this
very low level on an embedded device you can replace the entire firmware
on the device.  We don't want to end up in the situation where we've got
kernel support for a device and the only way to get it to actually run
sensibly is to install the silicon vendor's proprietary userspace, and
we especially don't want to end up in the situation where that userspace
is using standard and supported kernel interfaces to do its thing.

> IOW, I don't buy the "you can always rebuild the kernel if necessary"
> argument.  It simply is not true in general.

You can push that argument to extremes, of course.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-07  2:47                         ` [linux-pm] " Mark Brown
  2011-08-08 21:31                           ` Rafael J. Wysocki
@ 2011-08-08 21:31                           ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-08 21:31 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sunday, August 07, 2011, Mark Brown wrote:
> On Sat, Aug 06, 2011 at 09:46:20PM +0200, Rafael J. Wysocki wrote:
> > On Saturday, August 06, 2011, Mark Brown wrote:
> 
> > > I wouldn't say we've got to rely on userspace here - it seems like we
> > > ought to be able to use DMI or other system data to identify the
> > > affected systems and activate the workarounds.
> 
> > That's only practical on systems where the kernel can be rebuilt.
> > Moreover, if that affects individual devices, using DMI-based blacklists
> > is not really practical at all.
> 
> OK, so this does sound like there's probably a genuine issue on PCs due
> to limitations in the environment.  Is it possible to expose these
> things to userspace in a way that's limited to the affected platforms?

Well, in principle we could make it depend in CONFIG_ACPI or something like
this, but I'm not sure that will be well-received. :-)

> > > You're right that it doesn't stop the kernel doing anything, the concern
> > > is that people just won't bother making the kernel work properly and
> > > will just do their power management in userspace and not bother fixing
> > > the kernel.
> 
> > I wouldn't call it "fixing the kernel".  I'd rather say "putting workarounds
> > into the kernel", which I'm not sure is the right thing to at least in some
> > cases.
> 
> That does sound like a fair characterization for PCs.  For embedded
> systems where we have a *much* better knowledge of the hardware we're
> running on you're just working with the basics of what the hardware
> needs to run - the hardware needs whatever it needs and no matter what
> you think of the quality of the hardware there's an expectation that the
> kernel is ging to be able to work.

In the particular case in question, though, there's some freedom.  Namely,
the hardware will work for many different QoS constraints and it's not
precisely known in principle and upfront which one would be optimal for
a given workload.

> > > Punting to userspace seems like it is creating the
> > > expectation that we can't make the kernel work and isn't great from a
> > > usability perspective since users shouldn't really be worrying about bus
> > > performance or so on, it's not something that's visible at the level
> > > applications work at.
> 
> > However, platform builders may want to fine tuned things and I'm not sure
> > we should require them to patch the kernel for this purpose.
> 
> As I've said it's not the fine tuning that I'm worried about, it's the
> specific mechanism that's being suggested.  Being able to tune things in
> a way that's relevant to the device being tuned seems entirely sensible.

Do you know any better mechanism consistent accross all devices?
Please be specific. :-)

> > > I'm not sure I can see a lot of cases where you'd have root access and
> > > not be able to do kernel updates if required?  Having stuff in debugfs
> > > for diagnostics doesn't strike me as a problem if that's the issue.
> 
> > Root access doesn't necessarily mean you have all of the requisite
> > tools (like compilers etc.) and installing them isn't always trivial
> > (think of systems like phones etc.), let alone building the kernel from
> > sources (where you don't necessarily know the original .config used for
> > building your device's kernel).
> 
> Phones are exactly the sort of case I'm primarily concerned with here.
> 
> Realistically if you're in a position where you need to work at this
> very low level on an embedded device you can replace the entire firmware
> on the device.  We don't want to end up in the situation where we've got
> kernel support for a device and the only way to get it to actually run
> sensibly is to install the silicon vendor's proprietary userspace, and
> we especially don't want to end up in the situation where that userspace
> is using standard and supported kernel interfaces to do its thing.

Well, the wakelocks example shows clearly that preventing certain interfaces
from being merged into mainline doesn't actually prevent people from using
them in actual products.  I claim it's way better if a vendor uses its
proprietary user space with the mainline kernel than if that vendor patches
the kernel and _then_ uses its proprietary user space with it.  Your
argumentation seems to suggest that we encourage the latter.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-07  2:47                         ` [linux-pm] " Mark Brown
@ 2011-08-08 21:31                           ` Rafael J. Wysocki
  2011-08-19  3:11                             ` Mark Brown
  2011-08-19  3:11                             ` Mark Brown
  2011-08-08 21:31                           ` Rafael J. Wysocki
  1 sibling, 2 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-08 21:31 UTC (permalink / raw)
  To: Mark Brown
  Cc: Kevin Hilman, markgross, Linux PM mailing list, linux-omap, Jean Pihet

On Sunday, August 07, 2011, Mark Brown wrote:
> On Sat, Aug 06, 2011 at 09:46:20PM +0200, Rafael J. Wysocki wrote:
> > On Saturday, August 06, 2011, Mark Brown wrote:
> 
> > > I wouldn't say we've got to rely on userspace here - it seems like we
> > > ought to be able to use DMI or other system data to identify the
> > > affected systems and activate the workarounds.
> 
> > That's only practical on systems where the kernel can be rebuilt.
> > Moreover, if that affects individual devices, using DMI-based blacklists
> > is not really practical at all.
> 
> OK, so this does sound like there's probably a genuine issue on PCs due
> to limitations in the environment.  Is it possible to expose these
> things to userspace in a way that's limited to the affected platforms?

Well, in principle we could make it depend in CONFIG_ACPI or something like
this, but I'm not sure that will be well-received. :-)

> > > You're right that it doesn't stop the kernel doing anything, the concern
> > > is that people just won't bother making the kernel work properly and
> > > will just do their power management in userspace and not bother fixing
> > > the kernel.
> 
> > I wouldn't call it "fixing the kernel".  I'd rather say "putting workarounds
> > into the kernel", which I'm not sure is the right thing to at least in some
> > cases.
> 
> That does sound like a fair characterization for PCs.  For embedded
> systems where we have a *much* better knowledge of the hardware we're
> running on you're just working with the basics of what the hardware
> needs to run - the hardware needs whatever it needs and no matter what
> you think of the quality of the hardware there's an expectation that the
> kernel is ging to be able to work.

In the particular case in question, though, there's some freedom.  Namely,
the hardware will work for many different QoS constraints and it's not
precisely known in principle and upfront which one would be optimal for
a given workload.

> > > Punting to userspace seems like it is creating the
> > > expectation that we can't make the kernel work and isn't great from a
> > > usability perspective since users shouldn't really be worrying about bus
> > > performance or so on, it's not something that's visible at the level
> > > applications work at.
> 
> > However, platform builders may want to fine tuned things and I'm not sure
> > we should require them to patch the kernel for this purpose.
> 
> As I've said it's not the fine tuning that I'm worried about, it's the
> specific mechanism that's being suggested.  Being able to tune things in
> a way that's relevant to the device being tuned seems entirely sensible.

Do you know any better mechanism consistent accross all devices?
Please be specific. :-)

> > > I'm not sure I can see a lot of cases where you'd have root access and
> > > not be able to do kernel updates if required?  Having stuff in debugfs
> > > for diagnostics doesn't strike me as a problem if that's the issue.
> 
> > Root access doesn't necessarily mean you have all of the requisite
> > tools (like compilers etc.) and installing them isn't always trivial
> > (think of systems like phones etc.), let alone building the kernel from
> > sources (where you don't necessarily know the original .config used for
> > building your device's kernel).
> 
> Phones are exactly the sort of case I'm primarily concerned with here.
> 
> Realistically if you're in a position where you need to work at this
> very low level on an embedded device you can replace the entire firmware
> on the device.  We don't want to end up in the situation where we've got
> kernel support for a device and the only way to get it to actually run
> sensibly is to install the silicon vendor's proprietary userspace, and
> we especially don't want to end up in the situation where that userspace
> is using standard and supported kernel interfaces to do its thing.

Well, the wakelocks example shows clearly that preventing certain interfaces
from being merged into mainline doesn't actually prevent people from using
them in actual products.  I claim it's way better if a vendor uses its
proprietary user space with the mainline kernel than if that vendor patches
the kernel and _then_ uses its proprietary user space with it.  Your
argumentation seems to suggest that we encourage the latter.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-08 21:31                           ` Rafael J. Wysocki
  2011-08-19  3:11                             ` Mark Brown
@ 2011-08-19  3:11                             ` Mark Brown
  1 sibling, 0 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-19  3:11 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Mon, 2011-08-08 at 23:31 +0200, Rafael J. Wysocki wrote:
> On Sunday, August 07, 2011, Mark Brown wrote:

> > OK, so this does sound like there's probably a genuine issue on PCs due
> > to limitations in the environment.  Is it possible to expose these
> > things to userspace in a way that's limited to the affected platforms?

> Well, in principle we could make it depend in CONFIG_ACPI or something like
> this, but I'm not sure that will be well-received. :-)

Or the drivers for the particular buses in use?

> > That does sound like a fair characterization for PCs.  For embedded
> > systems where we have a *much* better knowledge of the hardware we're
> > running on you're just working with the basics of what the hardware
> > needs to run - the hardware needs whatever it needs and no matter what
> > you think of the quality of the hardware there's an expectation that the
> > kernel is ging to be able to work.

> In the particular case in question, though, there's some freedom.  Namely,
> the hardware will work for many different QoS constraints and it's not
> precisely known in principle and upfront which one would be optimal for
> a given workload.

But are these tunings things that we can usefully represent in a generic
API or are they specific parameters of the subsystem in question? I
don't think anyone has suggested that having tuning for things where
there are genuine choices is a good thing.

> > As I've said it's not the fine tuning that I'm worried about, it's the
> > specific mechanism that's being suggested.  Being able to tune things in
> > a way that's relevant to the device being tuned seems entirely sensible.

> Do you know any better mechanism consistent accross all devices?
> Please be specific. :-)

Well, I'm suggesting that we shouldn't have a standard userspace API for
this in the first place but should instead be doing things on the
subsystem or driver level. I'm not sure we can sensibly do anything that
works usefully for all devices.

> > Realistically if you're in a position where you need to work at this
> > very low level on an embedded device you can replace the entire firmware
> > on the device.  We don't want to end up in the situation where we've got
> > kernel support for a device and the only way to get it to actually run
> > sensibly is to install the silicon vendor's proprietary userspace, and
> > we especially don't want to end up in the situation where that userspace
> > is using standard and supported kernel interfaces to do its thing.

> Well, the wakelocks example shows clearly that preventing certain interfaces
> from being merged into mainline doesn't actually prevent people from using
> them in actual products.  I claim it's way better if a vendor uses its
> proprietary user space with the mainline kernel than if that vendor patches
> the kernel and _then_ uses its proprietary user space with it.  Your
> argumentation seems to suggest that we encourage the latter.

We can't stop people doing questionable things out of tree but that
doesn't mean lowering standards in mainline is a good idea. Keeping
things out of tree creates a range of costs - the effort required to
write the code and update for new kernel releases, support issues when
the out of tree code causes problems and so on - and makes it clear to
people using the code where the costs came from. If the code looks like
it's standard code using standard interfaces much of that pressure goes
away.

This is similar to all the stuff that's going on in the ARM tree at the
minute - there's nothing we can do to prevent vendors shipping random
code of any quality in out of tree BSPs but we can set high standards
for the quality of code we accept into mainline and let the resulting
pressures push people towards mainline solutions.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-08 21:31                           ` Rafael J. Wysocki
@ 2011-08-19  3:11                             ` Mark Brown
  2011-08-19 20:42                               ` Rafael J. Wysocki
  2011-08-19 20:42                               ` Rafael J. Wysocki
  2011-08-19  3:11                             ` Mark Brown
  1 sibling, 2 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-19  3:11 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Kevin Hilman, markgross, Linux PM mailing list, linux-omap, Jean Pihet

On Mon, 2011-08-08 at 23:31 +0200, Rafael J. Wysocki wrote:
> On Sunday, August 07, 2011, Mark Brown wrote:

> > OK, so this does sound like there's probably a genuine issue on PCs due
> > to limitations in the environment.  Is it possible to expose these
> > things to userspace in a way that's limited to the affected platforms?

> Well, in principle we could make it depend in CONFIG_ACPI or something like
> this, but I'm not sure that will be well-received. :-)

Or the drivers for the particular buses in use?

> > That does sound like a fair characterization for PCs.  For embedded
> > systems where we have a *much* better knowledge of the hardware we're
> > running on you're just working with the basics of what the hardware
> > needs to run - the hardware needs whatever it needs and no matter what
> > you think of the quality of the hardware there's an expectation that the
> > kernel is ging to be able to work.

> In the particular case in question, though, there's some freedom.  Namely,
> the hardware will work for many different QoS constraints and it's not
> precisely known in principle and upfront which one would be optimal for
> a given workload.

But are these tunings things that we can usefully represent in a generic
API or are they specific parameters of the subsystem in question? I
don't think anyone has suggested that having tuning for things where
there are genuine choices is a good thing.

> > As I've said it's not the fine tuning that I'm worried about, it's the
> > specific mechanism that's being suggested.  Being able to tune things in
> > a way that's relevant to the device being tuned seems entirely sensible.

> Do you know any better mechanism consistent accross all devices?
> Please be specific. :-)

Well, I'm suggesting that we shouldn't have a standard userspace API for
this in the first place but should instead be doing things on the
subsystem or driver level. I'm not sure we can sensibly do anything that
works usefully for all devices.

> > Realistically if you're in a position where you need to work at this
> > very low level on an embedded device you can replace the entire firmware
> > on the device.  We don't want to end up in the situation where we've got
> > kernel support for a device and the only way to get it to actually run
> > sensibly is to install the silicon vendor's proprietary userspace, and
> > we especially don't want to end up in the situation where that userspace
> > is using standard and supported kernel interfaces to do its thing.

> Well, the wakelocks example shows clearly that preventing certain interfaces
> from being merged into mainline doesn't actually prevent people from using
> them in actual products.  I claim it's way better if a vendor uses its
> proprietary user space with the mainline kernel than if that vendor patches
> the kernel and _then_ uses its proprietary user space with it.  Your
> argumentation seems to suggest that we encourage the latter.

We can't stop people doing questionable things out of tree but that
doesn't mean lowering standards in mainline is a good idea. Keeping
things out of tree creates a range of costs - the effort required to
write the code and update for new kernel releases, support issues when
the out of tree code causes problems and so on - and makes it clear to
people using the code where the costs came from. If the code looks like
it's standard code using standard interfaces much of that pressure goes
away.

This is similar to all the stuff that's going on in the ARM tree at the
minute - there's nothing we can do to prevent vendors shipping random
code of any quality in out of tree BSPs but we can set high standards
for the quality of code we accept into mainline and let the resulting
pressures push people towards mainline solutions.


^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-19  3:11                             ` Mark Brown
  2011-08-19 20:42                               ` Rafael J. Wysocki
@ 2011-08-19 20:42                               ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-19 20:42 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

Hi,

I really wouldn't like the discussion to go in circles.

First, please tell me what in particular you are objecting to,
because I don't think that's any of the patches that have been
sent to the linux-pm list to date.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-19  3:11                             ` Mark Brown
@ 2011-08-19 20:42                               ` Rafael J. Wysocki
  2011-08-19 23:14                                 ` Mark Brown
  2011-08-19 23:14                                 ` Mark Brown
  2011-08-19 20:42                               ` Rafael J. Wysocki
  1 sibling, 2 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-19 20:42 UTC (permalink / raw)
  To: Mark Brown
  Cc: Kevin Hilman, markgross, Linux PM mailing list, linux-omap, Jean Pihet

Hi,

I really wouldn't like the discussion to go in circles.

First, please tell me what in particular you are objecting to,
because I don't think that's any of the patches that have been
sent to the linux-pm list to date.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-19 20:42                               ` Rafael J. Wysocki
  2011-08-19 23:14                                 ` Mark Brown
@ 2011-08-19 23:14                                 ` Mark Brown
  1 sibling, 0 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-19 23:14 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Fri, Aug 19, 2011 at 10:42:20PM +0200, Rafael J. Wysocki wrote:

> I really wouldn't like the discussion to go in circles.

> First, please tell me what in particular you are objecting to,
> because I don't think that's any of the patches that have been
> sent to the linux-pm list to date.

The original issue that Kevin raised and CCed me in on was the idea of
exposing raw per-device wakeup latency constraints to userspace; it
seems much better to expose user level requirements via subsystem
interfaces and let the subsystem and driver translate these into actual
wakeup latency constraints:

  https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032422.html
  https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032428.html

This is much easier for users as it translates into something they're
actually doing (and in most cases the driver can make it Just Work) and
it means that off the shelf applications will end up tuning the system
appropriately by themselves.  I'm additionally concerned that if we
expose this stuff directly to userspace that's an open invitation to
driver authors to not even bother trying to make the kernel figure this
stuff out by itself and to instead tie the system together with magic
userspace.

In embedded systems this approach seems tractable and reasonable.  Your
concern seems to be that for PC class systems it's not going to be
possible to figure out the required latencies in the drivers reliably
enough to be useful so we'll need to punt to userspace and let users
tune their systems that way.  I can't speak for Kevin but I think my
preferred solution there would be to make this a feature of the relevant
systems rather than a standard feature that users can expect in the
Linux power management framework.

I think at some point in the discussion (you've not quoted any of the
text of the discussion for context...) you started thinking about other
constraints, different considerations may apply to those, I don't know
what other constraints we have.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-19 20:42                               ` Rafael J. Wysocki
@ 2011-08-19 23:14                                 ` Mark Brown
  2011-08-20  2:24                                   ` Alan Stern
                                                     ` (3 more replies)
  2011-08-19 23:14                                 ` Mark Brown
  1 sibling, 4 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-19 23:14 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Fri, Aug 19, 2011 at 10:42:20PM +0200, Rafael J. Wysocki wrote:

> I really wouldn't like the discussion to go in circles.

> First, please tell me what in particular you are objecting to,
> because I don't think that's any of the patches that have been
> sent to the linux-pm list to date.

The original issue that Kevin raised and CCed me in on was the idea of
exposing raw per-device wakeup latency constraints to userspace; it
seems much better to expose user level requirements via subsystem
interfaces and let the subsystem and driver translate these into actual
wakeup latency constraints:

  https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032422.html
  https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032428.html

This is much easier for users as it translates into something they're
actually doing (and in most cases the driver can make it Just Work) and
it means that off the shelf applications will end up tuning the system
appropriately by themselves.  I'm additionally concerned that if we
expose this stuff directly to userspace that's an open invitation to
driver authors to not even bother trying to make the kernel figure this
stuff out by itself and to instead tie the system together with magic
userspace.

In embedded systems this approach seems tractable and reasonable.  Your
concern seems to be that for PC class systems it's not going to be
possible to figure out the required latencies in the drivers reliably
enough to be useful so we'll need to punt to userspace and let users
tune their systems that way.  I can't speak for Kevin but I think my
preferred solution there would be to make this a feature of the relevant
systems rather than a standard feature that users can expect in the
Linux power management framework.

I think at some point in the discussion (you've not quoted any of the
text of the discussion for context...) you started thinking about other
constraints, different considerations may apply to those, I don't know
what other constraints we have.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-19 23:14                                 ` Mark Brown
@ 2011-08-20  2:24                                   ` Alan Stern
  2011-08-20  2:24                                   ` [linux-pm] " Alan Stern
                                                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 122+ messages in thread
From: Alan Stern @ 2011-08-20  2:24 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sat, 20 Aug 2011, Mark Brown wrote:

> The original issue that Kevin raised and CCed me in on was the idea of
> exposing raw per-device wakeup latency constraints to userspace; it
> seems much better to expose user level requirements via subsystem
> interfaces and let the subsystem and driver translate these into actual
> wakeup latency constraints:
> 
>   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032422.html
>   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032428.html
> 
> This is much easier for users as it translates into something they're
> actually doing (and in most cases the driver can make it Just Work) and
> it means that off the shelf applications will end up tuning the system
> appropriately by themselves.  I'm additionally concerned that if we
> expose this stuff directly to userspace that's an open invitation to
> driver authors to not even bother trying to make the kernel figure this
> stuff out by itself and to instead tie the system together with magic
> userspace.

Can you give a couple of examples to illustrate these points?  I think
it would help a lot to make the conversation more concrete.

Alan Stern

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-19 23:14                                 ` Mark Brown
  2011-08-20  2:24                                   ` Alan Stern
@ 2011-08-20  2:24                                   ` Alan Stern
  2011-08-20  6:25                                     ` Mark Brown
  2011-08-20  6:25                                     ` Mark Brown
  2011-08-20  9:35                                   ` Rafael J. Wysocki
  2011-08-20  9:35                                   ` [linux-pm] " Rafael J. Wysocki
  3 siblings, 2 replies; 122+ messages in thread
From: Alan Stern @ 2011-08-20  2:24 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rafael J. Wysocki, Linux PM mailing list, linux-omap, Jean Pihet,
	markgross

On Sat, 20 Aug 2011, Mark Brown wrote:

> The original issue that Kevin raised and CCed me in on was the idea of
> exposing raw per-device wakeup latency constraints to userspace; it
> seems much better to expose user level requirements via subsystem
> interfaces and let the subsystem and driver translate these into actual
> wakeup latency constraints:
> 
>   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032422.html
>   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032428.html
> 
> This is much easier for users as it translates into something they're
> actually doing (and in most cases the driver can make it Just Work) and
> it means that off the shelf applications will end up tuning the system
> appropriately by themselves.  I'm additionally concerned that if we
> expose this stuff directly to userspace that's an open invitation to
> driver authors to not even bother trying to make the kernel figure this
> stuff out by itself and to instead tie the system together with magic
> userspace.

Can you give a couple of examples to illustrate these points?  I think
it would help a lot to make the conversation more concrete.

Alan Stern


^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20  2:24                                   ` [linux-pm] " Alan Stern
  2011-08-20  6:25                                     ` Mark Brown
@ 2011-08-20  6:25                                     ` Mark Brown
  1 sibling, 0 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-20  6:25 UTC (permalink / raw)
  To: Alan Stern; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Fri, Aug 19, 2011 at 10:24:19PM -0400, Alan Stern wrote:
> On Sat, 20 Aug 2011, Mark Brown wrote:

> > interfaces and let the subsystem and driver translate these into actual
> > wakeup latency constraints:

> >   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032422.html
> >   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032428.html

> > This is much easier for users as it translates into something they're
> > actually doing (and in most cases the driver can make it Just Work) and
> > it means that off the shelf applications will end up tuning the system
> > appropriately by themselves.  I'm additionally concerned that if we
> > expose this stuff directly to userspace that's an open invitation to
> > driver authors to not even bother trying to make the kernel figure this
> > stuff out by itself and to instead tie the system together with magic
> > userspace.

> Can you give a couple of examples to illustrate these points?  I think
> it would help a lot to make the conversation more concrete.

Examples of what?  Latency constraints from drivers?  That'd be things
like Kevin listed in the second message linked above - the kernel knows
it needs to wake up within a given time period in order to have time to
do what it needs to do in response to a given wake source such as
filling a buffer before it underflows.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20  2:24                                   ` [linux-pm] " Alan Stern
@ 2011-08-20  6:25                                     ` Mark Brown
  2011-08-20 13:48                                       ` Alan Stern
  2011-08-20 13:48                                       ` [linux-pm] " Alan Stern
  2011-08-20  6:25                                     ` Mark Brown
  1 sibling, 2 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-20  6:25 UTC (permalink / raw)
  To: Alan Stern
  Cc: Rafael J. Wysocki, Linux PM mailing list, linux-omap, Jean Pihet,
	markgross

On Fri, Aug 19, 2011 at 10:24:19PM -0400, Alan Stern wrote:
> On Sat, 20 Aug 2011, Mark Brown wrote:

> > interfaces and let the subsystem and driver translate these into actual
> > wakeup latency constraints:

> >   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032422.html
> >   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032428.html

> > This is much easier for users as it translates into something they're
> > actually doing (and in most cases the driver can make it Just Work) and
> > it means that off the shelf applications will end up tuning the system
> > appropriately by themselves.  I'm additionally concerned that if we
> > expose this stuff directly to userspace that's an open invitation to
> > driver authors to not even bother trying to make the kernel figure this
> > stuff out by itself and to instead tie the system together with magic
> > userspace.

> Can you give a couple of examples to illustrate these points?  I think
> it would help a lot to make the conversation more concrete.

Examples of what?  Latency constraints from drivers?  That'd be things
like Kevin listed in the second message linked above - the kernel knows
it needs to wake up within a given time period in order to have time to
do what it needs to do in response to a given wake source such as
filling a buffer before it underflows.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-19 23:14                                 ` Mark Brown
  2011-08-20  2:24                                   ` Alan Stern
  2011-08-20  2:24                                   ` [linux-pm] " Alan Stern
@ 2011-08-20  9:35                                   ` Rafael J. Wysocki
  2011-08-20  9:35                                   ` [linux-pm] " Rafael J. Wysocki
  3 siblings, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-20  9:35 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Saturday, August 20, 2011, Mark Brown wrote:
> On Fri, Aug 19, 2011 at 10:42:20PM +0200, Rafael J. Wysocki wrote:
> 
> > I really wouldn't like the discussion to go in circles.
> 
> > First, please tell me what in particular you are objecting to,
> > because I don't think that's any of the patches that have been
> > sent to the linux-pm list to date.
> 
> The original issue that Kevin raised and CCed me in on was the idea of
> exposing raw per-device wakeup latency constraints to userspace; it
> seems much better to expose user level requirements via subsystem
> interfaces and let the subsystem and driver translate these into actual
> wakeup latency constraints:
> 
>   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032422.html
>   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032428.html

OK, so let's clarify things.

I'm not sure what you mean by "exposing per-device wakeup latency constraints
to user space".  I simply thought it might be useful to allow user space to
add and remove those, in analogy to what it can do with the currently available
PM QoS constraints.

My point is that this won't prevent kernel subsystems from adding their
own PM QoS constraints to devices and the constraints added by user space
will only have effect if they make the devices stay active for longer
times.  In consequence, they may only increase the energy usage of the system
and shouldn't affect functionality.

The reason why I think this may be useful is that I can readily imagine
scenarios in which user space (think a distribution or system vendor) will
want to do something that hasn't been anticipated by kernel developers
and the ability to add per-device PM QoS constraints will allow it to do that
without modifying the kernel.  Also, it will help to test and debug new drivers
and subsystems.

I don't want to prevent kernel subsystems from using their own interfaces to
acquire user-level input that translates into PM QoS constraints.  I simply
think it won't _hurt_ to provide user space with an additional level of
control over per-device PM QoS constraints.

> This is much easier for users as it translates into something they're
> actually doing (and in most cases the driver can make it Just Work) and
> it means that off the shelf applications will end up tuning the system
> appropriately by themselves.

The _end_ users really don't care.  They'll use whatever settings the user
interface exposes to them.  Moreover, even if there is an interface for
user space to add per-device PM QoS constraints, that doesn't mean the
user space is _required_ to use it.  If it doesn't, everything will work
as you describe.

> I'm additionally concerned that if we expose this stuff directly to userspace
> that's an open invitation to driver authors to not even bother trying to make
> the kernel figure this stuff out by itself and to instead tie the system
> together with magic userspace.

As I said, I don't think we can prevent that from happening anyway.
Worst case people will add strange interfaces to drivers making them
incompatible with anything except for their crazy user space.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-19 23:14                                 ` Mark Brown
                                                     ` (2 preceding siblings ...)
  2011-08-20  9:35                                   ` Rafael J. Wysocki
@ 2011-08-20  9:35                                   ` Rafael J. Wysocki
  2011-08-20 10:31                                     ` Mark Brown
  2011-08-20 10:31                                     ` [linux-pm] " Mark Brown
  3 siblings, 2 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-20  9:35 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Saturday, August 20, 2011, Mark Brown wrote:
> On Fri, Aug 19, 2011 at 10:42:20PM +0200, Rafael J. Wysocki wrote:
> 
> > I really wouldn't like the discussion to go in circles.
> 
> > First, please tell me what in particular you are objecting to,
> > because I don't think that's any of the patches that have been
> > sent to the linux-pm list to date.
> 
> The original issue that Kevin raised and CCed me in on was the idea of
> exposing raw per-device wakeup latency constraints to userspace; it
> seems much better to expose user level requirements via subsystem
> interfaces and let the subsystem and driver translate these into actual
> wakeup latency constraints:
> 
>   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032422.html
>   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032428.html

OK, so let's clarify things.

I'm not sure what you mean by "exposing per-device wakeup latency constraints
to user space".  I simply thought it might be useful to allow user space to
add and remove those, in analogy to what it can do with the currently available
PM QoS constraints.

My point is that this won't prevent kernel subsystems from adding their
own PM QoS constraints to devices and the constraints added by user space
will only have effect if they make the devices stay active for longer
times.  In consequence, they may only increase the energy usage of the system
and shouldn't affect functionality.

The reason why I think this may be useful is that I can readily imagine
scenarios in which user space (think a distribution or system vendor) will
want to do something that hasn't been anticipated by kernel developers
and the ability to add per-device PM QoS constraints will allow it to do that
without modifying the kernel.  Also, it will help to test and debug new drivers
and subsystems.

I don't want to prevent kernel subsystems from using their own interfaces to
acquire user-level input that translates into PM QoS constraints.  I simply
think it won't _hurt_ to provide user space with an additional level of
control over per-device PM QoS constraints.

> This is much easier for users as it translates into something they're
> actually doing (and in most cases the driver can make it Just Work) and
> it means that off the shelf applications will end up tuning the system
> appropriately by themselves.

The _end_ users really don't care.  They'll use whatever settings the user
interface exposes to them.  Moreover, even if there is an interface for
user space to add per-device PM QoS constraints, that doesn't mean the
user space is _required_ to use it.  If it doesn't, everything will work
as you describe.

> I'm additionally concerned that if we expose this stuff directly to userspace
> that's an open invitation to driver authors to not even bother trying to make
> the kernel figure this stuff out by itself and to instead tie the system
> together with magic userspace.

As I said, I don't think we can prevent that from happening anyway.
Worst case people will add strange interfaces to drivers making them
incompatible with anything except for their crazy user space.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20  9:35                                   ` [linux-pm] " Rafael J. Wysocki
@ 2011-08-20 10:31                                     ` Mark Brown
  2011-08-20 10:31                                     ` [linux-pm] " Mark Brown
  1 sibling, 0 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-20 10:31 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sat, Aug 20, 2011 at 11:35:58AM +0200, Rafael J. Wysocki wrote:

> I'm not sure what you mean by "exposing per-device wakeup latency constraints
> to user space".  I simply thought it might be useful to allow user space to
> add and remove those, in analogy to what it can do with the currently available
> PM QoS constraints.

I linked to the mails from Kevin...  To be honest I'm rather surprised
this stuff is getting exposed directly to userspace with write support.

> My point is that this won't prevent kernel subsystems from adding their
> own PM QoS constraints to devices and the constraints added by user space
> will only have effect if they make the devices stay active for longer
> times.  In consequence, they may only increase the energy usage of the system
> and shouldn't affect functionality.

Well, clearly that's not the only use - demand for increased energy
consumption by itself from users is generally quite low :)

> The reason why I think this may be useful is that I can readily imagine
> scenarios in which user space (think a distribution or system vendor) will
> want to do something that hasn't been anticipated by kernel developers
> and the ability to add per-device PM QoS constraints will allow it to do that

Coming at this from the embedded perspective modifying the kernel just
isn't an issue.  It's quite depressing in other cases too but some of
the circumstances you mentioned in previous messages are sensible do
make sense to me.  It does seem like this is a system specific problem
which we should be able to enable as part of the support for those
systems.

> without modifying the kernel.  Also, it will help to test and debug new drivers
> and subsystems.

If it were a debugfs facility I'd not be concerned.

> I don't want to prevent kernel subsystems from using their own interfaces to
> acquire user-level input that translates into PM QoS constraints.  I simply
> think it won't _hurt_ to provide user space with an additional level of
> control over per-device PM QoS constraints.

My experience has been that once you start providing an interface people
will find it, start using it and it takes a lot of work to convince them
that they ought to do something better.  This is totally reasonable from
when you look at things from their point of view, especially people who
aren't used to being able to improve anything except their own driver.

> > I'm additionally concerned that if we expose this stuff directly to userspace
> > that's an open invitation to driver authors to not even bother trying to make
> > the kernel figure this stuff out by itself and to instead tie the system
> > together with magic userspace.

> As I said, I don't think we can prevent that from happening anyway.
> Worst case people will add strange interfaces to drivers making them
> incompatible with anything except for their crazy user space.

That's not really a problem - if people are adding their own crazy
interfaces it's clear that they've done that.  It'll show up as a red
flag to anyone looking at their stuff and this will create pressure on
them to fix their code or at least do a better job for the next thing.

The goal isn't to tie people's hands to stop them doing silly things,
it's to make it clear that that is what they're doing.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20  9:35                                   ` [linux-pm] " Rafael J. Wysocki
  2011-08-20 10:31                                     ` Mark Brown
@ 2011-08-20 10:31                                     ` Mark Brown
  2011-08-20 16:51                                       ` Rafael J. Wysocki
  2011-08-20 16:51                                       ` [linux-pm] " Rafael J. Wysocki
  1 sibling, 2 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-20 10:31 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sat, Aug 20, 2011 at 11:35:58AM +0200, Rafael J. Wysocki wrote:

> I'm not sure what you mean by "exposing per-device wakeup latency constraints
> to user space".  I simply thought it might be useful to allow user space to
> add and remove those, in analogy to what it can do with the currently available
> PM QoS constraints.

I linked to the mails from Kevin...  To be honest I'm rather surprised
this stuff is getting exposed directly to userspace with write support.

> My point is that this won't prevent kernel subsystems from adding their
> own PM QoS constraints to devices and the constraints added by user space
> will only have effect if they make the devices stay active for longer
> times.  In consequence, they may only increase the energy usage of the system
> and shouldn't affect functionality.

Well, clearly that's not the only use - demand for increased energy
consumption by itself from users is generally quite low :)

> The reason why I think this may be useful is that I can readily imagine
> scenarios in which user space (think a distribution or system vendor) will
> want to do something that hasn't been anticipated by kernel developers
> and the ability to add per-device PM QoS constraints will allow it to do that

Coming at this from the embedded perspective modifying the kernel just
isn't an issue.  It's quite depressing in other cases too but some of
the circumstances you mentioned in previous messages are sensible do
make sense to me.  It does seem like this is a system specific problem
which we should be able to enable as part of the support for those
systems.

> without modifying the kernel.  Also, it will help to test and debug new drivers
> and subsystems.

If it were a debugfs facility I'd not be concerned.

> I don't want to prevent kernel subsystems from using their own interfaces to
> acquire user-level input that translates into PM QoS constraints.  I simply
> think it won't _hurt_ to provide user space with an additional level of
> control over per-device PM QoS constraints.

My experience has been that once you start providing an interface people
will find it, start using it and it takes a lot of work to convince them
that they ought to do something better.  This is totally reasonable from
when you look at things from their point of view, especially people who
aren't used to being able to improve anything except their own driver.

> > I'm additionally concerned that if we expose this stuff directly to userspace
> > that's an open invitation to driver authors to not even bother trying to make
> > the kernel figure this stuff out by itself and to instead tie the system
> > together with magic userspace.

> As I said, I don't think we can prevent that from happening anyway.
> Worst case people will add strange interfaces to drivers making them
> incompatible with anything except for their crazy user space.

That's not really a problem - if people are adding their own crazy
interfaces it's clear that they've done that.  It'll show up as a red
flag to anyone looking at their stuff and this will create pressure on
them to fix their code or at least do a better job for the next thing.

The goal isn't to tie people's hands to stop them doing silly things,
it's to make it clear that that is what they're doing.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20  6:25                                     ` Mark Brown
@ 2011-08-20 13:48                                       ` Alan Stern
  2011-08-20 13:48                                       ` [linux-pm] " Alan Stern
  1 sibling, 0 replies; 122+ messages in thread
From: Alan Stern @ 2011-08-20 13:48 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sat, 20 Aug 2011, Mark Brown wrote:

> On Fri, Aug 19, 2011 at 10:24:19PM -0400, Alan Stern wrote:
> > On Sat, 20 Aug 2011, Mark Brown wrote:
> 
> > > interfaces and let the subsystem and driver translate these into actual
> > > wakeup latency constraints:
> 
> > >   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032422.html
> > >   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032428.html
> 
> > > This is much easier for users as it translates into something they're
> > > actually doing (and in most cases the driver can make it Just Work) and
> > > it means that off the shelf applications will end up tuning the system
> > > appropriately by themselves.  I'm additionally concerned that if we
> > > expose this stuff directly to userspace that's an open invitation to
> > > driver authors to not even bother trying to make the kernel figure this
> > > stuff out by itself and to instead tie the system together with magic
> > > userspace.
> 
> > Can you give a couple of examples to illustrate these points?  I think
> > it would help a lot to make the conversation more concrete.
> 
> Examples of what?  Latency constraints from drivers?  That'd be things
> like Kevin listed in the second message linked above - the kernel knows
> it needs to wake up within a given time period in order to have time to
> do what it needs to do in response to a given wake source such as
> filling a buffer before it underflows.

No, I as wasking about driver- and subsystem-specific interfaces to
userspace that translate into things users are already doing.  Kevin's
example was a touchscreen (although that was really an example of
setting a power usage level, not a latency constraint).  Do you have
any others?

Alan Stern

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20  6:25                                     ` Mark Brown
  2011-08-20 13:48                                       ` Alan Stern
@ 2011-08-20 13:48                                       ` Alan Stern
  2011-08-20 15:30                                         ` Mark Brown
  2011-08-20 15:30                                         ` Mark Brown
  1 sibling, 2 replies; 122+ messages in thread
From: Alan Stern @ 2011-08-20 13:48 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rafael J. Wysocki, Linux PM mailing list, linux-omap, Jean Pihet,
	markgross

On Sat, 20 Aug 2011, Mark Brown wrote:

> On Fri, Aug 19, 2011 at 10:24:19PM -0400, Alan Stern wrote:
> > On Sat, 20 Aug 2011, Mark Brown wrote:
> 
> > > interfaces and let the subsystem and driver translate these into actual
> > > wakeup latency constraints:
> 
> > >   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032422.html
> > >   https://lists.linux-foundation.org/pipermail/linux-pm/2011-August/032428.html
> 
> > > This is much easier for users as it translates into something they're
> > > actually doing (and in most cases the driver can make it Just Work) and
> > > it means that off the shelf applications will end up tuning the system
> > > appropriately by themselves.  I'm additionally concerned that if we
> > > expose this stuff directly to userspace that's an open invitation to
> > > driver authors to not even bother trying to make the kernel figure this
> > > stuff out by itself and to instead tie the system together with magic
> > > userspace.
> 
> > Can you give a couple of examples to illustrate these points?  I think
> > it would help a lot to make the conversation more concrete.
> 
> Examples of what?  Latency constraints from drivers?  That'd be things
> like Kevin listed in the second message linked above - the kernel knows
> it needs to wake up within a given time period in order to have time to
> do what it needs to do in response to a given wake source such as
> filling a buffer before it underflows.

No, I as wasking about driver- and subsystem-specific interfaces to
userspace that translate into things users are already doing.  Kevin's
example was a touchscreen (although that was really an example of
setting a power usage level, not a latency constraint).  Do you have
any others?

Alan Stern


^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 13:48                                       ` [linux-pm] " Alan Stern
  2011-08-20 15:30                                         ` Mark Brown
@ 2011-08-20 15:30                                         ` Mark Brown
  1 sibling, 0 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-20 15:30 UTC (permalink / raw)
  To: Alan Stern; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sat, Aug 20, 2011 at 09:48:25AM -0400, Alan Stern wrote:

> No, I as wasking about driver- and subsystem-specific interfaces to
> userspace that translate into things users are already doing.  Kevin's
> example was a touchscreen (although that was really an example of
> setting a power usage level, not a latency constraint).  Do you have
> any others?

Any sort of media streaming would be an obvious example - the
application picks the amount of data it buffers and how often it's
notified of progress depending on the usage which then controls how
quickly the system needs to handle things.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 13:48                                       ` [linux-pm] " Alan Stern
@ 2011-08-20 15:30                                         ` Mark Brown
  2011-08-20 16:34                                           ` Rafael J. Wysocki
  2011-08-20 16:34                                           ` Rafael J. Wysocki
  2011-08-20 15:30                                         ` Mark Brown
  1 sibling, 2 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-20 15:30 UTC (permalink / raw)
  To: Alan Stern
  Cc: Rafael J. Wysocki, Linux PM mailing list, linux-omap, Jean Pihet,
	markgross

On Sat, Aug 20, 2011 at 09:48:25AM -0400, Alan Stern wrote:

> No, I as wasking about driver- and subsystem-specific interfaces to
> userspace that translate into things users are already doing.  Kevin's
> example was a touchscreen (although that was really an example of
> setting a power usage level, not a latency constraint).  Do you have
> any others?

Any sort of media streaming would be an obvious example - the
application picks the amount of data it buffers and how often it's
notified of progress depending on the usage which then controls how
quickly the system needs to handle things.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 15:30                                         ` Mark Brown
  2011-08-20 16:34                                           ` Rafael J. Wysocki
@ 2011-08-20 16:34                                           ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-20 16:34 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Saturday, August 20, 2011, Mark Brown wrote:
> On Sat, Aug 20, 2011 at 09:48:25AM -0400, Alan Stern wrote:
> 
> > No, I as wasking about driver- and subsystem-specific interfaces to
> > userspace that translate into things users are already doing.  Kevin's
> > example was a touchscreen (although that was really an example of
> > setting a power usage level, not a latency constraint).  Do you have
> > any others?
> 
> Any sort of media streaming would be an obvious example - the
> application picks the amount of data it buffers and how often it's
> notified of progress depending on the usage which then controls how
> quickly the system needs to handle things.

Well, what about other types of devices?

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 15:30                                         ` Mark Brown
@ 2011-08-20 16:34                                           ` Rafael J. Wysocki
  2011-08-20 17:04                                             ` Mark Brown
  2011-08-20 17:04                                             ` [linux-pm] " Mark Brown
  2011-08-20 16:34                                           ` Rafael J. Wysocki
  1 sibling, 2 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-20 16:34 UTC (permalink / raw)
  To: Mark Brown
  Cc: Alan Stern, Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Saturday, August 20, 2011, Mark Brown wrote:
> On Sat, Aug 20, 2011 at 09:48:25AM -0400, Alan Stern wrote:
> 
> > No, I as wasking about driver- and subsystem-specific interfaces to
> > userspace that translate into things users are already doing.  Kevin's
> > example was a touchscreen (although that was really an example of
> > setting a power usage level, not a latency constraint).  Do you have
> > any others?
> 
> Any sort of media streaming would be an obvious example - the
> application picks the amount of data it buffers and how often it's
> notified of progress depending on the usage which then controls how
> quickly the system needs to handle things.

Well, what about other types of devices?

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 10:31                                     ` [linux-pm] " Mark Brown
@ 2011-08-20 16:51                                       ` Rafael J. Wysocki
  2011-08-20 16:51                                       ` [linux-pm] " Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-20 16:51 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Saturday, August 20, 2011, Mark Brown wrote:
> On Sat, Aug 20, 2011 at 11:35:58AM +0200, Rafael J. Wysocki wrote:
> 
> > I'm not sure what you mean by "exposing per-device wakeup latency constraints
> > to user space".  I simply thought it might be useful to allow user space to
> > add and remove those, in analogy to what it can do with the currently available
> > PM QoS constraints.
> 
> I linked to the mails from Kevin...  To be honest I'm rather surprised
> this stuff is getting exposed directly to userspace with write support.
> 
> > My point is that this won't prevent kernel subsystems from adding their
> > own PM QoS constraints to devices and the constraints added by user space
> > will only have effect if they make the devices stay active for longer
> > times.  In consequence, they may only increase the energy usage of the system
> > and shouldn't affect functionality.
> 
> Well, clearly that's not the only use - demand for increased energy
> consumption by itself from users is generally quite low :)
> 
> > The reason why I think this may be useful is that I can readily imagine
> > scenarios in which user space (think a distribution or system vendor) will
> > want to do something that hasn't been anticipated by kernel developers
> > and the ability to add per-device PM QoS constraints will allow it to do that
> 
> Coming at this from the embedded perspective modifying the kernel just
> isn't an issue.  It's quite depressing in other cases too but some of
> the circumstances you mentioned in previous messages are sensible do
> make sense to me.  It does seem like this is a system specific problem
> which we should be able to enable as part of the support for those
> systems.

I don't think that's platform-specific in general.  For example, there are
devices that don't really belong to any media-streaming-alike framework
and we may (and probably will) want to use PM QoS with them, because they
may be included in PM domains and influence power management of other
devices.  Think of a serial console.

> > without modifying the kernel.  Also, it will help to test and debug new drivers
> > and subsystems.
> 
> If it were a debugfs facility I'd not be concerned.

If that's going to be per-device, it really is much easier to put it into
sysfs (we already have per-device PM debug interfaces in there).  It may
depend on CONFIG_PM_ADVANCED_DEBUG or something like this, though, at least
to start with.

> > I don't want to prevent kernel subsystems from using their own interfaces to
> > acquire user-level input that translates into PM QoS constraints.  I simply
> > think it won't _hurt_ to provide user space with an additional level of
> > control over per-device PM QoS constraints.
> 
> My experience has been that once you start providing an interface people
> will find it, start using it and it takes a lot of work to convince them
> that they ought to do something better.  This is totally reasonable from
> when you look at things from their point of view, especially people who
> aren't used to being able to improve anything except their own driver.

There are ways to make people do right things. :-)

Anyway, if an interface is provided, people are free to use it and it
kind of is their problem if they do that for unreasonable things.  That
might be an issue for us if we were to remove that interface going forward,
but I'm not sure if that's going to ever happen.

> > > I'm additionally concerned that if we expose this stuff directly to userspace
> > > that's an open invitation to driver authors to not even bother trying to make
> > > the kernel figure this stuff out by itself and to instead tie the system
> > > together with magic userspace.
> 
> > As I said, I don't think we can prevent that from happening anyway.
> > Worst case people will add strange interfaces to drivers making them
> > incompatible with anything except for their crazy user space.
> 
> That's not really a problem - if people are adding their own crazy
> interfaces it's clear that they've done that.  It'll show up as a red
> flag to anyone looking at their stuff and this will create pressure on
> them to fix their code or at least do a better job for the next thing.
> 
> The goal isn't to tie people's hands to stop them doing silly things,
> it's to make it clear that that is what they're doing.

The same applies to using kernel interfaces.  If someone uses a sane
interface for doing crazy stuff, that's their problem and should show
up as a red flag just as well.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 10:31                                     ` [linux-pm] " Mark Brown
  2011-08-20 16:51                                       ` Rafael J. Wysocki
@ 2011-08-20 16:51                                       ` Rafael J. Wysocki
  2011-08-20 17:22                                         ` Mark Brown
  2011-08-20 17:22                                         ` [linux-pm] " Mark Brown
  1 sibling, 2 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-20 16:51 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Saturday, August 20, 2011, Mark Brown wrote:
> On Sat, Aug 20, 2011 at 11:35:58AM +0200, Rafael J. Wysocki wrote:
> 
> > I'm not sure what you mean by "exposing per-device wakeup latency constraints
> > to user space".  I simply thought it might be useful to allow user space to
> > add and remove those, in analogy to what it can do with the currently available
> > PM QoS constraints.
> 
> I linked to the mails from Kevin...  To be honest I'm rather surprised
> this stuff is getting exposed directly to userspace with write support.
> 
> > My point is that this won't prevent kernel subsystems from adding their
> > own PM QoS constraints to devices and the constraints added by user space
> > will only have effect if they make the devices stay active for longer
> > times.  In consequence, they may only increase the energy usage of the system
> > and shouldn't affect functionality.
> 
> Well, clearly that's not the only use - demand for increased energy
> consumption by itself from users is generally quite low :)
> 
> > The reason why I think this may be useful is that I can readily imagine
> > scenarios in which user space (think a distribution or system vendor) will
> > want to do something that hasn't been anticipated by kernel developers
> > and the ability to add per-device PM QoS constraints will allow it to do that
> 
> Coming at this from the embedded perspective modifying the kernel just
> isn't an issue.  It's quite depressing in other cases too but some of
> the circumstances you mentioned in previous messages are sensible do
> make sense to me.  It does seem like this is a system specific problem
> which we should be able to enable as part of the support for those
> systems.

I don't think that's platform-specific in general.  For example, there are
devices that don't really belong to any media-streaming-alike framework
and we may (and probably will) want to use PM QoS with them, because they
may be included in PM domains and influence power management of other
devices.  Think of a serial console.

> > without modifying the kernel.  Also, it will help to test and debug new drivers
> > and subsystems.
> 
> If it were a debugfs facility I'd not be concerned.

If that's going to be per-device, it really is much easier to put it into
sysfs (we already have per-device PM debug interfaces in there).  It may
depend on CONFIG_PM_ADVANCED_DEBUG or something like this, though, at least
to start with.

> > I don't want to prevent kernel subsystems from using their own interfaces to
> > acquire user-level input that translates into PM QoS constraints.  I simply
> > think it won't _hurt_ to provide user space with an additional level of
> > control over per-device PM QoS constraints.
> 
> My experience has been that once you start providing an interface people
> will find it, start using it and it takes a lot of work to convince them
> that they ought to do something better.  This is totally reasonable from
> when you look at things from their point of view, especially people who
> aren't used to being able to improve anything except their own driver.

There are ways to make people do right things. :-)

Anyway, if an interface is provided, people are free to use it and it
kind of is their problem if they do that for unreasonable things.  That
might be an issue for us if we were to remove that interface going forward,
but I'm not sure if that's going to ever happen.

> > > I'm additionally concerned that if we expose this stuff directly to userspace
> > > that's an open invitation to driver authors to not even bother trying to make
> > > the kernel figure this stuff out by itself and to instead tie the system
> > > together with magic userspace.
> 
> > As I said, I don't think we can prevent that from happening anyway.
> > Worst case people will add strange interfaces to drivers making them
> > incompatible with anything except for their crazy user space.
> 
> That's not really a problem - if people are adding their own crazy
> interfaces it's clear that they've done that.  It'll show up as a red
> flag to anyone looking at their stuff and this will create pressure on
> them to fix their code or at least do a better job for the next thing.
> 
> The goal isn't to tie people's hands to stop them doing silly things,
> it's to make it clear that that is what they're doing.

The same applies to using kernel interfaces.  If someone uses a sane
interface for doing crazy stuff, that's their problem and should show
up as a red flag just as well.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 16:34                                           ` Rafael J. Wysocki
@ 2011-08-20 17:04                                             ` Mark Brown
  2011-08-20 17:04                                             ` [linux-pm] " Mark Brown
  1 sibling, 0 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-20 17:04 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sat, Aug 20, 2011 at 06:34:34PM +0200, Rafael J. Wysocki wrote:
> On Saturday, August 20, 2011, Mark Brown wrote:

> > Any sort of media streaming would be an obvious example - the
> > application picks the amount of data it buffers and how often it's
> > notified of progress depending on the usage which then controls how
> > quickly the system needs to handle things.

> Well, what about other types of devices?

Other than the input case (which is a latency issue - there's two
components, one is how much data is delivered for things like
touchscreens which stream and the other is how quickly the first data is
delivered) nothing immediately springs to mind but this may just be a
product of what I'm most familiar with.  I don't really see this as a
problem, for a lot of devices it's probably the case that the device can
figure out something sensible to do without any help.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 16:34                                           ` Rafael J. Wysocki
  2011-08-20 17:04                                             ` Mark Brown
@ 2011-08-20 17:04                                             ` Mark Brown
  2011-08-20 19:14                                               ` Rafael J. Wysocki
  2011-08-20 19:14                                               ` Rafael J. Wysocki
  1 sibling, 2 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-20 17:04 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Alan Stern, Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sat, Aug 20, 2011 at 06:34:34PM +0200, Rafael J. Wysocki wrote:
> On Saturday, August 20, 2011, Mark Brown wrote:

> > Any sort of media streaming would be an obvious example - the
> > application picks the amount of data it buffers and how often it's
> > notified of progress depending on the usage which then controls how
> > quickly the system needs to handle things.

> Well, what about other types of devices?

Other than the input case (which is a latency issue - there's two
components, one is how much data is delivered for things like
touchscreens which stream and the other is how quickly the first data is
delivered) nothing immediately springs to mind but this may just be a
product of what I'm most familiar with.  I don't really see this as a
problem, for a lot of devices it's probably the case that the device can
figure out something sensible to do without any help.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 16:51                                       ` [linux-pm] " Rafael J. Wysocki
@ 2011-08-20 17:22                                         ` Mark Brown
  2011-08-20 17:22                                         ` [linux-pm] " Mark Brown
  1 sibling, 0 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-20 17:22 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sat, Aug 20, 2011 at 06:51:42PM +0200, Rafael J. Wysocki wrote:
> On Saturday, August 20, 2011, Mark Brown wrote:

> > Coming at this from the embedded perspective modifying the kernel just
> > isn't an issue.  It's quite depressing in other cases too but some of
> > the circumstances you mentioned in previous messages are sensible do
> > make sense to me.  It does seem like this is a system specific problem
> > which we should be able to enable as part of the support for those
> > systems.

> I don't think that's platform-specific in general.  For example, there are
> devices that don't really belong to any media-streaming-alike framework
> and we may (and probably will) want to use PM QoS with them, because they
> may be included in PM domains and influence power management of other
> devices.  Think of a serial console.

Using PM QoS doesn't seem platform specific of course.  Having userspace
need to go in and do per-device overrides in order to get things working
does.

> > > without modifying the kernel.  Also, it will help to test and debug new drivers
> > > and subsystems.

> > If it were a debugfs facility I'd not be concerned.

> If that's going to be per-device, it really is much easier to put it into
> sysfs (we already have per-device PM debug interfaces in there).  It may
> depend on CONFIG_PM_ADVANCED_DEBUG or something like this, though, at least
> to start with.

Yeah, the debugfs device attachment stuff is slightly annoying but it's
fairly straightforward to create an appropriate heirachy - there's
several subsystems doing that sort of stuff by using dev_name().

> > That's not really a problem - if people are adding their own crazy
> > interfaces it's clear that they've done that.  It'll show up as a red
> > flag to anyone looking at their stuff and this will create pressure on
> > them to fix their code or at least do a better job for the next thing.

> > The goal isn't to tie people's hands to stop them doing silly things,
> > it's to make it clear that that is what they're doing.

> The same applies to using kernel interfaces.  If someone uses a sane
> interface for doing crazy stuff, that's their problem and should show
> up as a red flag just as well.

The big problem I'm seeing here is that there's nothing about having
userspace do all the knob twiddling that looks crazy just from looking
at the system.  The controls are there and in the standard kernel
interface, it's not like there's any ABIs or large piles of in kernel
code that need to be added (if anything the in kernel code should look
simpler as there's less going on).

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 16:51                                       ` [linux-pm] " Rafael J. Wysocki
  2011-08-20 17:22                                         ` Mark Brown
@ 2011-08-20 17:22                                         ` Mark Brown
  2011-08-20 19:18                                           ` Rafael J. Wysocki
  2011-08-20 19:18                                           ` Rafael J. Wysocki
  1 sibling, 2 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-20 17:22 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sat, Aug 20, 2011 at 06:51:42PM +0200, Rafael J. Wysocki wrote:
> On Saturday, August 20, 2011, Mark Brown wrote:

> > Coming at this from the embedded perspective modifying the kernel just
> > isn't an issue.  It's quite depressing in other cases too but some of
> > the circumstances you mentioned in previous messages are sensible do
> > make sense to me.  It does seem like this is a system specific problem
> > which we should be able to enable as part of the support for those
> > systems.

> I don't think that's platform-specific in general.  For example, there are
> devices that don't really belong to any media-streaming-alike framework
> and we may (and probably will) want to use PM QoS with them, because they
> may be included in PM domains and influence power management of other
> devices.  Think of a serial console.

Using PM QoS doesn't seem platform specific of course.  Having userspace
need to go in and do per-device overrides in order to get things working
does.

> > > without modifying the kernel.  Also, it will help to test and debug new drivers
> > > and subsystems.

> > If it were a debugfs facility I'd not be concerned.

> If that's going to be per-device, it really is much easier to put it into
> sysfs (we already have per-device PM debug interfaces in there).  It may
> depend on CONFIG_PM_ADVANCED_DEBUG or something like this, though, at least
> to start with.

Yeah, the debugfs device attachment stuff is slightly annoying but it's
fairly straightforward to create an appropriate heirachy - there's
several subsystems doing that sort of stuff by using dev_name().

> > That's not really a problem - if people are adding their own crazy
> > interfaces it's clear that they've done that.  It'll show up as a red
> > flag to anyone looking at their stuff and this will create pressure on
> > them to fix their code or at least do a better job for the next thing.

> > The goal isn't to tie people's hands to stop them doing silly things,
> > it's to make it clear that that is what they're doing.

> The same applies to using kernel interfaces.  If someone uses a sane
> interface for doing crazy stuff, that's their problem and should show
> up as a red flag just as well.

The big problem I'm seeing here is that there's nothing about having
userspace do all the knob twiddling that looks crazy just from looking
at the system.  The controls are there and in the standard kernel
interface, it's not like there's any ABIs or large piles of in kernel
code that need to be added (if anything the in kernel code should look
simpler as there's less going on).

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 17:04                                             ` [linux-pm] " Mark Brown
  2011-08-20 19:14                                               ` Rafael J. Wysocki
@ 2011-08-20 19:14                                               ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-20 19:14 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Saturday, August 20, 2011, Mark Brown wrote:
> On Sat, Aug 20, 2011 at 06:34:34PM +0200, Rafael J. Wysocki wrote:
> > On Saturday, August 20, 2011, Mark Brown wrote:
> 
> > > Any sort of media streaming would be an obvious example - the
> > > application picks the amount of data it buffers and how often it's
> > > notified of progress depending on the usage which then controls how
> > > quickly the system needs to handle things.
> 
> > Well, what about other types of devices?
> 
> Other than the input case (which is a latency issue - there's two
> components, one is how much data is delivered for things like
> touchscreens which stream and the other is how quickly the first data is
> delivered) nothing immediately springs to mind but this may just be a
> product of what I'm most familiar with.  I don't really see this as a
> problem, for a lot of devices it's probably the case that the device can
> figure out something sensible to do without any help.

I guess you mean the driver here and I'm not really sure it can.
For instance, the driver may not know what configuration it works in,
e.g. is there a power domain or a hierarchy of those and how much time
it takes to power them all down and up and what the power break even is.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 17:04                                             ` [linux-pm] " Mark Brown
@ 2011-08-20 19:14                                               ` Rafael J. Wysocki
  2011-08-21  8:25                                                 ` Mark Brown
  2011-08-21  8:25                                                 ` [linux-pm] " Mark Brown
  2011-08-20 19:14                                               ` Rafael J. Wysocki
  1 sibling, 2 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-20 19:14 UTC (permalink / raw)
  To: Mark Brown
  Cc: Alan Stern, Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Saturday, August 20, 2011, Mark Brown wrote:
> On Sat, Aug 20, 2011 at 06:34:34PM +0200, Rafael J. Wysocki wrote:
> > On Saturday, August 20, 2011, Mark Brown wrote:
> 
> > > Any sort of media streaming would be an obvious example - the
> > > application picks the amount of data it buffers and how often it's
> > > notified of progress depending on the usage which then controls how
> > > quickly the system needs to handle things.
> 
> > Well, what about other types of devices?
> 
> Other than the input case (which is a latency issue - there's two
> components, one is how much data is delivered for things like
> touchscreens which stream and the other is how quickly the first data is
> delivered) nothing immediately springs to mind but this may just be a
> product of what I'm most familiar with.  I don't really see this as a
> problem, for a lot of devices it's probably the case that the device can
> figure out something sensible to do without any help.

I guess you mean the driver here and I'm not really sure it can.
For instance, the driver may not know what configuration it works in,
e.g. is there a power domain or a hierarchy of those and how much time
it takes to power them all down and up and what the power break even is.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 17:22                                         ` [linux-pm] " Mark Brown
  2011-08-20 19:18                                           ` Rafael J. Wysocki
@ 2011-08-20 19:18                                           ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-20 19:18 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Saturday, August 20, 2011, Mark Brown wrote:
> On Sat, Aug 20, 2011 at 06:51:42PM +0200, Rafael J. Wysocki wrote:
> > On Saturday, August 20, 2011, Mark Brown wrote:
> 
> > > Coming at this from the embedded perspective modifying the kernel just
> > > isn't an issue.  It's quite depressing in other cases too but some of
> > > the circumstances you mentioned in previous messages are sensible do
> > > make sense to me.  It does seem like this is a system specific problem
> > > which we should be able to enable as part of the support for those
> > > systems.
> 
> > I don't think that's platform-specific in general.  For example, there are
> > devices that don't really belong to any media-streaming-alike framework
> > and we may (and probably will) want to use PM QoS with them, because they
> > may be included in PM domains and influence power management of other
> > devices.  Think of a serial console.
> 
> Using PM QoS doesn't seem platform specific of course.  Having userspace
> need to go in and do per-device overrides in order to get things working
> does.
> 
> > > > without modifying the kernel.  Also, it will help to test and debug new drivers
> > > > and subsystems.
> 
> > > If it were a debugfs facility I'd not be concerned.
> 
> > If that's going to be per-device, it really is much easier to put it into
> > sysfs (we already have per-device PM debug interfaces in there).  It may
> > depend on CONFIG_PM_ADVANCED_DEBUG or something like this, though, at least
> > to start with.
> 
> Yeah, the debugfs device attachment stuff is slightly annoying but it's
> fairly straightforward to create an appropriate heirachy - there's
> several subsystems doing that sort of stuff by using dev_name().

I'm not a big fan of that, sorry.  Besides, as I said, we already have
debug PM interfaces in sysfs, so I don't see the reason not to add
another one.

> > > That's not really a problem - if people are adding their own crazy
> > > interfaces it's clear that they've done that.  It'll show up as a red
> > > flag to anyone looking at their stuff and this will create pressure on
> > > them to fix their code or at least do a better job for the next thing.
> 
> > > The goal isn't to tie people's hands to stop them doing silly things,
> > > it's to make it clear that that is what they're doing.
> 
> > The same applies to using kernel interfaces.  If someone uses a sane
> > interface for doing crazy stuff, that's their problem and should show
> > up as a red flag just as well.
> 
> The big problem I'm seeing here is that there's nothing about having
> userspace do all the knob twiddling that looks crazy just from looking
> at the system.  The controls are there and in the standard kernel
> interface, it's not like there's any ABIs or large piles of in kernel
> code that need to be added (if anything the in kernel code should look
> simpler as there's less going on).

Well, I'm kind of not seeing that as a big problem.  At least, this is not
a technical issue, but a social one.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 17:22                                         ` [linux-pm] " Mark Brown
@ 2011-08-20 19:18                                           ` Rafael J. Wysocki
  2011-08-20 19:18                                           ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-20 19:18 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Saturday, August 20, 2011, Mark Brown wrote:
> On Sat, Aug 20, 2011 at 06:51:42PM +0200, Rafael J. Wysocki wrote:
> > On Saturday, August 20, 2011, Mark Brown wrote:
> 
> > > Coming at this from the embedded perspective modifying the kernel just
> > > isn't an issue.  It's quite depressing in other cases too but some of
> > > the circumstances you mentioned in previous messages are sensible do
> > > make sense to me.  It does seem like this is a system specific problem
> > > which we should be able to enable as part of the support for those
> > > systems.
> 
> > I don't think that's platform-specific in general.  For example, there are
> > devices that don't really belong to any media-streaming-alike framework
> > and we may (and probably will) want to use PM QoS with them, because they
> > may be included in PM domains and influence power management of other
> > devices.  Think of a serial console.
> 
> Using PM QoS doesn't seem platform specific of course.  Having userspace
> need to go in and do per-device overrides in order to get things working
> does.
> 
> > > > without modifying the kernel.  Also, it will help to test and debug new drivers
> > > > and subsystems.
> 
> > > If it were a debugfs facility I'd not be concerned.
> 
> > If that's going to be per-device, it really is much easier to put it into
> > sysfs (we already have per-device PM debug interfaces in there).  It may
> > depend on CONFIG_PM_ADVANCED_DEBUG or something like this, though, at least
> > to start with.
> 
> Yeah, the debugfs device attachment stuff is slightly annoying but it's
> fairly straightforward to create an appropriate heirachy - there's
> several subsystems doing that sort of stuff by using dev_name().

I'm not a big fan of that, sorry.  Besides, as I said, we already have
debug PM interfaces in sysfs, so I don't see the reason not to add
another one.

> > > That's not really a problem - if people are adding their own crazy
> > > interfaces it's clear that they've done that.  It'll show up as a red
> > > flag to anyone looking at their stuff and this will create pressure on
> > > them to fix their code or at least do a better job for the next thing.
> 
> > > The goal isn't to tie people's hands to stop them doing silly things,
> > > it's to make it clear that that is what they're doing.
> 
> > The same applies to using kernel interfaces.  If someone uses a sane
> > interface for doing crazy stuff, that's their problem and should show
> > up as a red flag just as well.
> 
> The big problem I'm seeing here is that there's nothing about having
> userspace do all the knob twiddling that looks crazy just from looking
> at the system.  The controls are there and in the standard kernel
> interface, it's not like there's any ABIs or large piles of in kernel
> code that need to be added (if anything the in kernel code should look
> simpler as there's less going on).

Well, I'm kind of not seeing that as a big problem.  At least, this is not
a technical issue, but a social one.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 19:14                                               ` Rafael J. Wysocki
@ 2011-08-21  8:25                                                 ` Mark Brown
  2011-08-21  8:25                                                 ` [linux-pm] " Mark Brown
  1 sibling, 0 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-21  8:25 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sat, Aug 20, 2011 at 09:14:37PM +0200, Rafael J. Wysocki wrote:

> I guess you mean the driver here and I'm not really sure it can.
> For instance, the driver may not know what configuration it works in,
> e.g. is there a power domain or a hierarchy of those and how much time
> it takes to power them all down and up and what the power break even is.

I don't understand why the driver would need to know what situation it's
in.  I'd been working on the basis that the idea was that the driver
said what the constraints it has are and then some code with a more
system wide view would make the actual decisions for things outside the
driver domian.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-20 19:14                                               ` Rafael J. Wysocki
  2011-08-21  8:25                                                 ` Mark Brown
@ 2011-08-21  8:25                                                 ` Mark Brown
  2011-08-21 18:05                                                   ` Rafael J. Wysocki
  2011-08-21 18:05                                                   ` Rafael J. Wysocki
  1 sibling, 2 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-21  8:25 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Alan Stern, Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sat, Aug 20, 2011 at 09:14:37PM +0200, Rafael J. Wysocki wrote:

> I guess you mean the driver here and I'm not really sure it can.
> For instance, the driver may not know what configuration it works in,
> e.g. is there a power domain or a hierarchy of those and how much time
> it takes to power them all down and up and what the power break even is.

I don't understand why the driver would need to know what situation it's
in.  I'd been working on the basis that the idea was that the driver
said what the constraints it has are and then some code with a more
system wide view would make the actual decisions for things outside the
driver domian.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-21  8:25                                                 ` [linux-pm] " Mark Brown
  2011-08-21 18:05                                                   ` Rafael J. Wysocki
@ 2011-08-21 18:05                                                   ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-21 18:05 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sunday, August 21, 2011, Mark Brown wrote:
> On Sat, Aug 20, 2011 at 09:14:37PM +0200, Rafael J. Wysocki wrote:
> 
> > I guess you mean the driver here and I'm not really sure it can.
> > For instance, the driver may not know what configuration it works in,
> > e.g. is there a power domain or a hierarchy of those and how much time
> > it takes to power them all down and up and what the power break even is.
> 
> I don't understand why the driver would need to know what situation it's
> in.  I'd been working on the basis that the idea was that the driver
> said what the constraints it has are and then some code with a more
> system wide view would make the actual decisions for things outside the
> driver domian.

That's correct, but in order to figure out a "sensible default"
the driver generally would need to know what the expectations with
respect to it are.  Otherwise it can very well generate a random
number and use that.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-21  8:25                                                 ` [linux-pm] " Mark Brown
@ 2011-08-21 18:05                                                   ` Rafael J. Wysocki
  2011-08-23  9:21                                                     ` Mark Brown
  2011-08-23  9:21                                                     ` Mark Brown
  2011-08-21 18:05                                                   ` Rafael J. Wysocki
  1 sibling, 2 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-21 18:05 UTC (permalink / raw)
  To: Mark Brown
  Cc: Alan Stern, Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sunday, August 21, 2011, Mark Brown wrote:
> On Sat, Aug 20, 2011 at 09:14:37PM +0200, Rafael J. Wysocki wrote:
> 
> > I guess you mean the driver here and I'm not really sure it can.
> > For instance, the driver may not know what configuration it works in,
> > e.g. is there a power domain or a hierarchy of those and how much time
> > it takes to power them all down and up and what the power break even is.
> 
> I don't understand why the driver would need to know what situation it's
> in.  I'd been working on the basis that the idea was that the driver
> said what the constraints it has are and then some code with a more
> system wide view would make the actual decisions for things outside the
> driver domian.

That's correct, but in order to figure out a "sensible default"
the driver generally would need to know what the expectations with
respect to it are.  Otherwise it can very well generate a random
number and use that.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-21 18:05                                                   ` Rafael J. Wysocki
  2011-08-23  9:21                                                     ` Mark Brown
@ 2011-08-23  9:21                                                     ` Mark Brown
  1 sibling, 0 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-23  9:21 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sun, Aug 21, 2011 at 08:05:53PM +0200, Rafael J. Wysocki wrote:
> On Sunday, August 21, 2011, Mark Brown wrote:

> > I don't understand why the driver would need to know what situation it's
> > in.  I'd been working on the basis that the idea was that the driver
> > said what the constraints it has are and then some code with a more
> > system wide view would make the actual decisions for things outside the
> > driver domian.

> That's correct, but in order to figure out a "sensible default"
> the driver generally would need to know what the expectations with
> respect to it are.  Otherwise it can very well generate a random
> number and use that.

Right, but I'd expect that should be something that the driver can
generally do based on knowledge of what it needs to deliver to its
users.  It doesn't need to be tunable to that - for example, input
devices will have a reasonable idea of the response time needed to
deliver interactive performance.  If it's really got no idea then
hopefully not providng any constraints will do something sensible.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-21 18:05                                                   ` Rafael J. Wysocki
@ 2011-08-23  9:21                                                     ` Mark Brown
  2011-08-23 21:31                                                       ` Rafael J. Wysocki
  2011-08-23 21:31                                                       ` Rafael J. Wysocki
  2011-08-23  9:21                                                     ` Mark Brown
  1 sibling, 2 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-23  9:21 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Alan Stern, Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Sun, Aug 21, 2011 at 08:05:53PM +0200, Rafael J. Wysocki wrote:
> On Sunday, August 21, 2011, Mark Brown wrote:

> > I don't understand why the driver would need to know what situation it's
> > in.  I'd been working on the basis that the idea was that the driver
> > said what the constraints it has are and then some code with a more
> > system wide view would make the actual decisions for things outside the
> > driver domian.

> That's correct, but in order to figure out a "sensible default"
> the driver generally would need to know what the expectations with
> respect to it are.  Otherwise it can very well generate a random
> number and use that.

Right, but I'd expect that should be something that the driver can
generally do based on knowledge of what it needs to deliver to its
users.  It doesn't need to be tunable to that - for example, input
devices will have a reasonable idea of the response time needed to
deliver interactive performance.  If it's really got no idea then
hopefully not providng any constraints will do something sensible.

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-23  9:21                                                     ` Mark Brown
  2011-08-23 21:31                                                       ` Rafael J. Wysocki
@ 2011-08-23 21:31                                                       ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-23 21:31 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Tuesday, August 23, 2011, Mark Brown wrote:
> On Sun, Aug 21, 2011 at 08:05:53PM +0200, Rafael J. Wysocki wrote:
> > On Sunday, August 21, 2011, Mark Brown wrote:
> 
> > > I don't understand why the driver would need to know what situation it's
> > > in.  I'd been working on the basis that the idea was that the driver
> > > said what the constraints it has are and then some code with a more
> > > system wide view would make the actual decisions for things outside the
> > > driver domian.
> 
> > That's correct, but in order to figure out a "sensible default"
> > the driver generally would need to know what the expectations with
> > respect to it are.  Otherwise it can very well generate a random
> > number and use that.
> 
> Right, but I'd expect that should be something that the driver can
> generally do based on knowledge of what it needs to deliver to its
> users.  It doesn't need to be tunable to that - for example, input
> devices will have a reasonable idea of the response time needed to
> deliver interactive performance.  If it's really got no idea then
> hopefully not providng any constraints will do something sensible.

Perhaps.  Still, that requires some policy to be put into drivers,
which I don't think is entirely correct.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-23  9:21                                                     ` Mark Brown
@ 2011-08-23 21:31                                                       ` Rafael J. Wysocki
  2011-08-25 10:38                                                         ` Mark Brown
  2011-08-25 10:38                                                         ` [linux-pm] " Mark Brown
  2011-08-23 21:31                                                       ` Rafael J. Wysocki
  1 sibling, 2 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-23 21:31 UTC (permalink / raw)
  To: Mark Brown
  Cc: Alan Stern, Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Tuesday, August 23, 2011, Mark Brown wrote:
> On Sun, Aug 21, 2011 at 08:05:53PM +0200, Rafael J. Wysocki wrote:
> > On Sunday, August 21, 2011, Mark Brown wrote:
> 
> > > I don't understand why the driver would need to know what situation it's
> > > in.  I'd been working on the basis that the idea was that the driver
> > > said what the constraints it has are and then some code with a more
> > > system wide view would make the actual decisions for things outside the
> > > driver domian.
> 
> > That's correct, but in order to figure out a "sensible default"
> > the driver generally would need to know what the expectations with
> > respect to it are.  Otherwise it can very well generate a random
> > number and use that.
> 
> Right, but I'd expect that should be something that the driver can
> generally do based on knowledge of what it needs to deliver to its
> users.  It doesn't need to be tunable to that - for example, input
> devices will have a reasonable idea of the response time needed to
> deliver interactive performance.  If it's really got no idea then
> hopefully not providng any constraints will do something sensible.

Perhaps.  Still, that requires some policy to be put into drivers,
which I don't think is entirely correct.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-23 21:31                                                       ` Rafael J. Wysocki
@ 2011-08-25 10:38                                                         ` Mark Brown
  2011-08-25 10:38                                                         ` [linux-pm] " Mark Brown
  1 sibling, 0 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-25 10:38 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Tue, Aug 23, 2011 at 11:31:54PM +0200, Rafael J. Wysocki wrote:

> Perhaps.  Still, that requires some policy to be put into drivers,
> which I don't think is entirely correct.

So, I don't really have the bandwidth to discuss this properly for at
least the next week or so - is it possible to find some time in the
power track at LPC for this?

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-23 21:31                                                       ` Rafael J. Wysocki
  2011-08-25 10:38                                                         ` Mark Brown
@ 2011-08-25 10:38                                                         ` Mark Brown
  2011-08-25 14:17                                                           ` Rafael J. Wysocki
  2011-08-25 14:17                                                           ` Rafael J. Wysocki
  1 sibling, 2 replies; 122+ messages in thread
From: Mark Brown @ 2011-08-25 10:38 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Alan Stern, Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Tue, Aug 23, 2011 at 11:31:54PM +0200, Rafael J. Wysocki wrote:

> Perhaps.  Still, that requires some policy to be put into drivers,
> which I don't think is entirely correct.

So, I don't really have the bandwidth to discuss this properly for at
least the next week or so - is it possible to find some time in the
power track at LPC for this?

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-25 10:38                                                         ` [linux-pm] " Mark Brown
  2011-08-25 14:17                                                           ` Rafael J. Wysocki
@ 2011-08-25 14:17                                                           ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-25 14:17 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Thursday, August 25, 2011, Mark Brown wrote:
> On Tue, Aug 23, 2011 at 11:31:54PM +0200, Rafael J. Wysocki wrote:
> 
> > Perhaps.  Still, that requires some policy to be put into drivers,
> > which I don't think is entirely correct.
> 
> So, I don't really have the bandwidth to discuss this properly for at
> least the next week or so - is it possible to find some time in the
> power track at LPC for this?

I think so, I'm going to add PM QoS to the agenda anyway.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-25 10:38                                                         ` [linux-pm] " Mark Brown
@ 2011-08-25 14:17                                                           ` Rafael J. Wysocki
  2011-08-25 14:41                                                             ` Jean Pihet
                                                                               ` (3 more replies)
  2011-08-25 14:17                                                           ` Rafael J. Wysocki
  1 sibling, 4 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-25 14:17 UTC (permalink / raw)
  To: Mark Brown
  Cc: Alan Stern, Linux PM mailing list, linux-omap, Jean Pihet, markgross

On Thursday, August 25, 2011, Mark Brown wrote:
> On Tue, Aug 23, 2011 at 11:31:54PM +0200, Rafael J. Wysocki wrote:
> 
> > Perhaps.  Still, that requires some policy to be put into drivers,
> > which I don't think is entirely correct.
> 
> So, I don't really have the bandwidth to discuss this properly for at
> least the next week or so - is it possible to find some time in the
> power track at LPC for this?

I think so, I'm going to add PM QoS to the agenda anyway.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-25 14:17                                                           ` Rafael J. Wysocki
@ 2011-08-25 14:41                                                             ` Jean Pihet
  2011-08-25 14:41                                                             ` [linux-pm] " Jean Pihet
                                                                               ` (2 subsequent siblings)
  3 siblings, 0 replies; 122+ messages in thread
From: Jean Pihet @ 2011-08-25 14:41 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: markgross, Mark Brown, Linux PM mailing list, linux-omap, Jean Pihet

On Thu, Aug 25, 2011 at 4:17 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Thursday, August 25, 2011, Mark Brown wrote:
>> On Tue, Aug 23, 2011 at 11:31:54PM +0200, Rafael J. Wysocki wrote:
>>
>> > Perhaps.  Still, that requires some policy to be put into drivers,
>> > which I don't think is entirely correct.
>>
>> So, I don't really have the bandwidth to discuss this properly for at
>> least the next week or so - is it possible to find some time in the
>> power track at LPC for this?
>
> I think so, I'm going to add PM QoS to the agenda anyway.
Unfortunately I cannot attend the conference this time.
Can you please keep me in the loop of the discussions? I am glad to
help implementing the code for the user space API.

>
> Thanks,
> Rafael

Thanks,
Jean

> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-25 14:17                                                           ` Rafael J. Wysocki
  2011-08-25 14:41                                                             ` Jean Pihet
@ 2011-08-25 14:41                                                             ` Jean Pihet
  2011-08-25 14:49                                                               ` Rafael J. Wysocki
  2011-08-25 14:49                                                               ` [linux-pm] " Rafael J. Wysocki
  2011-08-26 16:40                                                             ` mark gross
  2011-08-26 16:40                                                             ` [linux-pm] " mark gross
  3 siblings, 2 replies; 122+ messages in thread
From: Jean Pihet @ 2011-08-25 14:41 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mark Brown, Alan Stern, Linux PM mailing list, linux-omap,
	Jean Pihet, markgross

On Thu, Aug 25, 2011 at 4:17 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Thursday, August 25, 2011, Mark Brown wrote:
>> On Tue, Aug 23, 2011 at 11:31:54PM +0200, Rafael J. Wysocki wrote:
>>
>> > Perhaps.  Still, that requires some policy to be put into drivers,
>> > which I don't think is entirely correct.
>>
>> So, I don't really have the bandwidth to discuss this properly for at
>> least the next week or so - is it possible to find some time in the
>> power track at LPC for this?
>
> I think so, I'm going to add PM QoS to the agenda anyway.
Unfortunately I cannot attend the conference this time.
Can you please keep me in the loop of the discussions? I am glad to
help implementing the code for the user space API.

>
> Thanks,
> Rafael

Thanks,
Jean

> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-25 14:41                                                             ` [linux-pm] " Jean Pihet
@ 2011-08-25 14:49                                                               ` Rafael J. Wysocki
  2011-08-25 14:49                                                               ` [linux-pm] " Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-25 14:49 UTC (permalink / raw)
  To: Jean Pihet
  Cc: markgross, Mark Brown, Linux PM mailing list, linux-omap, Jean Pihet

On Thursday, August 25, 2011, Jean Pihet wrote:
> On Thu, Aug 25, 2011 at 4:17 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Thursday, August 25, 2011, Mark Brown wrote:
> >> On Tue, Aug 23, 2011 at 11:31:54PM +0200, Rafael J. Wysocki wrote:
> >>
> >> > Perhaps.  Still, that requires some policy to be put into drivers,
> >> > which I don't think is entirely correct.
> >>
> >> So, I don't really have the bandwidth to discuss this properly for at
> >> least the next week or so - is it possible to find some time in the
> >> power track at LPC for this?
> >
> > I think so, I'm going to add PM QoS to the agenda anyway.
> Unfortunately I cannot attend the conference this time.

Sorry to hear that.

> Can you please keep me in the loop of the discussions?

Sure, we will.

> I am glad to help implementing the code for the user space API.

Great, thanks!

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-25 14:41                                                             ` [linux-pm] " Jean Pihet
  2011-08-25 14:49                                                               ` Rafael J. Wysocki
@ 2011-08-25 14:49                                                               ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-25 14:49 UTC (permalink / raw)
  To: Jean Pihet
  Cc: Mark Brown, Alan Stern, Linux PM mailing list, linux-omap,
	Jean Pihet, markgross

On Thursday, August 25, 2011, Jean Pihet wrote:
> On Thu, Aug 25, 2011 at 4:17 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Thursday, August 25, 2011, Mark Brown wrote:
> >> On Tue, Aug 23, 2011 at 11:31:54PM +0200, Rafael J. Wysocki wrote:
> >>
> >> > Perhaps.  Still, that requires some policy to be put into drivers,
> >> > which I don't think is entirely correct.
> >>
> >> So, I don't really have the bandwidth to discuss this properly for at
> >> least the next week or so - is it possible to find some time in the
> >> power track at LPC for this?
> >
> > I think so, I'm going to add PM QoS to the agenda anyway.
> Unfortunately I cannot attend the conference this time.

Sorry to hear that.

> Can you please keep me in the loop of the discussions?

Sure, we will.

> I am glad to help implementing the code for the user space API.

Great, thanks!

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-06-30 15:11 ` jean.pihet
  2011-07-02 21:10   ` Rafael J. Wysocki
  2011-07-02 21:10   ` Rafael J. Wysocki
@ 2011-08-26  2:25   ` MyungJoo Ham
  2011-08-26  2:25   ` [linux-pm] " MyungJoo Ham
  3 siblings, 0 replies; 122+ messages in thread
From: MyungJoo Ham @ 2011-08-26  2:25 UTC (permalink / raw)
  To: jean.pihet; +Cc: markgross, Linux PM mailing list, linux-omap, Jean Pihet

On Fri, Jul 1, 2011 at 12:11 AM,  <jean.pihet@newoldbits.com> wrote:
> @@ -129,19 +146,19 @@ static const struct file_operations pm_qos_power_fops = {
>  /* unlocked internal variant */
>  static inline int pm_qos_get_value(struct pm_qos_object *o)
>  {
> -       if (plist_head_empty(&o->requests))
> +       if (plist_head_empty(o->requests))
>                return o->default_value;
>
>        switch (o->type) {
> -       case PM_QOS_MIN:
> -               return plist_first(&o->requests)->prio;
> +               case PM_QOS_MIN:
> +                       return plist_first(o->requests)->prio;
>
> -       case PM_QOS_MAX:
> -               return plist_last(&o->requests)->prio;
> +               case PM_QOS_MAX:
> +                       return plist_last(o->requests)->prio;
>
> -       default:
> -               /* runtime check for not using enum */
> -               BUG();
> +               default:
> +                       /* runtime check for not using enum */
> +                       BUG();
>        }
>  }

Hello,


Sorry to jump in this late, but, I've got a question in choosing QoS
value from the list with pm_qos_get_value function and pm_qos_type.

For QoS objects such as network throughput, wouldn't "PM_QOS_ADD" be
more appropriate than PM_QOS_MAX?
If A is requesting 10MB/s on NIC-X and B is requesting 5MB/s on NIC-X,
I guess PM QOS should say NIC-X that it needs to provide 15MB/s, not
10MB/s. Or, are we assuming that A and B will never put streams at the
same time?


Thanks,
MyungJoo

-- 
MyungJoo Ham, Ph.D.
Mobile Software Platform Lab, DMC Business, Samsung Electronics

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-06-30 15:11 ` jean.pihet
                     ` (2 preceding siblings ...)
  2011-08-26  2:25   ` MyungJoo Ham
@ 2011-08-26  2:25   ` MyungJoo Ham
  2011-08-26 16:54     ` mark gross
  2011-08-26 16:54     ` mark gross
  3 siblings, 2 replies; 122+ messages in thread
From: MyungJoo Ham @ 2011-08-26  2:25 UTC (permalink / raw)
  To: jean.pihet
  Cc: Rafael J. Wysocki, Paul Walmsley, Kevin Hilman, Magnus Damm,
	Linux PM mailing list, linux-omap, markgross, Jean Pihet

On Fri, Jul 1, 2011 at 12:11 AM,  <jean.pihet@newoldbits.com> wrote:
> @@ -129,19 +146,19 @@ static const struct file_operations pm_qos_power_fops = {
>  /* unlocked internal variant */
>  static inline int pm_qos_get_value(struct pm_qos_object *o)
>  {
> -       if (plist_head_empty(&o->requests))
> +       if (plist_head_empty(o->requests))
>                return o->default_value;
>
>        switch (o->type) {
> -       case PM_QOS_MIN:
> -               return plist_first(&o->requests)->prio;
> +               case PM_QOS_MIN:
> +                       return plist_first(o->requests)->prio;
>
> -       case PM_QOS_MAX:
> -               return plist_last(&o->requests)->prio;
> +               case PM_QOS_MAX:
> +                       return plist_last(o->requests)->prio;
>
> -       default:
> -               /* runtime check for not using enum */
> -               BUG();
> +               default:
> +                       /* runtime check for not using enum */
> +                       BUG();
>        }
>  }

Hello,


Sorry to jump in this late, but, I've got a question in choosing QoS
value from the list with pm_qos_get_value function and pm_qos_type.

For QoS objects such as network throughput, wouldn't "PM_QOS_ADD" be
more appropriate than PM_QOS_MAX?
If A is requesting 10MB/s on NIC-X and B is requesting 5MB/s on NIC-X,
I guess PM QOS should say NIC-X that it needs to provide 15MB/s, not
10MB/s. Or, are we assuming that A and B will never put streams at the
same time?


Thanks,
MyungJoo

-- 
MyungJoo Ham, Ph.D.
Mobile Software Platform Lab, DMC Business, Samsung Electronics
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-25 14:17                                                           ` Rafael J. Wysocki
  2011-08-25 14:41                                                             ` Jean Pihet
  2011-08-25 14:41                                                             ` [linux-pm] " Jean Pihet
@ 2011-08-26 16:40                                                             ` mark gross
  2011-08-26 16:40                                                             ` [linux-pm] " mark gross
  3 siblings, 0 replies; 122+ messages in thread
From: mark gross @ 2011-08-26 16:40 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: markgross, Mark Brown, Linux PM mailing list, linux-omap, Jean Pihet

On Thu, Aug 25, 2011 at 04:17:31PM +0200, Rafael J. Wysocki wrote:
> On Thursday, August 25, 2011, Mark Brown wrote:
> > On Tue, Aug 23, 2011 at 11:31:54PM +0200, Rafael J. Wysocki wrote:
> > 
> > > Perhaps.  Still, that requires some policy to be put into drivers,
> > > which I don't think is entirely correct.
> > 
> > So, I don't really have the bandwidth to discuss this properly for at
> > least the next week or so - is it possible to find some time in the
> > power track at LPC for this?
> 
> I think so, I'm going to add PM QoS to the agenda anyway.
>
FWIW I'll be there too.

--mark

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-25 14:17                                                           ` Rafael J. Wysocki
                                                                               ` (2 preceding siblings ...)
  2011-08-26 16:40                                                             ` mark gross
@ 2011-08-26 16:40                                                             ` mark gross
  3 siblings, 0 replies; 122+ messages in thread
From: mark gross @ 2011-08-26 16:40 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mark Brown, Alan Stern, Linux PM mailing list, linux-omap,
	Jean Pihet, markgross

On Thu, Aug 25, 2011 at 04:17:31PM +0200, Rafael J. Wysocki wrote:
> On Thursday, August 25, 2011, Mark Brown wrote:
> > On Tue, Aug 23, 2011 at 11:31:54PM +0200, Rafael J. Wysocki wrote:
> > 
> > > Perhaps.  Still, that requires some policy to be put into drivers,
> > > which I don't think is entirely correct.
> > 
> > So, I don't really have the bandwidth to discuss this properly for at
> > least the next week or so - is it possible to find some time in the
> > power track at LPC for this?
> 
> I think so, I'm going to add PM QoS to the agenda anyway.
>
FWIW I'll be there too.

--mark


^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-26  2:25   ` [linux-pm] " MyungJoo Ham
  2011-08-26 16:54     ` mark gross
@ 2011-08-26 16:54     ` mark gross
  1 sibling, 0 replies; 122+ messages in thread
From: mark gross @ 2011-08-26 16:54 UTC (permalink / raw)
  To: MyungJoo Ham; +Cc: markgross, Linux PM mailing list, linux-omap, Jean Pihet

On Fri, Aug 26, 2011 at 11:25:13AM +0900, MyungJoo Ham wrote:
> On Fri, Jul 1, 2011 at 12:11 AM,  <jean.pihet@newoldbits.com> wrote:
> > @@ -129,19 +146,19 @@ static const struct file_operations pm_qos_power_fops = {
> >  /* unlocked internal variant */
> >  static inline int pm_qos_get_value(struct pm_qos_object *o)
> >  {
> > -       if (plist_head_empty(&o->requests))
> > +       if (plist_head_empty(o->requests))
> >                return o->default_value;
> >
> >        switch (o->type) {
> > -       case PM_QOS_MIN:
> > -               return plist_first(&o->requests)->prio;
> > +               case PM_QOS_MIN:
> > +                       return plist_first(o->requests)->prio;
> >
> > -       case PM_QOS_MAX:
> > -               return plist_last(&o->requests)->prio;
> > +               case PM_QOS_MAX:
> > +                       return plist_last(o->requests)->prio;
> >
> > -       default:
> > -               /* runtime check for not using enum */
> > -               BUG();
> > +               default:
> > +                       /* runtime check for not using enum */
> > +                       BUG();
> >        }
> >  }
> 
> Hello,
> 
> 
> Sorry to jump in this late, but, I've got a question in choosing QoS
> value from the list with pm_qos_get_value function and pm_qos_type.
> 
> For QoS objects such as network throughput, wouldn't "PM_QOS_ADD" be
> more appropriate than PM_QOS_MAX?
> If A is requesting 10MB/s on NIC-X and B is requesting 5MB/s on NIC-X,
> I guess PM QOS should say NIC-X that it needs to provide 15MB/s, not
> 10MB/s. Or, are we assuming that A and B will never put streams at the
> same time?

This was brought up a few years back as well.  The reason we kept the
aggregate QoS for network Throughput as a max instead of a sum was that
there where already a number of interfaces for network shaping and we
didn't have a good answer to the problem of what to do when the
throughput qos requested exceeds hardware capabilities.  

Now that I have more experience with handsets I'm not sure it makes any
practical difference to sum or max the throughput qos requests.  So if
someone would like it to aggregate throughputs by summation of requests
that could be done.  

It turns out its the latency requests that are really used.

The network qos parameters also have a problem with discriminating
between what physical interface the QoS is for.  This limitation in the
ABI is partially addressed with some of the work that Jean Pihet's
patches are doing.

--mark

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-26  2:25   ` [linux-pm] " MyungJoo Ham
@ 2011-08-26 16:54     ` mark gross
  2011-08-26 20:56       ` Rafael J. Wysocki
  2011-08-26 20:56       ` Rafael J. Wysocki
  2011-08-26 16:54     ` mark gross
  1 sibling, 2 replies; 122+ messages in thread
From: mark gross @ 2011-08-26 16:54 UTC (permalink / raw)
  To: MyungJoo Ham
  Cc: jean.pihet, Rafael J. Wysocki, Paul Walmsley, Kevin Hilman,
	Magnus Damm, Linux PM mailing list, linux-omap, markgross,
	Jean Pihet

On Fri, Aug 26, 2011 at 11:25:13AM +0900, MyungJoo Ham wrote:
> On Fri, Jul 1, 2011 at 12:11 AM,  <jean.pihet@newoldbits.com> wrote:
> > @@ -129,19 +146,19 @@ static const struct file_operations pm_qos_power_fops = {
> >  /* unlocked internal variant */
> >  static inline int pm_qos_get_value(struct pm_qos_object *o)
> >  {
> > -       if (plist_head_empty(&o->requests))
> > +       if (plist_head_empty(o->requests))
> >                return o->default_value;
> >
> >        switch (o->type) {
> > -       case PM_QOS_MIN:
> > -               return plist_first(&o->requests)->prio;
> > +               case PM_QOS_MIN:
> > +                       return plist_first(o->requests)->prio;
> >
> > -       case PM_QOS_MAX:
> > -               return plist_last(&o->requests)->prio;
> > +               case PM_QOS_MAX:
> > +                       return plist_last(o->requests)->prio;
> >
> > -       default:
> > -               /* runtime check for not using enum */
> > -               BUG();
> > +               default:
> > +                       /* runtime check for not using enum */
> > +                       BUG();
> >        }
> >  }
> 
> Hello,
> 
> 
> Sorry to jump in this late, but, I've got a question in choosing QoS
> value from the list with pm_qos_get_value function and pm_qos_type.
> 
> For QoS objects such as network throughput, wouldn't "PM_QOS_ADD" be
> more appropriate than PM_QOS_MAX?
> If A is requesting 10MB/s on NIC-X and B is requesting 5MB/s on NIC-X,
> I guess PM QOS should say NIC-X that it needs to provide 15MB/s, not
> 10MB/s. Or, are we assuming that A and B will never put streams at the
> same time?

This was brought up a few years back as well.  The reason we kept the
aggregate QoS for network Throughput as a max instead of a sum was that
there where already a number of interfaces for network shaping and we
didn't have a good answer to the problem of what to do when the
throughput qos requested exceeds hardware capabilities.  

Now that I have more experience with handsets I'm not sure it makes any
practical difference to sum or max the throughput qos requests.  So if
someone would like it to aggregate throughputs by summation of requests
that could be done.  

It turns out its the latency requests that are really used.

The network qos parameters also have a problem with discriminating
between what physical interface the QoS is for.  This limitation in the
ABI is partially addressed with some of the work that Jean Pihet's
patches are doing.

--mark

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-26 16:54     ` mark gross
  2011-08-26 20:56       ` Rafael J. Wysocki
@ 2011-08-26 20:56       ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-26 20:56 UTC (permalink / raw)
  To: markgross; +Cc: Linux PM mailing list, linux-omap, Jean Pihet

On Friday, August 26, 2011, mark gross wrote:
> On Fri, Aug 26, 2011 at 11:25:13AM +0900, MyungJoo Ham wrote:
> > On Fri, Jul 1, 2011 at 12:11 AM,  <jean.pihet@newoldbits.com> wrote:
> > > @@ -129,19 +146,19 @@ static const struct file_operations pm_qos_power_fops = {
> > >  /* unlocked internal variant */
> > >  static inline int pm_qos_get_value(struct pm_qos_object *o)
> > >  {
> > > -       if (plist_head_empty(&o->requests))
> > > +       if (plist_head_empty(o->requests))
> > >                return o->default_value;
> > >
> > >        switch (o->type) {
> > > -       case PM_QOS_MIN:
> > > -               return plist_first(&o->requests)->prio;
> > > +               case PM_QOS_MIN:
> > > +                       return plist_first(o->requests)->prio;
> > >
> > > -       case PM_QOS_MAX:
> > > -               return plist_last(&o->requests)->prio;
> > > +               case PM_QOS_MAX:
> > > +                       return plist_last(o->requests)->prio;
> > >
> > > -       default:
> > > -               /* runtime check for not using enum */
> > > -               BUG();
> > > +               default:
> > > +                       /* runtime check for not using enum */
> > > +                       BUG();
> > >        }
> > >  }
> > 
> > Hello,
> > 
> > 
> > Sorry to jump in this late, but, I've got a question in choosing QoS
> > value from the list with pm_qos_get_value function and pm_qos_type.
> > 
> > For QoS objects such as network throughput, wouldn't "PM_QOS_ADD" be
> > more appropriate than PM_QOS_MAX?
> > If A is requesting 10MB/s on NIC-X and B is requesting 5MB/s on NIC-X,
> > I guess PM QOS should say NIC-X that it needs to provide 15MB/s, not
> > 10MB/s. Or, are we assuming that A and B will never put streams at the
> > same time?
> 
> This was brought up a few years back as well.  The reason we kept the
> aggregate QoS for network Throughput as a max instead of a sum was that
> there where already a number of interfaces for network shaping and we
> didn't have a good answer to the problem of what to do when the
> throughput qos requested exceeds hardware capabilities.  
> 
> Now that I have more experience with handsets I'm not sure it makes any
> practical difference to sum or max the throughput qos requests.  So if
> someone would like it to aggregate throughputs by summation of requests
> that could be done.  
> 
> It turns out its the latency requests that are really used.

Moreover, the throughput QoS is really difficult to handle, because
quite often there's no good mapping between energy-saving measures one
can use and the resulting throughput.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

* Re: [linux-pm] [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints
  2011-08-26 16:54     ` mark gross
@ 2011-08-26 20:56       ` Rafael J. Wysocki
  2011-08-26 20:56       ` Rafael J. Wysocki
  1 sibling, 0 replies; 122+ messages in thread
From: Rafael J. Wysocki @ 2011-08-26 20:56 UTC (permalink / raw)
  To: markgross
  Cc: MyungJoo Ham, jean.pihet, Paul Walmsley, Kevin Hilman,
	Magnus Damm, Linux PM mailing list, linux-omap, Jean Pihet

On Friday, August 26, 2011, mark gross wrote:
> On Fri, Aug 26, 2011 at 11:25:13AM +0900, MyungJoo Ham wrote:
> > On Fri, Jul 1, 2011 at 12:11 AM,  <jean.pihet@newoldbits.com> wrote:
> > > @@ -129,19 +146,19 @@ static const struct file_operations pm_qos_power_fops = {
> > >  /* unlocked internal variant */
> > >  static inline int pm_qos_get_value(struct pm_qos_object *o)
> > >  {
> > > -       if (plist_head_empty(&o->requests))
> > > +       if (plist_head_empty(o->requests))
> > >                return o->default_value;
> > >
> > >        switch (o->type) {
> > > -       case PM_QOS_MIN:
> > > -               return plist_first(&o->requests)->prio;
> > > +               case PM_QOS_MIN:
> > > +                       return plist_first(o->requests)->prio;
> > >
> > > -       case PM_QOS_MAX:
> > > -               return plist_last(&o->requests)->prio;
> > > +               case PM_QOS_MAX:
> > > +                       return plist_last(o->requests)->prio;
> > >
> > > -       default:
> > > -               /* runtime check for not using enum */
> > > -               BUG();
> > > +               default:
> > > +                       /* runtime check for not using enum */
> > > +                       BUG();
> > >        }
> > >  }
> > 
> > Hello,
> > 
> > 
> > Sorry to jump in this late, but, I've got a question in choosing QoS
> > value from the list with pm_qos_get_value function and pm_qos_type.
> > 
> > For QoS objects such as network throughput, wouldn't "PM_QOS_ADD" be
> > more appropriate than PM_QOS_MAX?
> > If A is requesting 10MB/s on NIC-X and B is requesting 5MB/s on NIC-X,
> > I guess PM QOS should say NIC-X that it needs to provide 15MB/s, not
> > 10MB/s. Or, are we assuming that A and B will never put streams at the
> > same time?
> 
> This was brought up a few years back as well.  The reason we kept the
> aggregate QoS for network Throughput as a max instead of a sum was that
> there where already a number of interfaces for network shaping and we
> didn't have a good answer to the problem of what to do when the
> throughput qos requested exceeds hardware capabilities.  
> 
> Now that I have more experience with handsets I'm not sure it makes any
> practical difference to sum or max the throughput qos requests.  So if
> someone would like it to aggregate throughputs by summation of requests
> that could be done.  
> 
> It turns out its the latency requests that are really used.

Moreover, the throughput QoS is really difficult to handle, because
quite often there's no good mapping between energy-saving measures one
can use and the resulting throughput.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 122+ messages in thread

end of thread, other threads:[~2011-08-26 20:56 UTC | newest]

Thread overview: 122+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-30 15:11 [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class jean.pihet
2011-06-30 15:11 ` [PATCH 01/11] PM: add a per-device wake-up latency constraints plist jean.pihet
2011-06-30 15:11 ` jean.pihet
2011-07-02 19:39   ` Rafael J. Wysocki
2011-07-20  8:57     ` Jean Pihet
2011-07-20  8:57     ` Jean Pihet
2011-07-02 19:39   ` Rafael J. Wysocki
2011-06-30 15:11 ` [PATCH 02/11] PM: extend PM QoS with per-device wake-up constraints jean.pihet
2011-06-30 15:11 ` jean.pihet
2011-07-02 21:10   ` Rafael J. Wysocki
2011-07-20  9:13     ` Jean Pihet
2011-07-20  9:13     ` Jean Pihet
2011-08-02 17:49     ` Kevin Hilman
2011-08-02 20:19       ` Rafael J. Wysocki
2011-08-02 20:19       ` Rafael J. Wysocki
2011-08-02 21:23         ` Kevin Hilman
2011-08-02 22:16           ` Rafael J. Wysocki
2011-08-04 13:24             ` [linux-pm] " Mark Brown
2011-08-04 19:15               ` Rafael J. Wysocki
2011-08-05 15:29                 ` mark gross
2011-08-05 15:29                 ` mark gross
2011-08-05 16:11                 ` Mark Brown
2011-08-05 16:11                 ` [linux-pm] " Mark Brown
2011-08-05 19:37                   ` Rafael J. Wysocki
2011-08-05 19:37                   ` [linux-pm] " Rafael J. Wysocki
2011-08-06  3:37                     ` Mark Brown
2011-08-06 19:46                       ` Rafael J. Wysocki
2011-08-07  2:47                         ` Mark Brown
2011-08-07  2:47                         ` [linux-pm] " Mark Brown
2011-08-08 21:31                           ` Rafael J. Wysocki
2011-08-19  3:11                             ` Mark Brown
2011-08-19 20:42                               ` Rafael J. Wysocki
2011-08-19 23:14                                 ` Mark Brown
2011-08-20  2:24                                   ` Alan Stern
2011-08-20  2:24                                   ` [linux-pm] " Alan Stern
2011-08-20  6:25                                     ` Mark Brown
2011-08-20 13:48                                       ` Alan Stern
2011-08-20 13:48                                       ` [linux-pm] " Alan Stern
2011-08-20 15:30                                         ` Mark Brown
2011-08-20 16:34                                           ` Rafael J. Wysocki
2011-08-20 17:04                                             ` Mark Brown
2011-08-20 17:04                                             ` [linux-pm] " Mark Brown
2011-08-20 19:14                                               ` Rafael J. Wysocki
2011-08-21  8:25                                                 ` Mark Brown
2011-08-21  8:25                                                 ` [linux-pm] " Mark Brown
2011-08-21 18:05                                                   ` Rafael J. Wysocki
2011-08-23  9:21                                                     ` Mark Brown
2011-08-23 21:31                                                       ` Rafael J. Wysocki
2011-08-25 10:38                                                         ` Mark Brown
2011-08-25 10:38                                                         ` [linux-pm] " Mark Brown
2011-08-25 14:17                                                           ` Rafael J. Wysocki
2011-08-25 14:41                                                             ` Jean Pihet
2011-08-25 14:41                                                             ` [linux-pm] " Jean Pihet
2011-08-25 14:49                                                               ` Rafael J. Wysocki
2011-08-25 14:49                                                               ` [linux-pm] " Rafael J. Wysocki
2011-08-26 16:40                                                             ` mark gross
2011-08-26 16:40                                                             ` [linux-pm] " mark gross
2011-08-25 14:17                                                           ` Rafael J. Wysocki
2011-08-23 21:31                                                       ` Rafael J. Wysocki
2011-08-23  9:21                                                     ` Mark Brown
2011-08-21 18:05                                                   ` Rafael J. Wysocki
2011-08-20 19:14                                               ` Rafael J. Wysocki
2011-08-20 16:34                                           ` Rafael J. Wysocki
2011-08-20 15:30                                         ` Mark Brown
2011-08-20  6:25                                     ` Mark Brown
2011-08-20  9:35                                   ` Rafael J. Wysocki
2011-08-20  9:35                                   ` [linux-pm] " Rafael J. Wysocki
2011-08-20 10:31                                     ` Mark Brown
2011-08-20 10:31                                     ` [linux-pm] " Mark Brown
2011-08-20 16:51                                       ` Rafael J. Wysocki
2011-08-20 16:51                                       ` [linux-pm] " Rafael J. Wysocki
2011-08-20 17:22                                         ` Mark Brown
2011-08-20 17:22                                         ` [linux-pm] " Mark Brown
2011-08-20 19:18                                           ` Rafael J. Wysocki
2011-08-20 19:18                                           ` Rafael J. Wysocki
2011-08-19 23:14                                 ` Mark Brown
2011-08-19 20:42                               ` Rafael J. Wysocki
2011-08-19  3:11                             ` Mark Brown
2011-08-08 21:31                           ` Rafael J. Wysocki
2011-08-06  3:37                     ` Mark Brown
2011-08-04 19:15               ` Rafael J. Wysocki
2011-08-04 13:24             ` Mark Brown
2011-08-02 21:23         ` Kevin Hilman
2011-08-02 17:49     ` Kevin Hilman
2011-07-02 21:10   ` Rafael J. Wysocki
2011-08-26  2:25   ` MyungJoo Ham
2011-08-26  2:25   ` [linux-pm] " MyungJoo Ham
2011-08-26 16:54     ` mark gross
2011-08-26 20:56       ` Rafael J. Wysocki
2011-08-26 20:56       ` Rafael J. Wysocki
2011-08-26 16:54     ` mark gross
2011-06-30 15:11 ` [PATCH 03/11] PM QoS: support the dynamic devices insertion and removal jean.pihet
2011-07-02 21:14   ` Rafael J. Wysocki
2011-07-02 21:14   ` Rafael J. Wysocki
2011-07-20  9:16     ` Jean Pihet
2011-07-20  9:16     ` Jean Pihet
2011-06-30 15:11 ` jean.pihet
2011-06-30 15:11 ` [PATCH 04/11] OMAP PM: create a PM layer plugin for per-device constraints jean.pihet
2011-06-30 15:11 ` jean.pihet
2011-06-30 15:11 ` [PATCH 05/11] OMAP PM: early init of the pwrdms states jean.pihet
2011-06-30 15:11 ` jean.pihet
2011-06-30 15:11 ` [PATCH 06/11] OMAP2+: powerdomain: control power domains next state jean.pihet
2011-06-30 15:11 ` jean.pihet
2011-06-30 15:11 ` [PATCH 07/11] OMAP3: powerdomain data: add wake-up latency figures jean.pihet
2011-06-30 15:11 ` jean.pihet
2011-06-30 15:11 ` [PATCH 08/11] OMAP4: " jean.pihet
2011-06-30 15:11 ` jean.pihet
2011-06-30 15:11 ` [PATCH 09/11] OMAP2+: omap_hwmod: manage the wake-up latency constraints jean.pihet
2011-06-30 15:11 ` jean.pihet
2011-06-30 15:11 ` [PATCH 10/11] OMAP: PM CONSTRAINTS: implement the devices " jean.pihet
2011-06-30 15:11 ` jean.pihet
2011-06-30 15:11 ` [PATCH 11/11] OMAP2+: cpuidle only influences the MPU state jean.pihet
2011-06-30 15:11 ` jean.pihet
2011-07-02 19:20 ` [PATCH v2 00/11] PM QoS: add a per-device wake-up latency constraint class Rafael J. Wysocki
2011-07-02 19:20 ` Rafael J. Wysocki
2011-07-04  7:16   ` Vishwanath Sripathy
2011-07-04  8:38     ` Rafael J. Wysocki
2011-07-04  8:38     ` Rafael J. Wysocki
2011-07-20  9:26   ` Jean Pihet
2011-07-20 13:22     ` mark gross
2011-07-20 13:22     ` mark gross
2011-07-20  9:26   ` Jean Pihet

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.