From patchwork Wed Apr 26 10:57:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 98245 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp261766qgf; Wed, 26 Apr 2017 03:59:12 -0700 (PDT) X-Received: by 10.98.25.69 with SMTP id 66mr32554794pfz.84.1493204352540; Wed, 26 Apr 2017 03:59:12 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y20si25067519pfj.343.2017.04.26.03.59.11; Wed, 26 Apr 2017 03:59:12 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2999036AbdDZK7D (ORCPT + 17 others); Wed, 26 Apr 2017 06:59:03 -0400 Received: from mail-pf0-f171.google.com ([209.85.192.171]:35559 "EHLO mail-pf0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2998899AbdDZK5n (ORCPT ); Wed, 26 Apr 2017 06:57:43 -0400 Received: by mail-pf0-f171.google.com with SMTP id v14so36980917pfd.2 for ; Wed, 26 Apr 2017 03:57:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=kABIkkmjgz1YlV9mQA0lAEe0FdxztogsuJdLqdUAgts=; b=J4gVm0Hj15QBKMUXYrFanjNgcjZ8oiz7RyWl/X+7IQM3nGgjEdgkJ55kMMBBXfR+lk fcphacP5rH4SW3tQz1mF9TJysbVsqWA5T2+l+SkFfaqWfFqEi2cJIYGYjuUfmTv9V9UF BiOCm6E5AfwYDQ+aSfZYiBtzoEz81JzIWZAbU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=kABIkkmjgz1YlV9mQA0lAEe0FdxztogsuJdLqdUAgts=; b=sYzbYymNy8VdNhoyXGrpO2tQ2W4jcCbqEDPE3ovypG02NeazkbQBGu+X57u0IKE9Wg LZA78fHrP8Lu5EMQpxvn651VSILiDO9ofGi7o7Qm5TDQxCxSiUXDzOVQIq636eRMd/K7 Pteav2LkS8x2ZwjucdW9YxkZlMGEtyiiNstmtC0nPhZesq149B+DZPIzJDdeChu+vSGt u33V1W3Iggp71FuZOskPidMH9dmScO7UQl+4hgFmZ20MN5KbRXf5wfcQrexQZd3qoRZe mC8xTno5/MI86MYl5n8XXZyRE7IM4JKjmQwZXwCaYZBvB/ZjGzGSBjtwVnsJO9wme4Fs vPvA== X-Gm-Message-State: AN3rC/4MpBRMImqIEeA+Ya+exs4o4P0iaSRHn9JzL3xnG7Oe6icOl999 Ug3Pq2zStv8DAB6Y X-Received: by 10.98.97.195 with SMTP id v186mr32078112pfb.81.1493204257443; Wed, 26 Apr 2017 03:57:37 -0700 (PDT) Received: from localhost ([122.172.121.5]) by smtp.gmail.com with ESMTPSA id y29sm41814113pfj.90.2017.04.26.03.57.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 26 Apr 2017 03:57:36 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Len Brown , Pavel Machek Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Vincent Guittot , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, sudeep.holla@arm.com, Viresh Kumar Subject: [PATCH V6 4/9] PM / QOS: Add DEV_PM_QOS_PERFORMANCE request Date: Wed, 26 Apr 2017 16:27:08 +0530 Message-Id: <166953ca65e499dfb42927c6c13734b513a2d29b.1493203884.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.12.0.432.g71c3a4f4ba37 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some platforms have the capability to configure the performance state of their Power Domains. The performance levels are identified by positive integer values, a lower value represents lower performance state. The power domain driver should be able to retrieve all information required to configure the performance state of the power domain, with the help of the performance constraint's target value. This patch adds a new QOS request type: DEV_PM_QOS_PERFORMANCE to support runtime performance constraints for the devices. Also allow notifiers to be registered against it, which will be used by frameworks like genpd. Signed-off-by: Viresh Kumar Acked-by: Ulf Hansson --- Documentation/power/pm_qos_interface.txt | 2 +- drivers/base/power/qos.c | 21 +++++++++++++++++++++ include/linux/pm_qos.h | 9 +++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) -- 2.12.0.432.g71c3a4f4ba37 diff --git a/Documentation/power/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt index 21d2d48f87a2..42870d28fc3c 100644 --- a/Documentation/power/pm_qos_interface.txt +++ b/Documentation/power/pm_qos_interface.txt @@ -168,7 +168,7 @@ The per-device PM QoS framework has a per-device notification tree. int dev_pm_qos_add_notifier(device, notifier): Adds a notification callback function for the device. The callback is called when the aggregated value of the device constraints list -is changed (for resume latency device PM QoS only). +is changed (for resume latency and performance device PM QoS). int dev_pm_qos_remove_notifier(device, notifier): Removes the notification callback function for the device. diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 654d8a12c2e7..084d26960dae 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -150,6 +150,10 @@ static int apply_constraint(struct dev_pm_qos_request *req, req->dev->power.set_latency_tolerance(req->dev, value); } break; + case DEV_PM_QOS_PERFORMANCE: + ret = pm_qos_update_target(&qos->performance, &req->data.pnode, + action, value); + break; case DEV_PM_QOS_FLAGS: ret = pm_qos_update_flags(&qos->flags, &req->data.flr, action, value); @@ -194,6 +198,14 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) c->no_constraint_value = PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT; c->type = PM_QOS_MIN; + c = &qos->performance; + plist_head_init(&c->list); + c->target_value = PM_QOS_PERFORMANCE_DEFAULT_VALUE; + c->default_value = PM_QOS_PERFORMANCE_DEFAULT_VALUE; + c->no_constraint_value = PM_QOS_PERFORMANCE_DEFAULT_VALUE; + c->type = PM_QOS_MAX; + c->notifiers = &qos->notifiers; + INIT_LIST_HEAD(&qos->flags.list); spin_lock_irq(&dev->power.lock); @@ -252,6 +264,11 @@ void dev_pm_qos_constraints_destroy(struct device *dev) apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); memset(req, 0, sizeof(*req)); } + c = &qos->performance; + plist_for_each_entry_safe(req, tmp, &c->list, data.pnode) { + apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); + memset(req, 0, sizeof(*req)); + } f = &qos->flags; list_for_each_entry_safe(req, tmp, &f->list, data.flr.node) { apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); @@ -362,6 +379,7 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req, switch(req->type) { case DEV_PM_QOS_RESUME_LATENCY: case DEV_PM_QOS_LATENCY_TOLERANCE: + case DEV_PM_QOS_PERFORMANCE: curr_value = req->data.pnode.prio; break; case DEV_PM_QOS_FLAGS: @@ -571,6 +589,9 @@ static void __dev_pm_qos_drop_user_request(struct device *dev, req = dev->power.qos->flags_req; dev->power.qos->flags_req = NULL; break; + case DEV_PM_QOS_PERFORMANCE: + dev_err(dev, "Invalid user request (performance)\n"); + return; } __dev_pm_qos_remove_request(req); kfree(req); diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index e546d1a2f237..665f90face40 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -36,6 +36,7 @@ enum pm_qos_flags_status { #define PM_QOS_RESUME_LATENCY_DEFAULT_VALUE 0 #define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 0 #define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1) +#define PM_QOS_PERFORMANCE_DEFAULT_VALUE 0 #define PM_QOS_LATENCY_ANY ((s32)(~(__u32)0 >> 1)) #define PM_QOS_FLAG_NO_POWER_OFF (1 << 0) @@ -55,6 +56,7 @@ struct pm_qos_flags_request { enum dev_pm_qos_req_type { DEV_PM_QOS_RESUME_LATENCY = 1, DEV_PM_QOS_LATENCY_TOLERANCE, + DEV_PM_QOS_PERFORMANCE, DEV_PM_QOS_FLAGS, }; @@ -96,6 +98,7 @@ struct pm_qos_flags { struct dev_pm_qos { struct pm_qos_constraints resume_latency; struct pm_qos_constraints latency_tolerance; + struct pm_qos_constraints performance; struct pm_qos_flags flags; struct dev_pm_qos_request *resume_latency_req; struct dev_pm_qos_request *latency_tolerance_req; @@ -121,6 +124,12 @@ static inline bool dev_pm_qos_is_resume_latency(struct device *dev, return &dev->power.qos->resume_latency == c; } +static inline bool dev_pm_qos_is_performance(struct device *dev, + struct pm_qos_constraints *c) +{ + return &dev->power.qos->performance == c; +} + int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node, enum pm_qos_req_action action, int value); bool pm_qos_update_flags(struct pm_qos_flags *pqf, From patchwork Wed Apr 26 10:57:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 98246 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp261792qgf; Wed, 26 Apr 2017 03:59:16 -0700 (PDT) X-Received: by 10.98.131.75 with SMTP id h72mr32194912pfe.190.1493204356011; Wed, 26 Apr 2017 03:59:16 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y20si25067519pfj.343.2017.04.26.03.59.15; Wed, 26 Apr 2017 03:59:16 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2999054AbdDZK7O (ORCPT + 17 others); Wed, 26 Apr 2017 06:59:14 -0400 Received: from mail-pf0-f173.google.com ([209.85.192.173]:33586 "EHLO mail-pf0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2998902AbdDZK5s (ORCPT ); Wed, 26 Apr 2017 06:57:48 -0400 Received: by mail-pf0-f173.google.com with SMTP id a188so40693989pfa.0 for ; Wed, 26 Apr 2017 03:57:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=sosoBv3Aw/pOkif+KVGq8NtmxVPmr+k3pCiDotsR/Vk=; b=YPXg2QjQdY5k1VzhQ+hMxaTGLHqWn77v6HQdzVY8eQ0THnXH0KcN6vjreCL0ZF4umL zy33FqoZWfoJG1a244qTyqEe0XwAwLlBgtP17QRXodrhhvhs8oTWWh/u6wTGtytCeeSD q9ThH+vKCd25cq+Pyca1r2r5IxkDi33t0NFJQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=sosoBv3Aw/pOkif+KVGq8NtmxVPmr+k3pCiDotsR/Vk=; b=rO/Z9lFurXWSa8LgRj+Eyzbs5gjGuOlXEND2mW7Qrnt1g84TPTmjg62wNzTpQ2FXcy bzWLO06LMN+zJgmVModoZ8u4jLq/9bpY8+IJE7JFqXAQ7o8zDnFNZKGwQxE3BFD8eDBG 68zO1gGC+BA1FWN+/DCEwYsHGakOE0xFU40P3OkjkxBf2ukL+3cfO5PEkjlMEdlC+jwx lzuCp7gz6/6ubdTLZAF14i3sMPwK6A+s9V6vvWTub61S/9SceuSEOihRiM9gIy19tGOm Snu/BPVwHg6vv6vqqmIu7WBxZGUEZ7Qw8QlSw4eFeLEdhv4FoIN2a8KxHCAOVSWrB7Od 4nQg== X-Gm-Message-State: AN3rC/5RIrvg0aS3M0rJRtihu9UR3be3ITcK5xaO6q2/uWIkFYDykvnN Q63V0kb2bZy0rqVy4ERAPA== X-Received: by 10.84.171.129 with SMTP id l1mr43256029plb.5.1493204267557; Wed, 26 Apr 2017 03:57:47 -0700 (PDT) Received: from localhost ([122.172.121.5]) by smtp.gmail.com with ESMTPSA id y29sm41815248pfj.90.2017.04.26.03.57.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 26 Apr 2017 03:57:46 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Len Brown , Pavel Machek Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Vincent Guittot , Stephen Boyd , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, sudeep.holla@arm.com, Viresh Kumar Subject: [PATCH V6 7/9] PM / domain: Register PM QOS performance notifier Date: Wed, 26 Apr 2017 16:27:11 +0530 Message-Id: <88fdc938b61ae97d2bc705bc01e3f8ad0db79e56.1493203884.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.12.0.432.g71c3a4f4ba37 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some platforms have the capability to configure the performance state of their Power Domains. The performance levels are identified by positive integer values, a lower value represents lower performance state. The power domain driver should be able to retrieve all information required to configure the performance state of the power domain, with the help of the performance constraint's target value. This patch implements performance state management in PM domain core. The performance QOS uses the common QOS notifier list and we call __performance_notifier() if the notifier is issued for performance constraint. This also allows the power domain drivers to implement a ->set_performance_state() callback, which will be called by the power domain core from within the notifier routine. If a domain doesn't implement ->set_performance_state() callback, then it is assumed that its parents are responsible for performance state configuration. Both devices and sub-domains are accounted for while finding the highest performance state requested. Signed-off-by: Viresh Kumar --- drivers/base/power/domain.c | 77 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/pm_domain.h | 4 +++ 2 files changed, 81 insertions(+) -- 2.12.0.432.g71c3a4f4ba37 diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index f6f616ac5cc2..7d35dafe8c97 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -462,6 +462,79 @@ static int genpd_latency_notifier(struct generic_pm_domain_data *gpd_data, return NOTIFY_DONE; } +static void __update_domain_performance_state(struct generic_pm_domain *genpd, + int depth) +{ + struct generic_pm_domain_data *pd_data; + struct generic_pm_domain *subdomain; + struct pm_domain_data *pdd; + unsigned int state = 0; + struct gpd_link *link; + + /* Traverse all devices within the domain */ + list_for_each_entry(pdd, &genpd->dev_list, list_node) { + pd_data = to_gpd_data(pdd); + + if (pd_data->performance_state > state) + state = pd_data->performance_state; + } + + /* Traverse all subdomains within the domain */ + list_for_each_entry(link, &genpd->master_links, master_node) { + subdomain = link->slave; + + if (subdomain->performance_state > state) + state = subdomain->performance_state; + } + + if (genpd->performance_state == state) + return; + + genpd->performance_state = state; + + if (genpd->set_performance_state) { + genpd->set_performance_state(genpd, state); + return; + } + + /* Propagate to parent power domains */ + list_for_each_entry(link, &genpd->slave_links, slave_node) { + struct generic_pm_domain *master = link->master; + + genpd_lock_nested(master, depth + 1); + __update_domain_performance_state(master, depth + 1); + genpd_unlock(master); + } +} + +static int __performance_notifier(struct generic_pm_domain_data *gpd_data, + unsigned long val) +{ + struct generic_pm_domain *genpd = ERR_PTR(-ENODATA); + struct device *dev = gpd_data->base.dev; + struct pm_domain_data *pdd; + + spin_lock_irq(&dev->power.lock); + + pdd = dev->power.subsys_data ? + dev->power.subsys_data->domain_data : NULL; + + if (pdd && pdd->dev) + genpd = dev_to_genpd(dev); + + spin_unlock_irq(&dev->power.lock); + + if (IS_ERR(genpd)) + return NOTIFY_DONE; + + genpd_lock(genpd); + gpd_data->performance_state = val; + __update_domain_performance_state(genpd, 0); + genpd_unlock(genpd); + + return NOTIFY_DONE; +} + static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, unsigned long val, void *ptr) { @@ -474,6 +547,9 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, if (dev_pm_qos_is_resume_latency(dev, ptr)) return genpd_latency_notifier(gpd_data, val); + if (dev_pm_qos_is_performance(dev, ptr)) + return __performance_notifier(gpd_data, val); + dev_err(dev, "%s: Unexpected notifier call\n", __func__); return NOTIFY_BAD; } @@ -1168,6 +1244,7 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev, gpd_data->td.constraint_changed = true; gpd_data->td.effective_constraint_ns = -1; gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier; + gpd_data->performance_state = 0; spin_lock_irq(&dev->power.lock); diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index b7803a251044..84ee474e66d0 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -63,8 +63,11 @@ struct generic_pm_domain { unsigned int device_count; /* Number of devices */ unsigned int suspended_count; /* System suspend device counter */ unsigned int prepared_count; /* Suspend counter of prepared devices */ + unsigned int performance_state; /* Max requested performance state */ int (*power_off)(struct generic_pm_domain *domain); int (*power_on)(struct generic_pm_domain *domain); + int (*set_performance_state)(struct generic_pm_domain *domain, + unsigned int state); struct gpd_dev_ops dev_ops; s64 max_off_time_ns; /* Maximum allowed "suspended" time. */ bool max_off_time_changed; @@ -118,6 +121,7 @@ struct generic_pm_domain_data { struct pm_domain_data base; struct gpd_timing_data td; struct notifier_block nb; + unsigned int performance_state; void *data; };