From patchwork Fri Oct 23 10:26:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chanwoo Choi X-Patchwork-Id: 11852665 X-Patchwork-Delegate: cw00.choi@samsung.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0B139157C for ; Fri, 23 Oct 2020 10:13:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C35EC2465E for ; Fri, 23 Oct 2020 10:12:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="A1gf1cOY" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S461967AbgJWKM6 (ORCPT ); Fri, 23 Oct 2020 06:12:58 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:54479 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S461950AbgJWKM5 (ORCPT ); Fri, 23 Oct 2020 06:12:57 -0400 Received: from epcas1p2.samsung.com (unknown [182.195.41.46]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20201023101251epoutp049aad9669cf05bcf64e56cf6d94a704f9~Al29VMP3D2611726117epoutp04H for ; Fri, 23 Oct 2020 10:12:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20201023101251epoutp049aad9669cf05bcf64e56cf6d94a704f9~Al29VMP3D2611726117epoutp04H DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1603447971; bh=S1F9EiXqIWpMNp9kRz5mWbI6bNg8qsz28wGtwJf1nZY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=A1gf1cOYYRW3yngl7QofATzKoxLLjPl8/XK8LS58fwot7tu5nGMT5mt28doqo4bOL PFq8lATqE5dVJeNnPUNaHBiwMRwWG8CbiILkhq2afRLi1pcNSZI4vlg7LqKCpL5/vR LyZC4VqYpoSQAUudj4RiPKo6RSNi6wLxJxC1wuV0= Received: from epsnrtp4.localdomain (unknown [182.195.42.165]) by epcas1p3.samsung.com (KnoxPortal) with ESMTP id 20201023101250epcas1p3f08a5f15f10251dfbb228689866e09a6~Al28RXLqM2804728047epcas1p3j; Fri, 23 Oct 2020 10:12:50 +0000 (GMT) Received: from epsmges1p1.samsung.com (unknown [182.195.40.156]) by epsnrtp4.localdomain (Postfix) with ESMTP id 4CHg5q6qBQzMqYkf; Fri, 23 Oct 2020 10:12:47 +0000 (GMT) Received: from epcas1p3.samsung.com ( [182.195.41.47]) by epsmges1p1.samsung.com (Symantec Messaging Gateway) with SMTP id D2.7D.09543.F9CA29F5; Fri, 23 Oct 2020 19:12:47 +0900 (KST) Received: from epsmtrp1.samsung.com (unknown [182.195.40.13]) by epcas1p4.samsung.com (KnoxPortal) with ESMTPA id 20201023101246epcas1p423f0444201300830fd63f33748dd8952~Al24xJSlN2709927099epcas1p4e; Fri, 23 Oct 2020 10:12:46 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp1.samsung.com (KnoxPortal) with ESMTP id 20201023101246epsmtrp138ef22675b3525f300adf0de9e85a23d~Al24wK9f50544505445epsmtrp1q; Fri, 23 Oct 2020 10:12:46 +0000 (GMT) X-AuditID: b6c32a35-35dff70000002547-33-5f92ac9f4d36 Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id AF.E9.08745.E9CA29F5; Fri, 23 Oct 2020 19:12:46 +0900 (KST) Received: from localhost.localdomain (unknown [10.113.221.102]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20201023101246epsmtip24d410d786bb79992a5fa50c597435d97~Al24eWvey3177231772epsmtip2r; Fri, 23 Oct 2020 10:12:46 +0000 (GMT) From: Chanwoo Choi To: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org Cc: digetx@gmail.com, lukasz.luba@arm.com, enric.balletbo@collabora.com, hl@rock-chips.com, thierry.reding@gmail.com, jonathanh@nvidia.com, abel.vesa@nxp.com, k.konieczny@samsung.com, b.zolnierkie@samsung.com, cw00.choi@samsung.com, chanwoo@kernel.org, myungjoo.ham@samsung.com, kyungmin.park@samsung.com Subject: [PATCH v5 1/2] PM / devfreq: Add governor feature flag Date: Fri, 23 Oct 2020 19:26:31 +0900 Message-Id: <20201023102632.740-2-cw00.choi@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201023102632.740-1-cw00.choi@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA01Sf1AUZRieb29v2WPmaj3JPpiEaymdwwFugaMlIRxhdFH+uBFnKqs5N25b GI678/YozIlUCO8Ik5MwuhBEozpAhIup82jm8EANMknFkZEgqwnSkF8HdtmP6bjVqf+e932f 533e7/1eXKJoxmLwYqOVsxhZA4lFol8MqJITWzqP6tTu6jT6k6vnAd3TeEZKO8ZGUfrG0rSU 7lj4GdCd435AB7uHJXSV8yRKn1hslNLfHpyJoK95mzA6cHgQ0PYlJ0a3HqyKoMcPfIbRf3ib 0U0E09ncCRjPxMeAOeuciGDc7XaMOVw5izE9sx6E+dvpQ5n3etsBE3DHamW7SjKLOFbPWZSc sdCkLzbyWeT2Al2OTpOuphKpDPoZUmlkS7ksMjdfm7il2BB6B6l8nTWUhVJaVhDI5OcyLaYy K6csMgnWLJIz6w3mDHOSwJYKZUY+qdBU+iylVqdoQsTdJUXXL3gR883M8sYDl9H94FBKDZDh kEiDjqoWaQ2IxBWEB8Ajn89jYrAI4GjfFBCDAIDHXE2Sh5LJth5ELHgBXOw69UCyBOCHA3fD LIxIgL5fx0IFHI8iXoSVQ6tWOBLCg8C+yitghbOayIa/X72OrGCUeBrW1y6FsZyg4fTIMCq6 xcGO7v5wTxmRAWcGj6IrjSDhwuHC3HzYABK5sP6r50X+anjnYm+EiGPg7SPVD/A+6BoaxESt DcBe33dSsZAKfW31yEofCaGCZ7zJYvpJePbP4+E5JcQjcHa5VipayaGtWiFS4uG1WxOIiKPh qUN2TMQMtC91oeJOakNr/Oc4qAOxzv8cTgDQDtZwZqGU5wTKTP3/y9wgfKgJGg9w3J1P8gME B34AcQkZJe9b79Ap5Hp275ucxaSzlBk4wQ80oeU5JDGPFZpCl2606ihNSmpqKp1GpWsoinxc /tcGm05B8KyVK+E4M2d5qENwWcx+5KNGNbPY8ZbCj+fk5S0j03M73jlW3FD+RoXFO9hzOX6P g6+w/Ph2w8bXyrPXvmCIGpm9lJ5zRZjmlbbdWt+7M+PrM2/2e8amynP8+aejz22+sNla96rq ovW3IZf6lff57/c1/JC9XIPeyTgvyzVtHV73VNBVd49pu32aL+i2TTcNdDqz87uFTWtHd94K 7tzGF6jQqbi9Dj5tAHl0rML2xJx7WNdc5N9GBkeIn7TqBDq4tS0OEwr7/b9QkS+dVEdnfNDF 3ujX5wUo9RaV65tzzg1f13/qjn1ZFnPP0Zq4vU4Zr5vcyCftud8an7gqVzMZ+NKj3LXGHmiR U/cXJi4NRZKoUMRSCRKLwP4LE2JK5zEEAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrBLMWRmVeSWpSXmKPExsWy7bCSvO68NZPiDaZ/1rFYdukoo8XGGetZ LSbeuMJicf3Lc1aL1R8fM1qsuX2I0eLHhlPMFi2zFrFYLPg0g9XibNMbdovLu+awWXzuPcJo 0fllFpvFwqYWdovbjSvYLH7umsfiIOCxZt4aRo8dd5cweuycdZfdY9OqTjaP3uZ3bB4b3+1g 8vg7az+LR9+WVYwenzfJBXBGcdmkpOZklqUW6dslcGVcPbaLqeCWTcWMxnMsDYztRl2MnBwS AiYS95ZuZOpi5OIQEtjBKDH5YisLREJSYtrFo8xdjBxAtrDE4cPFEDWfGCXWznrOClLDJqAl sf/FDTYQW0QgWmLxx4/MIEXMAieYJFZ/2cUEkhAWsJf4fukqmM0ioCoxuecLmM0rYCHx/Pwp qGXyEqs3HGAGsTkFLCXeHJkEFhcCqrnfu51xAiPfAkaGVYySqQXFuem5xYYFRnmp5XrFibnF pXnpesn5uZsYwYGvpbWDcc+qD3qHGJk4GA8xSnAwK4nw7lafGC/Em5JYWZValB9fVJqTWnyI UZqDRUmc9+ushXFCAumJJanZqakFqUUwWSYOTqkGpph7mx8eObf+0udvDH5LOJRn32H4ffJC kWOB14lwy9QJsreuT7FcnLXg28TKjgPucxUMJBx+MV8Un7P2I7dQwKwFOvse2PZM5TI1fuD5 O3Zy+UGl05931hrs707L2H29lPe7cKJ8ldSpsON/y33s4+bvkV41MUWZ/fqcnF9fXhk5S9u8 UY9kznPVlBF8utKikaG1Y28IF0PItu8ZYspZ3vtnpAm+N46NOPjb2szrxsXd5g5qli5zf7h0 6SQ9/nU1Z+azzOxbJ9bOkbUKVjybsVLnr3DbPpmy3Ttdt5sf+LVhQ+w6kbb3d9POB8edCtK6 eLjcleN+xwalV1uWclSza26NSazU3Mb0QY738mPvDCWW4oxEQy3mouJEAJulr9vrAgAA X-CMS-MailID: 20201023101246epcas1p423f0444201300830fd63f33748dd8952 X-Msg-Generator: CA X-Sendblock-Type: SVC_REQ_APPROVE CMS-TYPE: 101P DLP-Filter: Pass X-CFilter-Loop: Reflected X-CMS-RootMailID: 20201023101246epcas1p423f0444201300830fd63f33748dd8952 References: <20201023102632.740-1-cw00.choi@samsung.com> Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The devfreq governor is able to have the specific flag as follows in order to implement the specific feature. For example, devfreq allows user to change the governors on runtime via sysfs interface. But, if devfreq device uses 'passive' governor, don't allow user to change the governor. For this case, define the DEVFREQ_GOV_FLAG_IMMUTABLE and set it to flag of passive governor. [Definition for governor flag] - DEVFREQ_GOV_FLAG_IMMUTABLE : If immutable flag is set, governor is never changeable to other governors. - DEVFREQ_GOV_FLAG_IRQ_DRIVEN : Devfreq core won't schedule polling work for this governor if value is set. [Table of governor flag for devfreq governors] ------------------------------------------------------------------------------ | simple | perfor | power | user | passive | tegra30 | ondemand | mance | save | space| | ------------------------------------------------------------------------------ immutable | X | X | X | X | O | O interrupt_driven | X(polling)| X | X | X | X | O (irq) ------------------------------------------------------------------------------ Signed-off-by: Chanwoo Choi Reviewed-by: Dmitry Osipenko Tested-by: Dmitry Osipenko --- drivers/devfreq/devfreq.c | 25 ++++++++++++++----------- drivers/devfreq/governor.h | 18 ++++++++++++------ drivers/devfreq/governor_passive.c | 2 +- drivers/devfreq/tegra30-devfreq.c | 4 ++-- 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 1b236b9e4d9e..a862acfe987e 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -31,6 +31,7 @@ #define CREATE_TRACE_POINTS #include +#define IS_SUPPORTED_FLAG(f, name) ((f & DEVFREQ_GOV_FLAG_##name) ? true : false) #define HZ_PER_KHZ 1000 static struct class *devfreq_class; @@ -479,7 +480,7 @@ static void devfreq_monitor(struct work_struct *work) */ void devfreq_monitor_start(struct devfreq *devfreq) { - if (devfreq->governor->interrupt_driven) + if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN)) return; switch (devfreq->profile->timer) { @@ -509,7 +510,7 @@ EXPORT_SYMBOL(devfreq_monitor_start); */ void devfreq_monitor_stop(struct devfreq *devfreq) { - if (devfreq->governor->interrupt_driven) + if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN)) return; cancel_delayed_work_sync(&devfreq->work); @@ -540,7 +541,7 @@ void devfreq_monitor_suspend(struct devfreq *devfreq) devfreq->stop_polling = true; mutex_unlock(&devfreq->lock); - if (devfreq->governor->interrupt_driven) + if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN)) return; cancel_delayed_work_sync(&devfreq->work); @@ -560,12 +561,13 @@ void devfreq_monitor_resume(struct devfreq *devfreq) unsigned long freq; mutex_lock(&devfreq->lock); - if (!devfreq->stop_polling) - goto out; - if (devfreq->governor->interrupt_driven) + if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN)) goto out_update; + if (!devfreq->stop_polling) + goto out; + if (!delayed_work_pending(&devfreq->work) && devfreq->profile->polling_ms) queue_delayed_work(devfreq_wq, &devfreq->work, @@ -600,10 +602,10 @@ void devfreq_update_interval(struct devfreq *devfreq, unsigned int *delay) mutex_lock(&devfreq->lock); devfreq->profile->polling_ms = new_delay; - if (devfreq->stop_polling) + if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN)) goto out; - if (devfreq->governor->interrupt_driven) + if (devfreq->stop_polling) goto out; /* if new delay is zero, stop polling */ @@ -1370,7 +1372,8 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr, if (df->governor == governor) { ret = 0; goto out; - } else if (df->governor->immutable || governor->immutable) { + } else if (IS_SUPPORTED_FLAG(df->governor->flags, IMMUTABLE) + || IS_SUPPORTED_FLAG(governor->flags, IMMUTABLE)) { ret = -EINVAL; goto out; } @@ -1425,7 +1428,7 @@ static ssize_t available_governors_show(struct device *d, * The devfreq with immutable governor (e.g., passive) shows * only own governor. */ - if (df->governor->immutable) { + if (IS_SUPPORTED_FLAG(df->governor->flags, IMMUTABLE)) { count = scnprintf(&buf[count], DEVFREQ_NAME_LEN, "%s ", df->governor_name); /* @@ -1436,7 +1439,7 @@ static ssize_t available_governors_show(struct device *d, struct devfreq_governor *governor; list_for_each_entry(governor, &devfreq_governor_list, node) { - if (governor->immutable) + if (IS_SUPPORTED_FLAG(governor->flags, IMMUTABLE)) continue; count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), "%s ", governor->name); diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h index 02cf876244d6..7dbb110a869e 100644 --- a/drivers/devfreq/governor.h +++ b/drivers/devfreq/governor.h @@ -25,14 +25,21 @@ #define DEVFREQ_MIN_FREQ 0 #define DEVFREQ_MAX_FREQ ULONG_MAX +/* + * Definition of the governor feature flags + * - DEVFREQ_GOV_FLAG_IMMUTABLE + * : This governor is never changeable to other governors. + * - DEVFREQ_GOV_FLAG_IRQ_DRIVEN + * : The devfreq won't schedule the work for this governor. + */ +#define DEVFREQ_GOV_FLAG_IMMUTABLE BIT(0) +#define DEVFREQ_GOV_FLAG_IRQ_DRIVEN BIT(1) + /** * struct devfreq_governor - Devfreq policy governor * @node: list node - contains registered devfreq governors * @name: Governor's name - * @immutable: Immutable flag for governor. If the value is 1, - * this governor is never changeable to other governor. - * @interrupt_driven: Devfreq core won't schedule polling work for this - * governor if value is set to 1. + * @flags: Governor's feature flags * @get_target_freq: Returns desired operating frequency for the device. * Basically, get_target_freq will run * devfreq_dev_profile.get_dev_status() to get the @@ -50,8 +57,7 @@ struct devfreq_governor { struct list_head node; const char name[DEVFREQ_NAME_LEN]; - const unsigned int immutable; - const unsigned int interrupt_driven; + const u64 flags; int (*get_target_freq)(struct devfreq *this, unsigned long *freq); int (*event_handler)(struct devfreq *devfreq, unsigned int event, void *data); diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index 53a1b1596232..63332e4a65ae 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -158,7 +158,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq, static struct devfreq_governor devfreq_passive = { .name = DEVFREQ_GOV_PASSIVE, - .immutable = 1, + .flags = DEVFREQ_GOV_FLAG_IMMUTABLE, .get_target_freq = devfreq_passive_get_target_freq, .event_handler = devfreq_passive_event_handler, }; diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c index f5e74c2ede85..faa1aecf2a31 100644 --- a/drivers/devfreq/tegra30-devfreq.c +++ b/drivers/devfreq/tegra30-devfreq.c @@ -765,10 +765,10 @@ static int tegra_governor_event_handler(struct devfreq *devfreq, static struct devfreq_governor tegra_devfreq_governor = { .name = "tegra_actmon", + .flags = DEVFREQ_GOV_FLAG_IMMUTABLE + | DEVFREQ_GOV_FLAG_IRQ_DRIVEN, .get_target_freq = tegra_governor_get_target, .event_handler = tegra_governor_event_handler, - .immutable = true, - .interrupt_driven = true, }; static int tegra_devfreq_probe(struct platform_device *pdev) From patchwork Fri Oct 23 10:26:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chanwoo Choi X-Patchwork-Id: 11852663 X-Patchwork-Delegate: cw00.choi@samsung.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B7FAA157C for ; Fri, 23 Oct 2020 10:12:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 696FC221F9 for ; Fri, 23 Oct 2020 10:12:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="XfB5vA2w" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S461849AbgJWKMz (ORCPT ); Fri, 23 Oct 2020 06:12:55 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:54473 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S461948AbgJWKMy (ORCPT ); Fri, 23 Oct 2020 06:12:54 -0400 Received: from epcas1p1.samsung.com (unknown [182.195.41.45]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20201023101250epoutp0462ba6ebbd81c4989eb18fa5a1f0f2dc2~Al28SP7wS2695326953epoutp04O for ; Fri, 23 Oct 2020 10:12:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20201023101250epoutp0462ba6ebbd81c4989eb18fa5a1f0f2dc2~Al28SP7wS2695326953epoutp04O DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1603447970; bh=6gXrFAPQsjO5xq6j5mn2SaU5gNy4LLhcIjmZy2Fgfvo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XfB5vA2w5cYOiWhF/GE3VY3gFN89JjjyRSiK3Cd2lwk4M7O8ZTXjGNSdxaP6TqbXU HH//yEosj/cNXgDVaVwlnMNxRemRxUP5RMDsfDssn2rHu8t8kRdtufBI8DXwEroRND LpORWhfj5+YSfKqYWXGMkgn5455TB7BexfqrJWqI= Received: from epsnrtp1.localdomain (unknown [182.195.42.162]) by epcas1p2.samsung.com (KnoxPortal) with ESMTP id 20201023101250epcas1p2e2e208e5764ee1a2e4926bb77fc34389~Al27y4HPi1811318113epcas1p2s; Fri, 23 Oct 2020 10:12:50 +0000 (GMT) Received: from epsmges1p5.samsung.com (unknown [182.195.40.156]) by epsnrtp1.localdomain (Postfix) with ESMTP id 4CHg5q33yZzMqYlh; Fri, 23 Oct 2020 10:12:47 +0000 (GMT) Received: from epcas1p2.samsung.com ( [182.195.41.46]) by epsmges1p5.samsung.com (Symantec Messaging Gateway) with SMTP id B2.B1.09577.F9CA29F5; Fri, 23 Oct 2020 19:12:47 +0900 (KST) Received: from epsmtrp2.samsung.com (unknown [182.195.40.14]) by epcas1p1.samsung.com (KnoxPortal) with ESMTPA id 20201023101247epcas1p14b14dc1be24842daac1dc7bd229d4570~Al249SKB61547715477epcas1p1t; Fri, 23 Oct 2020 10:12:47 +0000 (GMT) Received: from epsmgms1p2.samsung.com (unknown [182.195.42.42]) by epsmtrp2.samsung.com (KnoxPortal) with ESMTP id 20201023101247epsmtrp227052476d5f86bf27247a5200bcfb85d~Al248RZVs0815808158epsmtrp2J; Fri, 23 Oct 2020 10:12:47 +0000 (GMT) X-AuditID: b6c32a39-bfdff70000002569-86-5f92ac9ff7c3 Received: from epsmtip2.samsung.com ( [182.195.34.31]) by epsmgms1p2.samsung.com (Symantec Messaging Gateway) with SMTP id B0.F9.08745.E9CA29F5; Fri, 23 Oct 2020 19:12:46 +0900 (KST) Received: from localhost.localdomain (unknown [10.113.221.102]) by epsmtip2.samsung.com (KnoxPortal) with ESMTPA id 20201023101246epsmtip2684d7471894e929f7ddc85f646e1750e~Al24nHIbc2824028240epsmtip23; Fri, 23 Oct 2020 10:12:46 +0000 (GMT) From: Chanwoo Choi To: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org Cc: digetx@gmail.com, lukasz.luba@arm.com, enric.balletbo@collabora.com, hl@rock-chips.com, thierry.reding@gmail.com, jonathanh@nvidia.com, abel.vesa@nxp.com, k.konieczny@samsung.com, b.zolnierkie@samsung.com, cw00.choi@samsung.com, chanwoo@kernel.org, myungjoo.ham@samsung.com, kyungmin.park@samsung.com Subject: [PATCH v5 2/2] PM / devfreq: Add governor attribute flag for specifc sysfs nodes Date: Fri, 23 Oct 2020 19:26:32 +0900 Message-Id: <20201023102632.740-3-cw00.choi@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201023102632.740-1-cw00.choi@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprNJsWRmVeSWpSXmKPExsWy7bCmnu78NZPiDW4vFLFYdukoo8XGGetZ LSbeuMJicf3Lc1aL1R8fM1qsuX2I0eLHhlPMFi2zFrFYLPg0g9XibNMbdovLu+awWXzuPcJo 0fllFpvFwqYWdovbjSvYLH7umsfiIOCxZt4aRo8dd5cweuycdZfdY9OqTjaP3uZ3bB4b3+1g 8vg7az+LR9+WVYwenzfJBXBGZdtkpCampBYppOYl56dk5qXbKnkHxzvHm5oZGOoaWlqYKynk Jeam2iq5+AToumXmAP2hpFCWmFMKFApILC5W0rezKcovLUlVyMgvLrFVSi1IySmwLNArTswt Ls1L10vOz7UyNDAwMgUqTMjOuHjoAFPBmfqKDzd/szYwTkjrYuTkkBAwkdhxYx1bFyMXh5DA DkaJ3w9OMEM4nxgl/r5cBuV8ZpTYe+s4C0zLr2PtLBCJXYwSncs/sEM4XxgltvybyA5SxSag JbH/xQ2gwRwcIgKREs0nBUFqmAV2MEnsbr7ICBIXFoiWmL00GKScRUBV4sTi5UwgYV4BC4mT Z40gdslLrN5wgBnE5hSwlHhzZBLYXgmBtRwSey9tZYYocpHYuriREcIWlnh1fAs7hC0l8fnd XjYIu1pi5ckjbBDNHUB37r/ACpEwlti/dDLYYmYBTYn1u/QhwooSO3/PBZvJLMAn8e5rDytI iYQAr0RHmxBEibLE5Qd3mSBsSYnF7Z1sECUeErsmxYCEhQR6GCUO/SyewCg3C2H+AkbGVYxi qQXFuempxYYFpsjxtYkRnEq1LHcwTn/7Qe8QIxMH4yFGCQ5mJRHe3eoT44V4UxIrq1KL8uOL SnNSiw8xmgKDbiKzlGhyPjCZ55XEG5oaGRsbW5gYmpkaGiqJ8/7R7ogXEkhPLEnNTk0tSC2C 6WPi4JRqYOILK72w9/FJvp7KUK4Fl0+rHpsbsXb2TKGJYv7eU0rmWt3OZ1X98ah9qa+BKeui Zr7IY96Sn8/aKdsrzTbKWtbZwxgnLZ8n814rbXNG0NyNsdzfc/eZnJ+7/JfB+bnBfyo6GLY/ faxS9ODGP9Xw2LuGEes5AmVuNaxKC9tYbhFizcWTL7OpdO2dhKn7z8y0tmz7ldc44ZvFXE7t CRP+GfXm9andaU+TkV/ydsLnrwG8ZZe7/krZ//ytJ+lkzysdpJLUc0pAjse0T9rJ6VTFkzWT A6c7l61OVdDLKjQ8/sfEqtW737pl6YbXDHwh9y2PiIfpTX7aKV23y+lqtdmXbdZHl2x2Dq99 KL2TSz1fiaU4I9FQi7moOBEATd5M0y4EAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrOLMWRmVeSWpSXmKPExsWy7bCSvO68NZPiDSbfMbNYdukoo8XGGetZ LSbeuMJicf3Lc1aL1R8fM1qsuX2I0eLHhlPMFi2zFrFYLPg0g9XibNMbdovLu+awWXzuPcJo 0fllFpvFwqYWdovbjSvYLH7umsfiIOCxZt4aRo8dd5cweuycdZfdY9OqTjaP3uZ3bB4b3+1g 8vg7az+LR9+WVYwenzfJBXBGcdmkpOZklqUW6dslcGVcPHSAqeBMfcWHm79ZGxgnpHUxcnJI CJhI/DrWztLFyMUhJLCDUaJh5lomiISkxLSLR5m7GDmAbGGJw4eLIWo+MUoc7jvKDlLDJqAl sf/FDTYQW0QgWmLxx4/MIEXMAieYJFZ/2QU2SFggUmLSu8WsIDaLgKrEicXLmUCG8gpYSJw8 awSxS15i9YYDzCA2p4ClxJsjk1hAbCGgkvu92xknMPItYGRYxSiZWlCcm55bbFhglJdarlec mFtcmpeul5yfu4kRHPZaWjsY96z6oHeIkYmD8RCjBAezkgjvbvWJ8UK8KYmVValF+fFFpTmp xYcYpTlYlMR5v85aGCckkJ5YkpqdmlqQWgSTZeLglGpgsgkIv2ypt9Xuu4f1L9FtN04rSFzY tHWd5hPl3Eu22xtveRf+YZnCsdCbWyriAu+Rtb+Z8y4cy5C2ufzEIkfkavStE3uzGtKmMak3 MUgeann75azPGv+pddM5cgs+8IvKGXX9kplrOD2ENdX1/8GFF6/xr/Y+om7v856xKX/17/T1 rGJ1swtEH8x6dff138h9xyYYrDLZm7bCUjdQ3kEjIfvkIYbVvYZLAmekLfAPsprFtyRl/XJv 08l3i41meEyVt4gSnfCV+7hRdX6z791DaaV73d+m5R/quzS1Smta/p3ruydrb/1umrlO6km0 4Guul75LPvoKLbepyJQMdetJ2v3+ynK/2D1aeq9e5ta+UGIpzkg01GIuKk4EAMhD8e3qAgAA X-CMS-MailID: 20201023101247epcas1p14b14dc1be24842daac1dc7bd229d4570 X-Msg-Generator: CA X-Sendblock-Type: SVC_REQ_APPROVE CMS-TYPE: 101P DLP-Filter: Pass X-CFilter-Loop: Reflected X-CMS-RootMailID: 20201023101247epcas1p14b14dc1be24842daac1dc7bd229d4570 References: <20201023102632.740-1-cw00.choi@samsung.com> Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org DEVFREQ supports the default governors like performance, simple_ondemand and also allows the devfreq driver to add their own governor like tegra30-devfreq.c according to their requirement. In result, some sysfs attributes are useful or not useful. Prior to that the user can access all sysfs attributes regardless of the available attributes. So, clarify the access permission of sysfs attributes according to governor. When adding the devfreq governor, can specify the available attribute information by using DEVFREQ_GOV_ATTR_* constant variable. The user can read or write the sysfs attributes in accordance to the specified attributes. When adding the governor, can add the following attributes according to the governor feature. [Definition for speific sysfs attributes] - DEVFREQ_GOV_ATTR_POLLING_INTERVAL to update polling interval for timer. : /sys/class/devfreq/[devfreq dev name]/polling_interval - DEVFREQ_GOV_ATTR_TIMER to change the type of timer on either deferrable or dealyed timer. : /sys/class/devfreq/[devfreq dev name]/timer And all devfreq governors have to support the following common attributes. The common attributes are added to devfreq class by default. - governor - available_governors - available_frequencies - cur_freq - target_freq - min_freq - max_freq - trans_stat [Table of governor attribute flags for devfreq governors] ------------------------------------------------------------------------------ | simple | perfor | power | user | passive | tegra30 | ondemand | mance | save | space| | ------------------------------------------------------------------------------ governor | O | O | O | O | O | O available_governors | O | O | O | O | O | O available_frequencies | O | O | O | O | O | O cur_freq | O | O | O | O | O | O target_freq | O | O | O | O | O | O min_freq | O | O | O | O | O | O max_freq | O | O | O | O | O | O trans_stat | O | O | O | O | O | O -------------------------------------------------------- polling_interval | O | X | X | X | X | O timer | O | X | X | X | X | X ------------------------------------------------------------------------------ Signed-off-by: Chanwoo Choi Reviewed-by: Dmitry Osipenko Tested-by: Dmitry Osipenko --- Documentation/ABI/testing/sysfs-class-devfreq | 54 +++--- drivers/devfreq/devfreq.c | 160 ++++++++++++------ drivers/devfreq/governor.h | 12 ++ drivers/devfreq/governor_simpleondemand.c | 2 + drivers/devfreq/tegra30-devfreq.c | 1 + 5 files changed, 157 insertions(+), 72 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index deefffb3bbe4..67af3f31e17c 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -37,20 +37,6 @@ Description: The /sys/class/devfreq/.../target_freq shows the next governor predicted target frequency of the corresponding devfreq object. -What: /sys/class/devfreq/.../polling_interval -Date: September 2011 -Contact: MyungJoo Ham -Description: - The /sys/class/devfreq/.../polling_interval shows and sets - the requested polling interval of the corresponding devfreq - object. The values are represented in ms. If the value is - less than 1 jiffy, it is considered to be 0, which means - no polling. This value is meaningless if the governor is - not polling; thus. If the governor is not using - devfreq-provided central polling - (/sys/class/devfreq/.../central_polling is 0), this value - may be useless. - What: /sys/class/devfreq/.../trans_stat Date: October 2012 Contact: MyungJoo Ham @@ -65,14 +51,6 @@ Description: as following: echo 0 > /sys/class/devfreq/.../trans_stat -What: /sys/class/devfreq/.../userspace/set_freq -Date: September 2011 -Contact: MyungJoo Ham -Description: - The /sys/class/devfreq/.../userspace/set_freq shows and - sets the requested frequency for the devfreq object if - userspace governor is in effect. - What: /sys/class/devfreq/.../available_frequencies Date: October 2012 Contact: Nishanth Menon @@ -109,6 +87,35 @@ Description: The max_freq overrides min_freq because max_freq may be used to throttle devices to avoid overheating. +What: /sys/class/devfreq/.../polling_interval +Date: September 2011 +Contact: MyungJoo Ham +Description: + The /sys/class/devfreq/.../polling_interval shows and sets + the requested polling interval of the corresponding devfreq + object. The values are represented in ms. If the value is + less than 1 jiffy, it is considered to be 0, which means + no polling. This value is meaningless if the governor is + not polling; thus. If the governor is not using + devfreq-provided central polling + (/sys/class/devfreq/.../central_polling is 0), this value + may be useless. + + A list of governors that support the node: + - simple_ondmenad + - tegra_actmon + +What: /sys/class/devfreq/.../userspace/set_freq +Date: September 2011 +Contact: MyungJoo Ham +Description: + The /sys/class/devfreq/.../userspace/set_freq shows and + sets the requested frequency for the devfreq object if + userspace governor is in effect. + + A list of governors that support the node: + - userspace + What: /sys/class/devfreq/.../timer Date: July 2020 Contact: Chanwoo Choi @@ -120,3 +127,6 @@ Description: as following: echo deferrable > /sys/class/devfreq/.../timer echo delayed > /sys/class/devfreq/.../timer + + A list of governors that support the node: + - simple_ondemand diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index a862acfe987e..f6c55cf498ed 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -32,6 +32,7 @@ #include #define IS_SUPPORTED_FLAG(f, name) ((f & DEVFREQ_GOV_FLAG_##name) ? true : false) +#define IS_SUPPORTED_ATTR(f, name) ((f & DEVFREQ_GOV_ATTR_##name) ? true : false) #define HZ_PER_KHZ 1000 static struct class *devfreq_class; @@ -760,6 +761,11 @@ static void devfreq_dev_release(struct device *dev) kfree(devfreq); } +static void create_sysfs_files(struct devfreq *devfreq, + const struct devfreq_governor *gov); +static void remove_sysfs_files(struct devfreq *devfreq, + const struct devfreq_governor *gov); + /** * devfreq_add_device() - Add devfreq feature to the device * @dev: the device to add devfreq feature. @@ -909,6 +915,8 @@ struct devfreq *devfreq_add_device(struct device *dev, goto err_init; } + create_sysfs_files(devfreq, governor); + devfreq->governor = governor; err = devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_START, NULL); @@ -947,9 +955,12 @@ int devfreq_remove_device(struct devfreq *devfreq) if (!devfreq) return -EINVAL; - if (devfreq->governor) + if (devfreq->governor) { devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_STOP, NULL); + remove_sysfs_files(devfreq, devfreq->governor); + } + device_unregister(&devfreq->dev); return 0; @@ -1378,13 +1389,22 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr, goto out; } + /* + * Stop the current governor and remove the specific sysfs files + * which depend on current governor. + */ ret = df->governor->event_handler(df, DEVFREQ_GOV_STOP, NULL); if (ret) { dev_warn(dev, "%s: Governor %s not stopped(%d)\n", __func__, df->governor->name, ret); goto out; } + remove_sysfs_files(df, df->governor); + /* + * Start the new governor and create the specific sysfs files + * which depend on new governor. + */ prev_governor = df->governor; df->governor = governor; strncpy(df->governor_name, governor->name, DEVFREQ_NAME_LEN); @@ -1392,6 +1412,8 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr, if (ret) { dev_warn(dev, "%s: Governor %s not started(%d)\n", __func__, df->governor->name, ret); + + /* Restore previous governor */ df->governor = prev_governor; strncpy(df->governor_name, prev_governor->name, DEVFREQ_NAME_LEN); @@ -1401,8 +1423,13 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr, "%s: reverting to Governor %s failed (%d)\n", __func__, df->governor_name, ret); df->governor = NULL; + goto out; } + create_sysfs_files(df, df->governor); + goto out; } + create_sysfs_files(df, df->governor); + out: mutex_unlock(&devfreq_list_lock); @@ -1484,39 +1511,6 @@ static ssize_t target_freq_show(struct device *dev, } static DEVICE_ATTR_RO(target_freq); -static ssize_t polling_interval_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct devfreq *df = to_devfreq(dev); - - if (!df->profile) - return -EINVAL; - - return sprintf(buf, "%d\n", df->profile->polling_ms); -} - -static ssize_t polling_interval_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct devfreq *df = to_devfreq(dev); - unsigned int value; - int ret; - - if (!df->governor) - return -EINVAL; - - ret = sscanf(buf, "%u", &value); - if (ret != 1) - return -EINVAL; - - df->governor->event_handler(df, DEVFREQ_GOV_UPDATE_INTERVAL, &value); - ret = count; - - return ret; -} -static DEVICE_ATTR_RW(polling_interval); - static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -1724,6 +1718,53 @@ static ssize_t trans_stat_store(struct device *dev, } static DEVICE_ATTR_RW(trans_stat); +static struct attribute *devfreq_attrs[] = { + &dev_attr_name.attr, + &dev_attr_governor.attr, + &dev_attr_available_governors.attr, + &dev_attr_cur_freq.attr, + &dev_attr_available_frequencies.attr, + &dev_attr_target_freq.attr, + &dev_attr_min_freq.attr, + &dev_attr_max_freq.attr, + &dev_attr_trans_stat.attr, + NULL, +}; +ATTRIBUTE_GROUPS(devfreq); + +static ssize_t polling_interval_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct devfreq *df = to_devfreq(dev); + + if (!df->profile) + return -EINVAL; + + return sprintf(buf, "%d\n", df->profile->polling_ms); +} + +static ssize_t polling_interval_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct devfreq *df = to_devfreq(dev); + unsigned int value; + int ret; + + if (!df->governor) + return -EINVAL; + + ret = sscanf(buf, "%u", &value); + if (ret != 1) + return -EINVAL; + + df->governor->event_handler(df, DEVFREQ_GOV_UPDATE_INTERVAL, &value); + ret = count; + + return ret; +} +static DEVICE_ATTR_RW(polling_interval); + static ssize_t timer_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1787,21 +1828,36 @@ static ssize_t timer_store(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RW(timer); -static struct attribute *devfreq_attrs[] = { - &dev_attr_name.attr, - &dev_attr_governor.attr, - &dev_attr_available_governors.attr, - &dev_attr_cur_freq.attr, - &dev_attr_available_frequencies.attr, - &dev_attr_target_freq.attr, - &dev_attr_polling_interval.attr, - &dev_attr_min_freq.attr, - &dev_attr_max_freq.attr, - &dev_attr_trans_stat.attr, - &dev_attr_timer.attr, - NULL, -}; -ATTRIBUTE_GROUPS(devfreq); +#define CREATE_SYSFS_FILE(df, name) \ +{ \ + int ret; \ + ret = sysfs_create_file(&df->dev.kobj, &dev_attr_##name.attr); \ + if (ret < 0) { \ + dev_warn(&df->dev, \ + "Unable to create attr(%s)\n", "##name"); \ + } \ +} \ + +/* Create the specific sysfs files which depend on each governor. */ +static void create_sysfs_files(struct devfreq *devfreq, + const struct devfreq_governor *gov) +{ + if (IS_SUPPORTED_ATTR(gov->attrs, POLLING_INTERVAL)) + CREATE_SYSFS_FILE(devfreq, polling_interval); + if (IS_SUPPORTED_ATTR(gov->attrs, TIMER)) + CREATE_SYSFS_FILE(devfreq, timer); +} + +/* Remove the specific sysfs files which depend on each governor. */ +static void remove_sysfs_files(struct devfreq *devfreq, + const struct devfreq_governor *gov) +{ + if (IS_SUPPORTED_ATTR(gov->attrs, POLLING_INTERVAL)) + sysfs_remove_file(&devfreq->dev.kobj, + &dev_attr_polling_interval.attr); + if (IS_SUPPORTED_ATTR(gov->attrs, TIMER)) + sysfs_remove_file(&devfreq->dev.kobj, &dev_attr_timer.attr); +} /** * devfreq_summary_show() - Show the summary of the devfreq devices @@ -1858,8 +1914,12 @@ static int devfreq_summary_show(struct seq_file *s, void *data) mutex_lock(&devfreq->lock); cur_freq = devfreq->previous_freq; get_freq_range(devfreq, &min_freq, &max_freq); - polling_ms = devfreq->profile->polling_ms; timer = devfreq->profile->timer; + + if (IS_SUPPORTED_ATTR(devfreq->governor->attrs, POLLING_INTERVAL)) + polling_ms = devfreq->profile->polling_ms; + else + polling_ms = 0; mutex_unlock(&devfreq->lock); seq_printf(s, diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h index 7dbb110a869e..df413b851bb2 100644 --- a/drivers/devfreq/governor.h +++ b/drivers/devfreq/governor.h @@ -35,10 +35,21 @@ #define DEVFREQ_GOV_FLAG_IMMUTABLE BIT(0) #define DEVFREQ_GOV_FLAG_IRQ_DRIVEN BIT(1) +/* + * Definition of governor attribute flags except for common sysfs attributes + * - DEVFREQ_GOV_ATTR_POLLING_INTERVAL + * : Indicate polling_interal sysfs attribute + * - DEVFREQ_GOV_ATTR_TIMER + * : Indicate timer sysfs attribute + */ +#define DEVFREQ_GOV_ATTR_POLLING_INTERVAL BIT(0) +#define DEVFREQ_GOV_ATTR_TIMER BIT(1) + /** * struct devfreq_governor - Devfreq policy governor * @node: list node - contains registered devfreq governors * @name: Governor's name + * @attrs: Governor's sysfs attribute flags * @flags: Governor's feature flags * @get_target_freq: Returns desired operating frequency for the device. * Basically, get_target_freq will run @@ -57,6 +68,7 @@ struct devfreq_governor { struct list_head node; const char name[DEVFREQ_NAME_LEN]; + const u64 attrs; const u64 flags; int (*get_target_freq)(struct devfreq *this, unsigned long *freq); int (*event_handler)(struct devfreq *devfreq, diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c index 1b314e1df028..d57b82a2b570 100644 --- a/drivers/devfreq/governor_simpleondemand.c +++ b/drivers/devfreq/governor_simpleondemand.c @@ -117,6 +117,8 @@ static int devfreq_simple_ondemand_handler(struct devfreq *devfreq, static struct devfreq_governor devfreq_simple_ondemand = { .name = DEVFREQ_GOV_SIMPLE_ONDEMAND, + .attrs = DEVFREQ_GOV_ATTR_POLLING_INTERVAL + | DEVFREQ_GOV_ATTR_TIMER, .get_target_freq = devfreq_simple_ondemand_func, .event_handler = devfreq_simple_ondemand_handler, }; diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c index faa1aecf2a31..8f5b60bef336 100644 --- a/drivers/devfreq/tegra30-devfreq.c +++ b/drivers/devfreq/tegra30-devfreq.c @@ -765,6 +765,7 @@ static int tegra_governor_event_handler(struct devfreq *devfreq, static struct devfreq_governor tegra_devfreq_governor = { .name = "tegra_actmon", + .attrs = DEVFREQ_GOV_ATTR_POLLING_INTERVAL, .flags = DEVFREQ_GOV_FLAG_IMMUTABLE | DEVFREQ_GOV_FLAG_IRQ_DRIVEN, .get_target_freq = tegra_governor_get_target,