From patchwork Tue Aug 19 08:38:41 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomeu Vizoso X-Patchwork-Id: 381283 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 08F7A14009B for ; Tue, 19 Aug 2014 18:41:23 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752202AbaHSIj2 (ORCPT ); Tue, 19 Aug 2014 04:39:28 -0400 Received: from mail-la0-f49.google.com ([209.85.215.49]:51131 "EHLO mail-la0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752153AbaHSIj0 (ORCPT ); Tue, 19 Aug 2014 04:39:26 -0400 Received: by mail-la0-f49.google.com with SMTP id hz20so5546137lab.22 for ; Tue, 19 Aug 2014 01:39:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=ordft0WeUY5qOXgbXQQUnRqgwn2SZx29TDmBvSkaKyg=; b=Q5YTGGS7228h02wL58znAbq8aQcDTn56ivOYsRrHJYgX+sVrN896hIhY511cM3sJxj PYynNXEM93QASrZiVlybjmFrRi5a7m0LvDgjHY3ft0vAF8BbOM/Wv8D+1t31etUCqY9+ ikzB5b3cYBynNkzA7v+8NmHG3jYhbQtbIkoTquvQk4UiWUawr4B9pjvMdKPjGEGc61KE DY33BmlvSrAO70Kof4hDfD+LtZxVUhxqMiLWdYr46WoRC5BtBJqpk6mJRuqPeA9t0VbU 0In7Bu3r5jeDFE5OCzS9lfO9jc1HUJxQO+emVeErcr3LK8X+Vn6rL8efPiZdgV+WbyGM ex/A== X-Received: by 10.152.2.72 with SMTP id 8mr14700346las.40.1408437564353; Tue, 19 Aug 2014 01:39:24 -0700 (PDT) Received: from cizrna.lan (37-48-36-184.tmcz.cz. [37.48.36.184]) by mx.google.com with ESMTPSA id n2sm12090051lag.18.2014.08.19.01.39.20 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Aug 2014 01:39:23 -0700 (PDT) From: Tomeu Vizoso To: linux-pm@vger.kernel.org Cc: Thierry Reding , =?UTF-8?q?Terje=20Bergstr=C3=B6m?= , Stephen Warren , "Rafael J. Wysocki" , Pavel Machek , Len Brown , linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, Javier Martinez Canillas , Mikko Perttunen , Tomeu Vizoso Subject: [PATCH v3 1/3] PM / QoS: Add PM_QOS_MEMORY_BANDWIDTH class Date: Tue, 19 Aug 2014 10:38:41 +0200 Message-Id: <1408437523-8542-2-git-send-email-tomeu.vizoso@collabora.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1408437523-8542-1-git-send-email-tomeu.vizoso@collabora.com> References: <1408437523-8542-1-git-send-email-tomeu.vizoso@collabora.com> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org Also adds a class type PM_QOS_SUM that aggregates the values by summing them. It can be used by memory controllers to calculate the optimum clock frequency based on the bandwidth needs of the different memory clients. Signed-off-by: Tomeu Vizoso Acked-by: Pavel Machek --- v3: * Changed units to be megabits per second --- Documentation/power/pm_qos_interface.txt | 4 +++- include/linux/pm_qos.h | 5 ++++- kernel/power/qos.c | 27 ++++++++++++++++++++++++++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Documentation/power/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt index a5da5c7..129f7c0 100644 --- a/Documentation/power/pm_qos_interface.txt +++ b/Documentation/power/pm_qos_interface.txt @@ -5,7 +5,8 @@ performance expectations by drivers, subsystems and user space applications on one of the parameters. Two different PM QoS frameworks are available: -1. PM QoS classes for cpu_dma_latency, network_latency, network_throughput. +1. PM QoS classes for cpu_dma_latency, network_latency, network_throughput, +memory_bandwidth. 2. the per-device PM QoS framework provides the API to manage the per-device latency constraints and PM QoS flags. @@ -13,6 +14,7 @@ Each parameters have defined units: * latency: usec * timeout: usec * throughput: kbs (kilo bit / sec) + * memory bandwidth: mbs (mega bit / sec) 1. PM QoS framework diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 9ab4bf7..636e828 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -15,6 +15,7 @@ enum { PM_QOS_CPU_DMA_LATENCY, PM_QOS_NETWORK_LATENCY, PM_QOS_NETWORK_THROUGHPUT, + PM_QOS_MEMORY_BANDWIDTH, /* insert new class ID */ PM_QOS_NUM_CLASSES, @@ -32,6 +33,7 @@ enum pm_qos_flags_status { #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_MEMORY_BANDWIDTH_DEFAULT_VALUE 0 #define PM_QOS_RESUME_LATENCY_DEFAULT_VALUE 0 #define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 0 #define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1) @@ -69,7 +71,8 @@ struct dev_pm_qos_request { enum pm_qos_type { PM_QOS_UNITIALIZED, PM_QOS_MAX, /* return the largest value */ - PM_QOS_MIN /* return the smallest value */ + PM_QOS_MIN, /* return the smallest value */ + PM_QOS_SUM /* return the sum */ }; /* diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 884b770..5f4c006 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -105,11 +105,27 @@ static struct pm_qos_object network_throughput_pm_qos = { }; +static BLOCKING_NOTIFIER_HEAD(memory_bandwidth_notifier); +static struct pm_qos_constraints memory_bw_constraints = { + .list = PLIST_HEAD_INIT(memory_bw_constraints.list), + .target_value = PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE, + .default_value = PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE, + .no_constraint_value = PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE, + .type = PM_QOS_SUM, + .notifiers = &memory_bandwidth_notifier, +}; +static struct pm_qos_object memory_bandwidth_pm_qos = { + .constraints = &memory_bw_constraints, + .name = "memory_bandwidth", +}; + + static struct pm_qos_object *pm_qos_array[] = { &null_pm_qos, &cpu_dma_pm_qos, &network_lat_pm_qos, - &network_throughput_pm_qos + &network_throughput_pm_qos, + &memory_bandwidth_pm_qos, }; static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf, @@ -130,6 +146,9 @@ static const struct file_operations pm_qos_power_fops = { /* unlocked internal variant */ static inline int pm_qos_get_value(struct pm_qos_constraints *c) { + struct plist_node *node; + int total_value = 0; + if (plist_head_empty(&c->list)) return c->no_constraint_value; @@ -140,6 +159,12 @@ static inline int pm_qos_get_value(struct pm_qos_constraints *c) case PM_QOS_MAX: return plist_last(&c->list)->prio; + case PM_QOS_SUM: + plist_for_each(node, &c->list) + total_value += node->prio; + + return total_value; + default: /* runtime check for not using enum */ BUG();