From patchwork Wed Feb 21 15:29:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 129089 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp752080ljc; Wed, 21 Feb 2018 07:31:21 -0800 (PST) X-Google-Smtp-Source: AH8x227PgTVAYQsATWm6KOXRNZROamtpJEFaj2L3ZCCVgo87n/MBaH4rViXdEklUzPg04Tfq0jSI X-Received: by 10.99.171.70 with SMTP id k6mr3092514pgp.355.1519227081115; Wed, 21 Feb 2018 07:31:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519227081; cv=none; d=google.com; s=arc-20160816; b=usii0h0Qc64bEmNhEDr9LkhQPBa/V8GkOFDQpDFeT1FL4Z5FE0Ec8knzny3yxA3JNK PJZyQgIAXxckSVtCM0UGALKLmL+wvpR17alHSGIO9LHPFy0UQyLqsJiDVVze1obwPICZ L8lYaagXPMnZBX6Njhn0vvZMBBuW/8bFGLV+IxZmS/dkOfce86Sg4cji4RqgLTDOQrVs HH4JV8ICby913wEKgQ0c+YfukYeDxHYVzDPBR1K9QTYCOv1WvXEo+4Ad4VAuZzhrFg0U bsrLaFd+wIK+CfZ6Fk26QNm6aflHTQoTycV636J22xVIw9taOBH4gjD0zE22dTq0v8fv qqSA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=LKbkROPJ7+yX2cTKE+YWPN3i3ijWAuW4LQ/8mPl//u4=; b=oCKnooiRlPzGfG+N2QBrbIvyp8imNIXnAUML7umwAhZ3krZx220JobyUc6ZLmTBhnd okSBC23NnviMmT94QFVvFxl0IuWYlU7F0xhxsTuDUOkYkiV36Rt0T5vinIhTJhtLmjFq C+FlvnvjsMRkhxMZWMJGXoiR/NElxVR56+iQeyKqyuZP3hqwUj9rcXy19ytT1OvQ88zp jqt8Fd3q+BQ8k54B/7V/pCEEWYiUHyA9zSxjkq3GgSLWxojlBYov64YyA1vhIJgdJr8N fZSA6DKNCx3JTmgstwrDG5DUdYQuRrQUu4aaveSP9hIbFNFks/H1bqFGmHLbzGZXewcv f4Vg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=L1VVITFR; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t1-v6si1250742plr.558.2018.02.21.07.31.20; Wed, 21 Feb 2018 07:31:21 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-pm-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 header.s=google header.b=L1VVITFR; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-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 S966033AbeBUPbS (ORCPT + 11 others); Wed, 21 Feb 2018 10:31:18 -0500 Received: from mail-wr0-f194.google.com ([209.85.128.194]:45404 "EHLO mail-wr0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S938276AbeBUP3n (ORCPT ); Wed, 21 Feb 2018 10:29:43 -0500 Received: by mail-wr0-f194.google.com with SMTP id p104so5584303wrc.12 for ; Wed, 21 Feb 2018 07:29:42 -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; bh=LKbkROPJ7+yX2cTKE+YWPN3i3ijWAuW4LQ/8mPl//u4=; b=L1VVITFRsJQgD7+ay1fNHtts3z/ypXZQOwLA5zP2wc0YgNgiAo+OHQK2EadyE3FgPk VILQ4oYtoEDc0CKQCRMlda3DelgG+lHmST2kn10pI2ofTrwq9wCU9vus94P5VLX2I1ye M7nmMNUChDk1wg4CfnqosGdNe1IpH0mg7AIOg= 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; bh=LKbkROPJ7+yX2cTKE+YWPN3i3ijWAuW4LQ/8mPl//u4=; b=TNLMkcurdPJvFvBcxNBcvD92aHaTOfmugcn8lpNYTXPVH8yc6sy2hwpTl10qr715+6 STn1CAZByTIdgKjpP6cr910wgI70bG8eRVoudk2ruVqbzCbPseiVrpktvsHyjiji6mx1 YhC/Ov3FU0uIeJLcq/BhST6MCzMwNqxZz66QY6RhBZkGc43CwKz7EiZBeIiJMLd6GI5Y 8B+W/VX9FaMTXN9gQm+O4AUcC+bXkFXrp6JSzAv/WRZJ4EAuDcKsASt+2In6IL1Ua/d/ 0Cut2F51cG+Oi+ajU7hXJlt7x9emCJj0W8NWuY1NibH8JPCJLT0IcU/galXDROf8qjqT NfLQ== X-Gm-Message-State: APf1xPAt2MfyFcV86S7xPFzNtofPUdz5877TmjdJgSpa1hiu/vjDKtIL qNqV7pqv7wur1HMLrT2xU5JsQA== X-Received: by 10.28.111.28 with SMTP id k28mr2357945wmc.54.1519226981874; Wed, 21 Feb 2018 07:29:41 -0800 (PST) Received: from localhost.localdomain ([2a01:e35:879a:6cd0:c4f2:763f:443f:f48]) by smtp.gmail.com with ESMTPSA id 32sm26552736wrm.14.2018.02.21.07.29.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 21 Feb 2018 07:29:41 -0800 (PST) From: Daniel Lezcano To: edubezval@gmail.com Cc: kevin.wangtao@linaro.org, leo.yan@linaro.org, vincent.guittot@linaro.org, amit.kachhap@gmail.com, linux-kernel@vger.kernel.org, javi.merino@kernel.org, rui.zhang@intel.com, daniel.thompson@linaro.org, linux-pm@vger.kernel.org, Viresh Kumar , Philippe Ombredanne Subject: [PATCH V2 2/7] thermal/drivers/cpu_cooling: Add Software Package Data Exchange (SPDX) Date: Wed, 21 Feb 2018 16:29:23 +0100 Message-Id: <1519226968-19821-3-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1519226968-19821-1-git-send-email-daniel.lezcano@linaro.org> References: <1519226968-19821-1-git-send-email-daniel.lezcano@linaro.org> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org For license auditing purpose, let's add the SPDX tag. Signed-off-by: Daniel Lezcano Acked-by: Viresh Kumar Acked-by: Philippe Ombredanne --- drivers/thermal/cpu_cooling.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) -- 2.7.4 diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 42110ee..d7528bc 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/drivers/thermal/cpu_cooling.c * @@ -8,21 +9,6 @@ * Authors: Amit Daniel * Viresh Kumar * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include #include From patchwork Wed Feb 21 15:29:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 129083 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp750384ljc; Wed, 21 Feb 2018 07:29:50 -0800 (PST) X-Google-Smtp-Source: AH8x224/m6ajtRZ7+EzhxbmwU4WinhQmE535y5zO2ITgHLArMaKHNhnYsUP4b3HPEPa+w/hYbVfw X-Received: by 2002:a17:902:7682:: with SMTP id m2-v6mr3468957pll.185.1519226989951; Wed, 21 Feb 2018 07:29:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519226989; cv=none; d=google.com; s=arc-20160816; b=Lm+K1ZXcMC+QJGGT+KOytXgSa2Ae7SY4P7NWgGKySg7rL98qhwBO9D84W6m6BrpUTW xq4GZCBNNKCswmRT2/cym3kdXda8i5HssoOLFJ2sg0MC9ex8/ryFAobUK1tkXaMjThRL AVVp78sJC7zwFj9bST3Sb+5a/k1clqT/m+vpxRCHYppGHblIVdJYfJXaY91f2outqkNv yaGNj2w6PPu8aXKW2jT7Nnri8UDVxiFWGJJvrfYpTAqBT8o5DE0kw9PwwuO/Iocxd1xl wCnVchiTCg5q8cVcWesHUjDbA4GFCdGdAK3B1Ag2+129lxISA4qXa1p2G6f2p1HciJpv HZxQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=MIkW9DTQm3etLCbfi0N45TzrpKsVBg+3M2BS1Oo+eSk=; b=sC0oaIFnuad7zLXvuwDks+zVd5TrjbOMGiP6TRBAsbwkMwUAB7VFr0apFE2ZbhrH6u SNOycM6wDffC5kZvRapXC0oSLgRwnHaOrp9TeRUlf6axABFahCu+Jkw8U8QXsvz/bqrE cWoW9ZgYDlko8AX9Om5YyTocMF+0ktU5kEaDtlXsI1o6U+tQr6fOY4wh3b8N8yx/79yw HsAl0dWmSJS7cb4CeVz2GHXMjwhPCv9s2lz8SS8dAndlSPYrSgTTsXH5KZflh14clc8m PcwoIiEHfhDb5zovC9Xkb+GGrV4484/BPBbWlZnlb95iR6fSDmABSI6lMKze6mezFVFT iaVg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ZjWzqWS8; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t24-v6si5569936plo.340.2018.02.21.07.29.49; Wed, 21 Feb 2018 07:29:49 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-pm-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 header.s=google header.b=ZjWzqWS8; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-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 S938296AbeBUP3r (ORCPT + 11 others); Wed, 21 Feb 2018 10:29:47 -0500 Received: from mail-wr0-f193.google.com ([209.85.128.193]:37728 "EHLO mail-wr0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S938292AbeBUP3p (ORCPT ); Wed, 21 Feb 2018 10:29:45 -0500 Received: by mail-wr0-f193.google.com with SMTP id z12so5619254wrg.4 for ; Wed, 21 Feb 2018 07:29:44 -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; bh=MIkW9DTQm3etLCbfi0N45TzrpKsVBg+3M2BS1Oo+eSk=; b=ZjWzqWS8QXCS9TXfEVz99RTwqgnrXlcEXWOG+t0JbR48FF8jG6vd2I7LMwloqvQtk3 Uo9BCUIvHwJWLBCkVDFErBD/Dd39YyKRmircnUTXmN9wxK3/3aWCxn95z90kS8q9TS6L gjC1KkSLBgIUBj3SbmXhdd6/M0UrLu9Eert9c= 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; bh=MIkW9DTQm3etLCbfi0N45TzrpKsVBg+3M2BS1Oo+eSk=; b=Ii+9hEWgveJeKcGnG24uSKFD769mnf0f7vRULQPN0lderql1j7oNfFwLiQyBSB6yqY ZzuPerI/CfA/7TIJmVwE2Wwe8QW8+vZouoDx8QgRnSx1jF3cFcuz2kMeEMk/k6RzkDgQ VCGoxTcVOy8pu8fR6SjV8gi6ELjcW+UfRyp+SiRUn9tqbRpzv2BOY42l9OAIWoGitcsQ WHqkvPu+A7tRZWwzIxy0PZy/Ohm1avVi+9qJ6/JeRmTp2nW4a07llvnrqIdG8ySvqk7z oFv+gXXXXJFwUefNItooenvJYBxfzVqCs6JFP8RnwpWs4BUSU8n1tdoUBZDBbfxy1gIl ZpIw== X-Gm-Message-State: APf1xPDrFL7AU5d4ORPIqva9DaqfZtapxIH0Yt1JMK40yJehrIxWemtS nPmE/lWnMNXphCLMrsWoMEMnrA== X-Received: by 10.223.135.51 with SMTP id a48mr3417062wra.149.1519226983630; Wed, 21 Feb 2018 07:29:43 -0800 (PST) Received: from localhost.localdomain ([2a01:e35:879a:6cd0:c4f2:763f:443f:f48]) by smtp.gmail.com with ESMTPSA id 32sm26552736wrm.14.2018.02.21.07.29.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 21 Feb 2018 07:29:42 -0800 (PST) From: Daniel Lezcano To: edubezval@gmail.com Cc: kevin.wangtao@linaro.org, leo.yan@linaro.org, vincent.guittot@linaro.org, amit.kachhap@gmail.com, linux-kernel@vger.kernel.org, javi.merino@kernel.org, rui.zhang@intel.com, daniel.thompson@linaro.org, linux-pm@vger.kernel.org, Viresh Kumar Subject: [PATCH V2 3/7] thermal/drivers/cpu_cooling: Remove pointless field Date: Wed, 21 Feb 2018 16:29:24 +0100 Message-Id: <1519226968-19821-4-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1519226968-19821-1-git-send-email-daniel.lezcano@linaro.org> References: <1519226968-19821-1-git-send-email-daniel.lezcano@linaro.org> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The structure cpufreq_cooling_device provides a backpointer to the thermal device but this one is used for a trace and to unregister. For the trace, we don't really need this field and the unregister function as the same pointer passed as parameter. Remove it. Acked-by: Viresh Kumar Signed-off-by: Daniel Lezcano --- drivers/thermal/cpu_cooling.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) -- 2.7.4 diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index d7528bc..7bdc19f 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -88,7 +88,6 @@ struct cpufreq_cooling_device { unsigned int clipped_freq; unsigned int max_level; struct freq_table *freq_table; /* In descending order */ - struct thermal_cooling_device *cdev; struct cpufreq_policy *policy; struct list_head node; struct time_in_idle *idle_time; @@ -197,8 +196,7 @@ static int update_freq_table(struct cpufreq_cooling_device *cpufreq_cdev, dev = get_cpu_device(cpu); if (unlikely(!dev)) { - dev_warn(&cpufreq_cdev->cdev->device, - "No cpu device for cpu %d\n", cpu); + pr_warn("No cpu device for cpu %d\n", cpu); return -ENODEV; } @@ -762,7 +760,6 @@ __cpufreq_cooling_register(struct device_node *np, goto remove_ida; cpufreq_cdev->clipped_freq = cpufreq_cdev->freq_table[0].frequency; - cpufreq_cdev->cdev = cdev; mutex_lock(&cooling_list_lock); /* Register the notifier for first cpufreq cooling device */ @@ -922,7 +919,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER); - thermal_cooling_device_unregister(cpufreq_cdev->cdev); + thermal_cooling_device_unregister(cdev); ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id); kfree(cpufreq_cdev->idle_time); kfree(cpufreq_cdev->freq_table); From patchwork Wed Feb 21 15:29:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 129087 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp751201ljc; Wed, 21 Feb 2018 07:30:33 -0800 (PST) X-Google-Smtp-Source: AH8x227u0FjBOoZcJu8s28HAY04oKOVsGuLNNYMQIDovqYsSuhagjdtiae3E4yv0q46J+xUe8U0a X-Received: by 10.99.172.2 with SMTP id v2mr3100113pge.204.1519227033567; Wed, 21 Feb 2018 07:30:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519227033; cv=none; d=google.com; s=arc-20160816; b=Vo3+2zO6NmAPRc5hAmaFYNx+0m6iFDnNQ2vQUEP1Z1OuF0NbzGJdpE+i4B8G3fHNhH yP2EAs5kZ5VlkBQZ92fxqh84IvG3IoSXXO5PmQJCOz3i/qBhPz2/L8M+RFJqbjQsp3jK IS58U+t5OWZTDR0E8QylwkZ3P7/tdfBO/4NtwQJIQ07l0AT59QHnf0dgbvruJtPUZAhA gxSRS73uwNVBAlqemGGxFZAPKUsu3CVPvWZ23oxTOQpwcQPSme+CXCDfHjpGvV+cCaiQ 9wrRPDNKtSSmH8IAGTBZnEw6x2qWF8S/FxFjIsn5aICx5RzW+zTNiIVi/k/+LkiZ5g5t lrVg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=T1pkiCxqgzri3SRd5Jn9QYeoiNV9xRR29xnevUB20Rk=; b=psdZcnkO28wgaMlxqPeLhtBAc1ZxMRAwew0Z056nFrty4xJbV1mrDtDoWIDsNNE6bK l+V+yJPmD7ktcWk/tA2uLMFZWwGAWj9JbLMvCUY+s32ai1NcCF5A5vbzYOclImrgkda8 UIYO48z1cnaYK4/yYqWaImRplEZlRyw8x8LcAJK5LC7uTpv+6MOCkT8mehfVWfYBUhcU dfmyGYSI5lJ/S/qRn4mNGJyP/HpjXkOv/E10wqgjg2/XXuQKpofnNcjRQk6+X0BLKNwd vt2bVxo++5WD6yPueQB5cQukJH8q2JkoyOl9ArtFS+58DyDxhnctPD+pG5U2RXF/zr95 MkTg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Bg3q0Pvd; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r4si1203020pgp.603.2018.02.21.07.30.33; Wed, 21 Feb 2018 07:30:33 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-pm-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 header.s=google header.b=Bg3q0Pvd; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-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 S936272AbeBUPab (ORCPT + 11 others); Wed, 21 Feb 2018 10:30:31 -0500 Received: from mail-wr0-f195.google.com ([209.85.128.195]:32956 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S938323AbeBUPaA (ORCPT ); Wed, 21 Feb 2018 10:30:00 -0500 Received: by mail-wr0-f195.google.com with SMTP id s5so5635000wra.0 for ; Wed, 21 Feb 2018 07:29: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 :mime-version:content-transfer-encoding; bh=T1pkiCxqgzri3SRd5Jn9QYeoiNV9xRR29xnevUB20Rk=; b=Bg3q0Pvd9FxPWUopA15//gIqR8zqyhico1WoexGc1ykYJnD0Am5jg+eAQtUmDS7SWL 5XZGahvkoaDHY3kqwa/3YyhJ+mBzYgC1CbSTMl2UrZUgQlPeQOKm+SsdLtj7KYz4/o7W RGTmaYMTPz8GIBlrLaDRegKGeLeeDjClaDrV4= 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:mime-version:content-transfer-encoding; bh=T1pkiCxqgzri3SRd5Jn9QYeoiNV9xRR29xnevUB20Rk=; b=lznr1JAasUqEKoikfccZkzfnpOGA8JutwqCpJFeyxAL4pekkDRH0o2h9Ld/O9xteBD jCHTXZ6k4VhoUd8j2PysRHUSX6ryLHvB17+EARVscj/k9K4UVSqPutMQxWzKVLBpLvCW jMnwEuqu8fXkaXdai2utNq6SUYONVRbQp+5R9GCGhIe/ApeSEKf790I9H9V5tAK18rpi LIx9wMjPDEq65Xdo1xch+HFVZ5xXgKz3+N6CmCHhFcn4xuoq74CNCeWse6yBjxWvyP2u QUrE/zOhGYGgZxnekRb7bXDiaGc4b/8l/xYDbiYT12tl+ybwlPJj/8XVdO87uK0WMtEe /Hiw== X-Gm-Message-State: APf1xPAlRXgdkY+/K+mMnatE+G3GEUMvW4boykOqciYhKJ7w5VMBOYFt lViTINz9k+rd7JilW0ARl1K9cunpApo= X-Received: by 10.223.178.26 with SMTP id u26mr3459683wra.63.1519226998832; Wed, 21 Feb 2018 07:29:58 -0800 (PST) Received: from localhost.localdomain ([2a01:e35:879a:6cd0:c4f2:763f:443f:f48]) by smtp.gmail.com with ESMTPSA id 32sm26552736wrm.14.2018.02.21.07.29.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 21 Feb 2018 07:29:58 -0800 (PST) From: Daniel Lezcano To: edubezval@gmail.com Cc: kevin.wangtao@linaro.org, leo.yan@linaro.org, vincent.guittot@linaro.org, amit.kachhap@gmail.com, linux-kernel@vger.kernel.org, javi.merino@kernel.org, rui.zhang@intel.com, daniel.thompson@linaro.org, linux-pm@vger.kernel.org, Viresh Kumar Subject: [PATCH V2 6/7] thermal/drivers/cpu_cooling: Introduce the cpu idle cooling driver Date: Wed, 21 Feb 2018 16:29:27 +0100 Message-Id: <1519226968-19821-7-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1519226968-19821-1-git-send-email-daniel.lezcano@linaro.org> References: <1519226968-19821-1-git-send-email-daniel.lezcano@linaro.org> MIME-Version: 1.0 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The cpu idle cooling driver performs synchronized idle injection across all cpus belonging to the same cluster and offers a new method to cool down a SoC. Each cluster has its own idle cooling device, each core has its own idle injection thread, each idle injection thread uses play_idle to enter idle. In order to reach the deepest idle state, each cooling device has the idle injection threads synchronized together. It has some similarity with the intel power clamp driver but it is actually designed to work on the ARM architecture via the DT with a mathematical proof with the power model which comes with the Documentation. The idle injection cycle is fixed while the running cycle is variable. That allows to have control on the device reactivity for the user experience. At the mitigation point the idle threads are unparked, they play idle the specified amount of time and they schedule themselves. The last thread sets the next idle injection deadline and when the timer expires it wakes up all the threads which in turn play idle again. Meanwhile the running cycle is changed by set_cur_state. When the mitigation ends, the threads are parked. The algorithm is self adaptive, so there is no need to handle hotplugging. If we take an example of the balanced point, we can use the DT for the hi6220. The sustainable power for the SoC is 3326mW to mitigate at 75°C. Eight cores running at full blast at the maximum OPP consumes 5280mW. The first value is given in the DT, the second is calculated from the OPP with the formula: Pdyn = Cdyn x Voltage^2 x Frequency As the SoC vendors don't want to share the static leakage values, we assume it is zero, so the Prun = Pdyn + Pstatic = Pdyn + 0 = Pdyn. In order to reduce the power to 3326mW, we have to apply a ratio to the running time. ratio = (Prun - Ptarget) / Ptarget = (5280 - 3326) / 3326 = 0,5874 We know the idle cycle which is fixed, let's assume 10ms. However from this duration we have to substract the wake up latency for the cluster idle state. In our case, it is 1.5ms. So for a 10ms latency for idle, we are really idle 8.5ms. As we know the idle duration and the ratio, we can compute the running cycle. running_cycle = 8.5 / 0.5874 = 14.47ms So for 8.5ms of idle, we have 14.47ms of running cycle, and that brings the SoC to the balanced trip point of 75°C. The driver has been tested on the hi6220 and it appears the temperature stabilizes at 75°C with an idle injection time of 10ms (8.5ms real) and running cycle of 14ms as expected by the theory above. Signed-off-by: Kevin Wangtao Signed-off-by: Daniel Lezcano --- drivers/thermal/Kconfig | 10 + drivers/thermal/cpu_cooling.c | 451 ++++++++++++++++++++++++++++++++++++++++++ include/linux/cpu_cooling.h | 9 + 3 files changed, 470 insertions(+) -- 2.7.4 diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 5aaae1b..6c34117 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -166,6 +166,16 @@ config CPU_FREQ_THERMAL This will be useful for platforms using the generic thermal interface and not the ACPI interface. +config CPU_IDLE_THERMAL + bool "CPU idle cooling strategy" + depends on CPU_IDLE + help + This implements the generic CPU cooling mechanism through + idle injection. This will throttle the CPU by injecting + fixed idle cycle. All CPUs belonging to the same cluster + will enter idle synchronously to reach the deepest idle + state. + endchoice config CLOCK_THERMAL diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 5c219dc..9340216 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -10,18 +10,32 @@ * Viresh Kumar * */ +#undef DEBUG +#define pr_fmt(fmt) "CPU cooling: " fmt + #include #include #include +#include #include +#include #include +#include #include #include +#include +#include #include #include +#include + +#include +#include #include +#include + #ifdef CONFIG_CPU_FREQ_THERMAL /* * Cooling state <-> CPUFreq frequency @@ -928,3 +942,440 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) } EXPORT_SYMBOL_GPL(cpufreq_cooling_unregister); #endif /* CONFIG_CPU_FREQ_THERMAL */ + +#ifdef CONFIG_CPU_IDLE_THERMAL +/* + * The idle duration injection. As we don't have yet a way to specify + * from the DT configuration, let's default to a tick duration. + */ +#define DEFAULT_IDLE_TIME_US TICK_USEC + +/** + * struct cpuidle_cooling_device - data for the idle cooling device + * @cdev: a pointer to a struct thermal_cooling_device + * @cpumask: a cpumask containing the CPU managed by the cooling device + * @timer: a hrtimer giving the tempo for the idle injection cycles + * @kref: a kernel refcount on this structure + * @count: an atomic to keep track of the last task exiting the idle cycle + * @idle_cycle: an integer defining the duration of the idle injection + * @state: an normalized integer giving the state of the cooling device + */ +struct cpuidle_cooling_device { + struct thermal_cooling_device *cdev; + struct cpumask *cpumask; + struct list_head node; + struct hrtimer timer; + struct kref kref; + atomic_t count; + unsigned int idle_cycle; + unsigned int state; +}; + +/** + * @tsk: an array of pointer to the idle injection tasks + * @waitq: the waiq for the idle injection tasks + */ +struct cpuidle_cooling_tsk { + struct task_struct *tsk; + wait_queue_head_t waitq; +}; + +DEFINE_PER_CPU(struct cpuidle_cooling_tsk, cpuidle_cooling_tsk); + +static LIST_HEAD(cpuidle_cdev_list); + +/** + * cpuidle_cooling_wakeup - Wake up all idle injection threads + * @idle_cdev: the idle cooling device + * + * Every idle injection task belonging to the idle cooling device and + * running on an online cpu will be wake up by this call. + */ +static void cpuidle_cooling_wakeup(struct cpuidle_cooling_device *idle_cdev) +{ + int cpu; + struct cpuidle_cooling_tsk *cct; + + for_each_cpu_and(cpu, idle_cdev->cpumask, cpu_online_mask) { + cct = per_cpu_ptr(&cpuidle_cooling_tsk, cpu); + wake_up_process(cct->tsk); + } +} + +/** + * cpuidle_cooling_wakeup_fn - Running cycle timer callback + * @timer: a hrtimer structure + * + * When the mitigation is acting, the CPU is allowed to run an amount + * of time, then the idle injection happens for the specified delay + * and the idle task injection schedules itself until the timer event + * wakes the idle injection tasks again for a new idle injection + * cycle. The time between the end of the idle injection and the timer + * expiration is the allocated running time for the CPU. + * + * Returns always HRTIMER_NORESTART + */ +static enum hrtimer_restart cpuidle_cooling_wakeup_fn(struct hrtimer *timer) +{ + struct cpuidle_cooling_device *idle_cdev = + container_of(timer, struct cpuidle_cooling_device, timer); + + cpuidle_cooling_wakeup(idle_cdev); + + return HRTIMER_NORESTART; +} + +/** + * cpuidle_cooling_runtime - Running time computation + * @idle_cdev: the idle cooling device + * + * The running duration is computed from the idle injection duration + * which is fixed. If we reach 100% of idle injection ratio, that + * means the running duration is zero. If we have a 50% ratio + * injection, that means we have equal duration for idle and for + * running duration. + * + * The formula is deduced as the following: + * + * running = idle x ((100 / ratio) - 1) + * + * For precision purpose for integer math, we use the following: + * + * running = (idle x 100) / ratio - idle + * + * For example, if we have an injected duration of 50%, then we end up + * with 10ms of idle injection and 10ms of running duration. + * + * Returns a s64 nanosecond based + */ +static s64 cpuidle_cooling_runtime(struct cpuidle_cooling_device *idle_cdev) +{ + s64 next_wakeup; + int state = idle_cdev->state; + + /* + * The function must never be called when there is no + * mitigation because: + * - that does not make sense + * - we end up with a division by zero + */ + BUG_ON(!state); + + next_wakeup = (s64)((idle_cdev->idle_cycle * 100) / state) - + idle_cdev->idle_cycle; + + return next_wakeup * NSEC_PER_USEC; +} + +/** + * cpuidle_cooling_injection_thread - Idle injection mainloop thread function + * @arg: a void pointer containing the idle cooling device address + * + * This main function does basically two operations: + * + * - Goes idle for a specific amount of time + * + * - Sets a timer to wake up all the idle injection threads after a + * running period + * + * That happens only when the mitigation is enabled, otherwise the + * task is scheduled out. + * + * In order to keep the tasks synchronized together, it is the last + * task exiting the idle period which is in charge of setting the + * timer. + * + * This function never returns. + */ +static int cpuidle_cooling_injection_thread(void *arg) +{ + struct sched_param param = { .sched_priority = MAX_USER_RT_PRIO/2 }; + struct cpuidle_cooling_device *idle_cdev = arg; + struct cpuidle_cooling_tsk *cct = per_cpu_ptr(&cpuidle_cooling_tsk, + smp_processor_id()); + DEFINE_WAIT(wait); + + set_freezable(); + + sched_setscheduler(current, SCHED_FIFO, ¶m); + + while (1) { + s64 next_wakeup; + + prepare_to_wait(&cct->waitq, &wait, TASK_INTERRUPTIBLE); + + schedule(); + + atomic_inc(&idle_cdev->count); + + play_idle(idle_cdev->idle_cycle / USEC_PER_MSEC); + + /* + * The last CPU waking up is in charge of setting the + * timer. If the CPU is hotplugged, the timer will + * move to another CPU (which may not belong to the + * same cluster) but that is not a problem as the + * timer will be set again by another CPU belonging to + * the cluster, so this mechanism is self adaptive and + * does not require any hotplugging dance. + */ + if (!atomic_dec_and_test(&idle_cdev->count)) + continue; + + if (!idle_cdev->state) + continue; + + next_wakeup = cpuidle_cooling_runtime(idle_cdev); + + hrtimer_start(&idle_cdev->timer, ns_to_ktime(next_wakeup), + HRTIMER_MODE_REL_PINNED); + } + + finish_wait(&cct->waitq, &wait); + + return 0; +} + +/** + * cpuidle_cooling_release - Kref based release helper + * @kref: a pointer to the kref structure + * + * This function is automatically called by the kref_put function when + * the idle cooling device refcount reaches zero. At this point, we + * have the guarantee the structure is no longer in use and we can + * safely release all the ressources. + */ +static void __init cpuidle_cooling_release(struct kref *kref) +{ + struct cpuidle_cooling_device *idle_cdev = + container_of(kref, struct cpuidle_cooling_device, kref); + + thermal_cooling_device_unregister(idle_cdev->cdev); + kfree(idle_cdev); +} + +/** + * cpuidle_cooling_get_max_state - Get the maximum state + * @cdev : the thermal cooling device + * @state : a pointer to the state variable to be filled + * + * The function gives always 100 as the injection ratio is percentile + * based for consistency accros different platforms. + * + * The function can not fail, it returns always zero. + */ +static int cpuidle_cooling_get_max_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + /* + * Depending on the configuration or the hardware, the running + * cycle and the idle cycle could be different. We want unify + * that to an 0..100 interval, so the set state interface will + * be the same whatever the platform is. + * + * The state 100% will make the cluster 100% ... idle. A 0% + * injection ratio means no idle injection at all and 50% + * means for 10ms of idle injection, we have 10ms of running + * time. + */ + *state = 100; + + return 0; +} + +/** + * cpuidle_cooling_get_cur_state - Get the current cooling state + * @cdev: the thermal cooling device + * @state: a pointer to the state + * + * The function just copy the state value from the private thermal + * cooling device structure, the mapping is 1 <-> 1. + * + * The function can not fail, it returns always zero. + */ +static int cpuidle_cooling_get_cur_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct cpuidle_cooling_device *idle_cdev = cdev->devdata; + + *state = idle_cdev->state; + + return 0; +} + +/** + * cpuidle_cooling_set_cur_state - Set the current cooling state + * @cdev: the thermal cooling device + * @state: the target state + * + * The function checks first if we are initiating the mitigation which + * in turn wakes up all the idle injection tasks belonging to the idle + * cooling device. In any case, it updates the internal state for the + * cooling device. + * + * The function can not fail, it returns always zero. + */ +static int cpuidle_cooling_set_cur_state(struct thermal_cooling_device *cdev, + unsigned long state) +{ + struct cpuidle_cooling_device *idle_cdev = cdev->devdata; + unsigned long current_state = idle_cdev->state; + + idle_cdev->state = state; + + if (current_state == 0 && state > 0) { + pr_debug("Starting cooling cpus '%*pbl'\n", + cpumask_pr_args(idle_cdev->cpumask)); + cpuidle_cooling_wakeup(idle_cdev); + } else if (current_state > 0 && !state) { + pr_debug("Stopping cooling cpus '%*pbl'\n", + cpumask_pr_args(idle_cdev->cpumask)); + } + + return 0; +} + +/** + * cpuidle_cooling_ops - thermal cooling device ops + */ +static struct thermal_cooling_device_ops cpuidle_cooling_ops = { + .get_max_state = cpuidle_cooling_get_max_state, + .get_cur_state = cpuidle_cooling_get_cur_state, + .set_cur_state = cpuidle_cooling_set_cur_state, +}; + +/** + * cpuilde_cooling_unregister - Idle cooling device exit function + * + * This function unregisters the cpuidle cooling device and frees the + * ressources previously allocated by the init function. This function + * is called when the initialization fails. + */ +static void cpuidle_cooling_unregister(void) +{ + struct cpuidle_cooling_device *tmp, *idle_cdev = NULL; + struct cpuidle_cooling_tsk *cct; + int cpu; + + list_for_each_entry_safe(idle_cdev, tmp, &cpuidle_cdev_list, node) { + for_each_cpu(cpu, idle_cdev->cpumask) { + cct = per_cpu_ptr(&cpuidle_cooling_tsk, cpu); + if (cct->tsk) + kthread_stop(cct->tsk); + kref_put(&idle_cdev->kref, cpuidle_cooling_release); + } + } +} + +/** + * cpuidle_cooling_register - Idle cooling device initialization function + * + * This function is in charge of creating a cooling device per cluster + * and register it to thermal framework. For this we rely on the + * topology as there is nothing yet describing better the idle state + * power domains. + * + * For each first CPU of the cluster's cpumask, we allocate the idle + * cooling device, initialize the general fields and then we initialze + * the rest in a per cpu basis. + * + * Returns zero on success, < 0 otherwise. + */ +int cpuidle_cooling_register(void) +{ + struct cpuidle_cooling_device *idle_cdev = NULL; + struct thermal_cooling_device *cdev; + struct cpuidle_cooling_tsk *cct; + struct task_struct *tsk; + struct device_node *np; + cpumask_t *cpumask; + char dev_name[THERMAL_NAME_LENGTH]; + int ret = -ENOMEM, cpu; + int index = 0; + + for_each_possible_cpu(cpu) { + cpumask = topology_core_cpumask(cpu); + + cct = per_cpu_ptr(&cpuidle_cooling_tsk, cpu); + + /* + * This condition makes the first cpu belonging to the + * cluster to create a cooling device and allocates + * the structure. Others CPUs belonging to the same + * cluster will just increment the refcount on the + * cooling device structure and initialize it. + */ + if (cpu == cpumask_first(cpumask)) { + np = of_cpu_device_node_get(cpu); + + idle_cdev = kzalloc(sizeof(*idle_cdev), GFP_KERNEL); + if (!idle_cdev) + goto out_fail; + + idle_cdev->idle_cycle = DEFAULT_IDLE_TIME_US; + + atomic_set(&idle_cdev->count, 0); + + kref_init(&idle_cdev->kref); + + /* + * Initialize the timer to wakeup all the idle + * injection tasks + */ + hrtimer_init(&idle_cdev->timer, + CLOCK_MONOTONIC, HRTIMER_MODE_REL); + + /* + * The wakeup function callback which is in + * charge of waking up all CPUs belonging to + * the same cluster + */ + idle_cdev->timer.function = cpuidle_cooling_wakeup_fn; + + /* + * The thermal cooling device name + */ + snprintf(dev_name, sizeof(dev_name), "thermal-idle-%d", index++); + cdev = thermal_of_cooling_device_register(np, dev_name, + idle_cdev, + &cpuidle_cooling_ops); + if (IS_ERR(cdev)) { + ret = PTR_ERR(cdev); + goto out_fail; + } + + idle_cdev->cdev = cdev; + + idle_cdev->cpumask = cpumask; + + list_add(&idle_cdev->node, &cpuidle_cdev_list); + + pr_info("Created idle cooling device for cpus '%*pbl'\n", + cpumask_pr_args(cpumask)); + } + + kref_get(&idle_cdev->kref); + + init_waitqueue_head(&cct->waitq); + + tsk = kthread_create_on_cpu(cpuidle_cooling_injection_thread, + idle_cdev, cpu, "kidle_inject/%u"); + if (IS_ERR(tsk)) { + ret = PTR_ERR(tsk); + goto out_fail; + } + + cct->tsk = tsk; + + wake_up_process(tsk); + } + + return 0; + +out_fail: + cpuidle_cooling_unregister(); + pr_err("Failed to create idle cooling device (%d)\n", ret); + + return ret; +} +#endif /* CONFIG_CPU_IDLE_THERMAL */ diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h index c0accc7..fee2038 100644 --- a/include/linux/cpu_cooling.h +++ b/include/linux/cpu_cooling.h @@ -120,4 +120,13 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) } #endif /* CONFIG_CPU_FREQ_THERMAL */ +#ifdef CONFIG_CPU_IDLE_THERMAL +extern int cpuidle_cooling_register(void); +#else /* CONFIG_CPU_IDLE_THERMAL */ +static inline int cpuidle_cooling_register(void) +{ + return 0; +} +#endif /* CONFIG_CPU_IDLE_THERMAL */ + #endif /* __CPU_COOLING_H__ */