From patchwork Fri Feb 24 09:06:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 94421 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp601391qgi; Fri, 24 Feb 2017 01:14:14 -0800 (PST) X-Received: by 10.99.172.2 with SMTP id v2mr2200641pge.100.1487927654352; Fri, 24 Feb 2017 01:14:14 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r19si6851451pfe.12.2017.02.24.01.14.13; Fri, 24 Feb 2017 01:14:14 -0800 (PST) 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 S1751486AbdBXJOM (ORCPT + 25 others); Fri, 24 Feb 2017 04:14:12 -0500 Received: from mail-pg0-f48.google.com ([74.125.83.48]:36044 "EHLO mail-pg0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750964AbdBXJOA (ORCPT ); Fri, 24 Feb 2017 04:14:00 -0500 Received: by mail-pg0-f48.google.com with SMTP id s67so9311439pgb.3 for ; Fri, 24 Feb 2017 01:13:59 -0800 (PST) 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=Wb+4LPqYIclTuLyYI4AM0nB+s84Fuy3x4FkaxOpSvB4=; b=PIldqzhHNtNFXqA2bLcNVMn4SuF/VnooJ5AG8y9Sef3uCd5ZjXHQJdOq3cxWPpTnT5 hn+grHEXNVg+9Vy/13rrbD0wfvLXHWUBn9UzKBXwFreTj/SJLsxJoubCEACddXt/Mecf qwo9cF/EsV4Ukvr9PeWnZ7TY+p9HW3lKeXj+w= 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=Wb+4LPqYIclTuLyYI4AM0nB+s84Fuy3x4FkaxOpSvB4=; b=j85RDfsDpyGPXlm+SiqCYCXmbXZWymQ5blk4dDVuuTlGI8uYPFOmKmCfIR/qcyxGwk p4Q2c7b8ZzW9H527+ROfVPIHxK+S1EVYa4EAjZwOXldwDQ/UnNgXOgAuuv4Y5nvejpDT VLXYG+0qXAa+Wn1r97+JAlW38y3Jc7jHSl5EItkbOKW1qc7/05IEenBAX8oslprbd3wv whQGWmpkx8y7NE3wdR0ptUEI46CTv4A6zB9ik/1x4LxNMW+jI47X376R/dodd76ms8y1 9nGnU2OOaOR6OUha1fZWAJnlYePOIEF3rTkrugVdEnU2BGwefwrJrL/Vht8OQ4lgffyt E3fw== X-Gm-Message-State: AMke39mcMQHvo+gjIyO4npyuZOiyXfiB7Ur8XgJ5hifZmidLH4cJZAPOxs+hZ3Yqf23gg1ob X-Received: by 10.99.115.71 with SMTP id d7mr2177851pgn.56.1487927215105; Fri, 24 Feb 2017 01:06:55 -0800 (PST) Received: from localhost ([122.172.165.189]) by smtp.gmail.com with ESMTPSA id 64sm13882531pfq.112.2017.02.24.01.06.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Feb 2017 01:06:54 -0800 (PST) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Kevin Hilman , Pavel Machek , Len Brown Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Stephen Boyd , Nishanth Menon , Vincent Guittot , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, Viresh Kumar Subject: [PATCH V3 3/7] PM / QOS: Keep common notifier list for genpd constraints Date: Fri, 24 Feb 2017 14:36:35 +0530 Message-Id: <851a8ddd4b30e632f2491fc034c62a0b0ebcccfa.1487926924.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.7.1.410.g6faf27b 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 Only the resume_latency constraint uses the notifiers right now. In order to prepare for adding new constraint types with notifiers, move to a common notifier list. Update pm_qos_update_target() to pass a pointer to the constraint structure to the notifier callbacks. Also update the notifier callbacks as well to error out for unexpected constraints. Signed-off-by: Viresh Kumar Tested-by: Rajendra Nayak --- drivers/base/power/domain.c | 26 +++++++++++++++++++------- drivers/base/power/qos.c | 15 ++++----------- include/linux/pm_qos.h | 7 +++++++ kernel/power/qos.c | 2 +- 4 files changed, 31 insertions(+), 19 deletions(-) -- 2.7.1.410.g6faf27b diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index e697dec9d25b..303490ab5ffd 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -416,14 +416,10 @@ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth) return ret; } -static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, - unsigned long val, void *ptr) +static int __resume_latency_notifier(struct generic_pm_domain_data *gpd_data, + unsigned long val) { - struct generic_pm_domain_data *gpd_data; - struct device *dev; - - gpd_data = container_of(nb, struct generic_pm_domain_data, nb); - dev = gpd_data->base.dev; + struct device *dev = gpd_data->base.dev; for (;;) { struct generic_pm_domain *genpd; @@ -456,6 +452,22 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, return NOTIFY_DONE; } +static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, + unsigned long val, void *ptr) +{ + struct generic_pm_domain_data *gpd_data; + struct device *dev; + + gpd_data = container_of(nb, struct generic_pm_domain_data, nb); + dev = gpd_data->base.dev; + + if (dev_pm_qos_notifier_is_resume_latency(dev, ptr)) + return __resume_latency_notifier(gpd_data, val); + + dev_err(dev, "%s: Unexpected notifier call\n", __func__); + return NOTIFY_BAD; +} + /** * genpd_power_off_work_fn - Power off PM domain whose subdomain count is 0. * @work: Work structure used for scheduling the execution of this function. diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 271bec73185e..851fff60319c 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -173,18 +173,12 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) { struct dev_pm_qos *qos; struct pm_qos_constraints *c; - struct blocking_notifier_head *n; qos = kzalloc(sizeof(*qos), GFP_KERNEL); if (!qos) return -ENOMEM; - n = kzalloc(sizeof(*n), GFP_KERNEL); - if (!n) { - kfree(qos); - return -ENOMEM; - } - BLOCKING_INIT_NOTIFIER_HEAD(n); + BLOCKING_INIT_NOTIFIER_HEAD(&qos->notifiers); c = &qos->resume_latency; plist_head_init(&c->list); @@ -192,7 +186,7 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) c->default_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; c->no_constraint_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; c->type = PM_QOS_MIN; - c->notifiers = n; + c->notifiers = &qos->notifiers; c = &qos->latency_tolerance; plist_head_init(&c->list); @@ -269,7 +263,6 @@ void dev_pm_qos_constraints_destroy(struct device *dev) dev->power.qos = ERR_PTR(-ENODEV); spin_unlock_irq(&dev->power.lock); - kfree(qos->resume_latency.notifiers); kfree(qos); out: @@ -488,7 +481,7 @@ int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier) ret = dev_pm_qos_constraints_allocate(dev); if (!ret) - ret = blocking_notifier_chain_register(dev->power.qos->resume_latency.notifiers, + ret = blocking_notifier_chain_register(&dev->power.qos->notifiers, notifier); mutex_unlock(&dev_pm_qos_mtx); @@ -515,7 +508,7 @@ int dev_pm_qos_remove_notifier(struct device *dev, /* Silently return if the constraints object is not present. */ if (!IS_ERR_OR_NULL(dev->power.qos)) - retval = blocking_notifier_chain_unregister(dev->power.qos->resume_latency.notifiers, + retval = blocking_notifier_chain_unregister(&dev->power.qos->notifiers, notifier); mutex_unlock(&dev_pm_qos_mtx); diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 3e2547d6e207..dd02020a02b6 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -100,6 +100,7 @@ struct dev_pm_qos { struct dev_pm_qos_request *resume_latency_req; struct dev_pm_qos_request *latency_tolerance_req; struct dev_pm_qos_request *flags_req; + struct blocking_notifier_head notifiers; /* common for all constraints */ }; /* Action requested to pm_qos_update_target */ @@ -114,6 +115,12 @@ static inline int dev_pm_qos_request_active(struct dev_pm_qos_request *req) return req->dev != NULL; } +static inline bool dev_pm_qos_notifier_is_resume_latency(struct device *dev, + struct pm_qos_constraints *c) +{ + return &dev->power.qos->resume_latency == 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, diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 97b0df71303e..073324e0c3c8 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -315,7 +315,7 @@ int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node, if (c->notifiers) blocking_notifier_call_chain(c->notifiers, (unsigned long)curr_value, - NULL); + c); } else { ret = 0; } From patchwork Fri Feb 24 09:06:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 94424 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp601539qgi; Fri, 24 Feb 2017 01:14:44 -0800 (PST) X-Received: by 10.84.198.164 with SMTP id p33mr2392297pld.85.1487927684263; Fri, 24 Feb 2017 01:14:44 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s5si6813245pgg.177.2017.02.24.01.14.43; Fri, 24 Feb 2017 01:14:44 -0800 (PST) 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 S1751507AbdBXJOc (ORCPT + 25 others); Fri, 24 Feb 2017 04:14:32 -0500 Received: from mail-pg0-f47.google.com ([74.125.83.47]:33722 "EHLO mail-pg0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751177AbdBXJOW (ORCPT ); Fri, 24 Feb 2017 04:14:22 -0500 Received: by mail-pg0-f47.google.com with SMTP id z128so9381966pgb.0 for ; Fri, 24 Feb 2017 01:14:22 -0800 (PST) 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=WeHjjDnGxkgacc2YBSp7TWZ/PwAQ2QQ7CJ0/Rel4SUI=; b=f1HhKLKOIfT9UD5JGfKRpe193dyDPwIpwkyXwlrmzz5huMXgw/cXgmx/VnsxTM9fms QfEJwyqZ7XuZgr4sKMexnz3QCLtEOzPuK4HnAR6jrjxuYmWwdYvFw1FxZXLL+t5Vf1rk P81W+p6NpXLGP3f/46HpMnmTb08M3yl7WdPZo= 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=WeHjjDnGxkgacc2YBSp7TWZ/PwAQ2QQ7CJ0/Rel4SUI=; b=FdhuwOdHovfuCqoGs8+M2k8lmswTe8T7CMgvsV/XlLvhMEDAE69Danz8sckSW6F1Q6 9mxSzApgAyYLP/SmlmisW3/2H5dqlIYmNHO57f6/KCR8Z6tS6uKNqRnp2gomB1kjsW42 +FFj11baiM7o9M0T2VSvGyMDXEEIf+lQDpaJtIfhmPzXLL5r1AI2Q86Zy2V0smVE4OEu K+hHi5xt6TjgneLM98UQywHEqpKCGpdCu4GsqohRt9aau9QDUMWSXxZrtQHEf+kXJuLS bGXF3pazRuonHWjKolZJQp1SqhSyLHY4ImMNz6NN29c++tEzwFvW4/d3J5jMNANKd8i2 tFgg== X-Gm-Message-State: AMke39knUBBcZVh60aKoUptN6m2YyoK4WnHbYWpvwOVrYldaVxtmjViSZMDlnDMmWZXafGsk X-Received: by 10.98.141.138 with SMTP id p10mr2123416pfk.111.1487927218390; Fri, 24 Feb 2017 01:06:58 -0800 (PST) Received: from localhost ([122.172.165.189]) by smtp.gmail.com with ESMTPSA id u129sm13852926pfb.130.2017.02.24.01.06.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Feb 2017 01:06:57 -0800 (PST) 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, Stephen Boyd , Nishanth Menon , Vincent Guittot , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, Viresh Kumar Subject: [PATCH V3 4/7] PM / QOS: Add DEV_PM_QOS_PERFORMANCE request Date: Fri, 24 Feb 2017 14:36:36 +0530 Message-Id: X-Mailer: git-send-email 2.7.1.410.g6faf27b 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 Tested-by: Rajendra Nayak --- Documentation/power/pm_qos_interface.txt | 2 +- drivers/base/power/qos.c | 21 +++++++++++++++++++++ include/linux/pm_qos.h | 10 ++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) -- 2.7.1.410.g6faf27b diff --git a/Documentation/power/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt index 21d2d48f87a2..4b7decdebf98 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 only). 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 851fff60319c..ca93ef6613c9 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -151,6 +151,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); @@ -195,6 +199,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); @@ -253,6 +265,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); @@ -363,6 +380,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: @@ -572,6 +590,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 dd02020a02b6..c369286026b5 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,9 +98,11 @@ 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; + struct dev_pm_qos_request *performance_req; struct dev_pm_qos_request *flags_req; struct blocking_notifier_head notifiers; /* common for all constraints */ }; @@ -121,6 +125,12 @@ static inline bool dev_pm_qos_notifier_is_resume_latency(struct device *dev, return &dev->power.qos->resume_latency == c; } +static inline bool dev_pm_qos_notifier_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 Fri Feb 24 09:06:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 94425 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp601542qgi; Fri, 24 Feb 2017 01:14:44 -0800 (PST) X-Received: by 10.99.43.74 with SMTP id r71mr2171950pgr.83.1487927684643; Fri, 24 Feb 2017 01:14:44 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s5si6813245pgg.177.2017.02.24.01.14.44; Fri, 24 Feb 2017 01:14:44 -0800 (PST) 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 S1751542AbdBXJOl (ORCPT + 25 others); Fri, 24 Feb 2017 04:14:41 -0500 Received: from mail-pg0-f42.google.com ([74.125.83.42]:35832 "EHLO mail-pg0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751334AbdBXJO0 (ORCPT ); Fri, 24 Feb 2017 04:14:26 -0500 Received: by mail-pg0-f42.google.com with SMTP id b129so9352337pgc.2 for ; Fri, 24 Feb 2017 01:14:25 -0800 (PST) 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=TAT89OO4uHxMyC3t7s8a0b5jBfH6XCxZ6sJZGfpOOEI=; b=JrzcPQb6Y/+twD58d4xhPpqlhsmmdhyBh9WjX+8gwaKYInmGjXf5RHnCC3ZPrAXgAN X340hQ7SbDsijf4GVima9To7jFkgr62SJ9tgQywgcdBepJzLb5ZVY0N073JDiwr1AY74 kvYvCQ8fX+l274Xuax1/Hs2iSzOfll0Pce3uA= 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=TAT89OO4uHxMyC3t7s8a0b5jBfH6XCxZ6sJZGfpOOEI=; b=qt8uknYeyJgA0sQ8LNzW3teEwXHgDp8KvvhcT0Ww7x/Z1t8w9q4SLYuwlyPdkOiqO5 eWUvGhldS/n1UREMAb97GgsJdnfTim57TSDBU9+urOMGyjvg4FfvJywPt1IM0woAzUBJ H7cySdCLjW7/HXZYVj1ePMmM4MtNdEfodXDzPOK4NnxgIdUTy82AbrcYAHoGvXLYjaB6 o1TVEZ5cwaSsPlAQ9sJPZQhoEBgJ1MIu9I16YltPtLHsBbFSouyO/1IHLsTUFSJc3h09 MAx71dRw4LICXQ9x/s/5bCSl2vs5Jc0XrRAjQ+DxYro69r19+3tqg9qPghzRnPdyyPQ4 P4iw== X-Gm-Message-State: AMke39mCD8YeMDk5JuD6cFwsORhuDd95yS3TlSmmA9u5jvGm02jIOrcgiEfAzu4ieUXrX6Fy X-Received: by 10.84.136.75 with SMTP id 69mr2425379plk.172.1487927221513; Fri, 24 Feb 2017 01:07:01 -0800 (PST) Received: from localhost ([122.172.165.189]) by smtp.gmail.com with ESMTPSA id y187sm13873589pfy.123.2017.02.24.01.07.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Feb 2017 01:07:01 -0800 (PST) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Kevin Hilman , Len Brown , Pavel Machek Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Stephen Boyd , Nishanth Menon , Vincent Guittot , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, Viresh Kumar Subject: [PATCH V3 5/7] PM / domain: Register for PM QOS performance notifier Date: Fri, 24 Feb 2017 14:36:37 +0530 Message-Id: <4c694a1dbef6184b5ad3cfdc038fe826f6a0c972.1487926924.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.7.1.410.g6faf27b 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 Tested-by: Rajendra Nayak --- drivers/base/power/domain.c | 77 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/pm_domain.h | 4 +++ 2 files changed, 81 insertions(+) -- 2.7.1.410.g6faf27b diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 303490ab5ffd..202effbebfd1 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -452,6 +452,79 @@ static int __resume_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) { @@ -464,6 +537,9 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, if (dev_pm_qos_notifier_is_resume_latency(dev, ptr)) return __resume_latency_notifier(gpd_data, val); + if (dev_pm_qos_notifier_is_performance(dev, ptr)) + return __performance_notifier(gpd_data, val); + dev_err(dev, "%s: Unexpected notifier call\n", __func__); return NOTIFY_BAD; } @@ -1157,6 +1233,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 5339ed5bd6f9..83795935709e 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -62,8 +62,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; @@ -117,6 +120,7 @@ struct generic_pm_domain_data { struct pm_domain_data base; struct gpd_timing_data td; struct notifier_block nb; + unsigned int performance_state; }; #ifdef CONFIG_PM_GENERIC_DOMAINS