From patchwork Fri Jan 22 08:40:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "pi-cheng.chen" X-Patchwork-Id: 8088441 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 3588F9F1CC for ; Fri, 22 Jan 2016 08:44:28 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 450A920457 for ; Fri, 22 Jan 2016 08:44:27 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4C05A202B8 for ; Fri, 22 Jan 2016 08:44:26 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aMXJA-0000Ww-BY; Fri, 22 Jan 2016 08:43:04 +0000 Received: from mail-pf0-x232.google.com ([2607:f8b0:400e:c00::232]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aMXHb-0007hy-V5 for linux-arm-kernel@lists.infradead.org; Fri, 22 Jan 2016 08:41:35 +0000 Received: by mail-pf0-x232.google.com with SMTP id e65so38753948pfe.0 for ; Fri, 22 Jan 2016 00:41:07 -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=P9W0mI7xYnBvzFRyZbemoTk/3COx/YcNQSujVEG5AEY=; b=hiv6EnU1M3lg/xBmiGWKzsan45dPKx3JC/RgNH6nGs8WPVMxTLHlzlfGbW7sOsSEgG pVlnLf/saOpXfT64VezH4aWwUkCY9PdRuANJWW+8RJv44Lbtab5sxUj8oeMrFMmSnnEo oWmb4/nZ+q5lRRjPrjOhtghV5MZVEEe4CnGHA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=P9W0mI7xYnBvzFRyZbemoTk/3COx/YcNQSujVEG5AEY=; b=jLBrlKRgC0HrF+X1HYcBj+TJdbhaAZfZB8QVL5W6X047++Sdk5VhlBVZhUB9yDpFNW jJ2EYkouSdwPigu4qZeq4JOcUdlP6LT5mkA+6W1G0vTprrZQAxBDb1zDFNP2M7GjK6Ar +dbUL9ai2dx4EyDmABB5tLoDMLoHEaa2tzjq0+OonH56bzi4opG+iie999sGnXZjw66y hyUW8/P4X/Knj6GP+uI7Ci/ew7F+TB0NVnlHjvOec0vLajkhRcUuC5AKKZ1zfL9Dphi5 B3FgA2edFFeqhOenz8dq76gP2TTH33BNHzpjdMCXMiFGOUDVEUU/80Dz6PLHe9hiybYc UDBw== X-Gm-Message-State: AG10YOTUa75wHj3IECO8PiPGYCf9uhoQ0wHDd9OrUYVeHLgvHcJQ0XVfkGsTZY7S1dw88D7G X-Received: by 10.98.10.81 with SMTP id s78mr2650232pfi.119.1453452067268; Fri, 22 Jan 2016 00:41:07 -0800 (PST) Received: from localhost.localdomain ([124.219.30.17]) by smtp.googlemail.com with ESMTPSA id ty5sm7761114pac.48.2016.01.22.00.41.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 22 Jan 2016 00:41:06 -0800 (PST) From: Pi-Cheng Chen To: Nishanth Menon , Eduardo Valentin , Viresh Kumar , Rob Herring , Sascha Hauer Subject: [PATCH 5/5] cpufreq: mt8173: Add notifier to handle OPP voltage adjustment Date: Fri, 22 Jan 2016 16:40:29 +0800 Message-Id: <1453452029-20843-6-git-send-email-pi-cheng.chen@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1453452029-20843-1-git-send-email-pi-cheng.chen@linaro.org> References: <1453452029-20843-1-git-send-email-pi-cheng.chen@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160122_004128_252928_628A3A75 X-CRM114-Status: GOOD ( 16.69 ) X-Spam-Score: -2.7 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-pm@vger.kernel.org, Kevin Hilman , Stephen Boyd , linux-mediatek@lists.infradead.org, Matthias Brugger , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a notifier to receive OPP voltage adjustment event which is triggered by voltage change of OPP entries done by Mediatek SVS (Smart Voltage Scaling) engine. CC: Stephen Boyd Signed-off-by: Pi-Cheng Chen --- This patch is modify from the patch which adds[1] a notifier in cpufreq-dt to handle OPP voltage adjust event. This patch relies on the on the runtime voltage adjustment mechanism of OPP introduced in the same patchset. [1] https://lkml.org/lkml/2015/9/18/833 --- drivers/cpufreq/mt8173-cpufreq.c | 55 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/drivers/cpufreq/mt8173-cpufreq.c b/drivers/cpufreq/mt8173-cpufreq.c index 1ede917..248f6e8 100644 --- a/drivers/cpufreq/mt8173-cpufreq.c +++ b/drivers/cpufreq/mt8173-cpufreq.c @@ -48,8 +48,11 @@ struct mtk_cpu_dvfs_info { struct clk *cpu_clk; struct clk *inter_clk; struct thermal_cooling_device *cdev; + struct mutex lock; + struct notifier_block opp_nb; struct list_head list_head; int intermediate_voltage; + unsigned long opp_freq; bool need_voltage_tracking; }; @@ -211,6 +214,33 @@ static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc) vproc + VOLT_TOL); } +static int mtk_cpufreq_opp_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct dev_pm_opp *opp = data; + struct mtk_cpu_dvfs_info *info = container_of(nb, + struct mtk_cpu_dvfs_info, + opp_nb); + unsigned long freq, volt; + int ret = 0; + + if (event == OPP_EVENT_ADJUST_VOLTAGE) { + freq = dev_pm_opp_get_freq(opp); + + if (info->opp_freq == freq) { + volt = dev_pm_opp_get_voltage(opp); + mutex_lock(&info->lock); + ret = mtk_cpufreq_set_voltage(info, volt); + mutex_unlock(&info->lock); + if (ret) + dev_err(info->cpu_dev, + "failed to scale voltage: %d\n", ret); + } + } + + return notifier_from_errno(ret); +} + static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index) { @@ -245,6 +275,8 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, vproc = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); + mutex_lock(&info->lock); + /* * If the new voltage or the intermediate voltage is higher than the * current voltage, scale up voltage first. @@ -256,6 +288,7 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, pr_err("cpu%d: failed to scale up voltage!\n", policy->cpu); mtk_cpufreq_set_voltage(info, old_vproc); + mutex_unlock(&info->lock); return ret; } } @@ -267,6 +300,7 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, policy->cpu); mtk_cpufreq_set_voltage(info, old_vproc); WARN_ON(1); + mutex_unlock(&info->lock); return ret; } @@ -277,6 +311,7 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, policy->cpu); clk_set_parent(cpu_clk, armpll); mtk_cpufreq_set_voltage(info, old_vproc); + mutex_unlock(&info->lock); return ret; } @@ -287,6 +322,7 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, policy->cpu); mtk_cpufreq_set_voltage(info, inter_vproc); WARN_ON(1); + mutex_unlock(&info->lock); return ret; } @@ -302,10 +338,14 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, clk_set_parent(cpu_clk, info->inter_clk); clk_set_rate(armpll, old_freq_hz); clk_set_parent(cpu_clk, armpll); + mutex_unlock(&info->lock); return ret; } } + info->opp_freq = freq_hz; + mutex_unlock(&info->lock); + return 0; } @@ -343,6 +383,7 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) struct dev_pm_opp *opp; unsigned long rate; int ret; + struct srcu_notifier_head *opp_srcu_head; cpu_dev = get_cpu_device(cpu); if (!cpu_dev) { @@ -417,11 +458,25 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) info->intermediate_voltage = dev_pm_opp_get_voltage(opp); rcu_read_unlock(); + opp_srcu_head = dev_pm_opp_get_notifier(cpu_dev); + if (IS_ERR(opp_srcu_head)) { + ret = PTR_ERR(opp_srcu_head); + goto out_free_opp_table; + } + + info->opp_nb.notifier_call = mtk_cpufreq_opp_notifier; + ret = srcu_notifier_chain_register(opp_srcu_head, &info->opp_nb); + if (ret) + goto out_free_opp_table; + info->cpu_dev = cpu_dev; info->proc_reg = proc_reg; info->sram_reg = IS_ERR(sram_reg) ? NULL : sram_reg; info->cpu_clk = cpu_clk; info->inter_clk = inter_clk; + info->opp_freq = clk_get_rate(cpu_clk); + + mutex_init(&info->lock); /* * If SRAM regulator is present, software "voltage tracking" is needed