From patchwork Tue Apr 24 09:39:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 134060 Delivered-To: patch@linaro.org Received: by 10.46.151.6 with SMTP id r6csp2011132lji; Tue, 24 Apr 2018 02:40:02 -0700 (PDT) X-Google-Smtp-Source: AIpwx4+0IOh6lM6b9X/L/0+QaLxj8V23NsLfAQ3gIUrZNFT+ilq8UZBgzeNBUun6wdZwzdsvN6gp X-Received: by 10.101.102.143 with SMTP id b15mr19189718pgw.183.1524562801907; Tue, 24 Apr 2018 02:40:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524562801; cv=none; d=google.com; s=arc-20160816; b=My0r/gIYcndeVjTYiEt/Dn4OzumXxXL04aEVxInp7mQpBX9rnvfOGGiYIdFegIfua6 QdqeG32J32y12yUk/QFxNoSenECCZKlmvdzshN24fgaBnksyJxWrz3xch/zgo/FslvJi 4ymbVHLLqeW3xgCO4bklcQa8lnPXyHXyDwfAs9uRmO5RANsmF5f4HHFBBXxCmj/yd9M1 CM6VZDRyuNYb96Ot1bLcQ1NA9huSXXvR/hBqw+oD8wlFoDArddd78Yjnki76ZNg/iqAt mOa/E99bUeAEkzekO0JQPWr7KFjmlsoMrsSHpg8yTrWgGN1b0kq9io/YJltMoYrmoK3V rjkw== 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:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature :arc-authentication-results; bh=pFjwJAvEkaGMhSBRU2A6wkAG/nsTdz/Y7VYE8+1+HIE=; b=bGZmkCmF3uu6lG/06ycqgpZx1vwgOf320hkC7MoM4b8lzMah1CGus/D57e1Oic8Cak sSSkBNG0Oktqfh6CH07WZj82qr6JRbQIUNFqE6I5uxLj7HbGqwNx1vDWC1uWqBkU8tlN cRrITOc0iCvGUowNu4Wyq2wGb+HqldNSRloihv/04F/i5Z9FKg+nsZKOqTAopkHPoq61 tLNpmvycDjzWUfQ4Zfh8ifDUdE/OfnCUomjbdnj3HphPXWZQvbBhZKA+ySUyYWwt/fmi 1QNph9xEMgGButEf0xLs6Md3HzWXYivom11frpRsizVYL85tH+A4/Ofi8naOpXCkLyUV syzw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=IDVe8PXR; 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 m18si11109785pgu.352.2018.04.24.02.40.01; Tue, 24 Apr 2018 02:40:01 -0700 (PDT) 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=IDVe8PXR; 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 S1751440AbeDXJkB (ORCPT + 11 others); Tue, 24 Apr 2018 05:40:01 -0400 Received: from mail-pg0-f67.google.com ([74.125.83.67]:40964 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753088AbeDXJj7 (ORCPT ); Tue, 24 Apr 2018 05:39:59 -0400 Received: by mail-pg0-f67.google.com with SMTP id m21so7451098pgv.8 for ; Tue, 24 Apr 2018 02:39:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=pFjwJAvEkaGMhSBRU2A6wkAG/nsTdz/Y7VYE8+1+HIE=; b=IDVe8PXR1409UfzXnWInnrvHCLnsr2q6ppl/IhfwVsAZhaLrIL+lT+415d5ob8d5vS 5/7pE2n63ODLfQfovqKrVsCwez7RLkciK1WbE1HZk18hWBXTtaFXdPnJdkPw2DosjRwP lN4Rxm4m/nAkO8iq61GkBGkhxpVaRvQA908bQ= 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=pFjwJAvEkaGMhSBRU2A6wkAG/nsTdz/Y7VYE8+1+HIE=; b=LiPKJZDy9ShLo2A1fGyTMqAqfCLlpU60P+EgvJ1Wf/n97c7G+h9KEYXaAi2vhOM359 La9lyVxbyWgnT8cr6/kVQroGapfFd47NsDj6SVd7IbqXYLsS5Bz4mouKciJuqiRIjp1z GMx4S3LJYmPKqiYfAtQEBL1GTluoRAdqNFC+Mjlx3MoY7LpFO+jobsOW28LsiYd2iPaB nWoRi27qaC5mrEvN0oaLQP1JseHPEWE5nT+tcopyb3r2+alOqshw2kdxdadxfg6+2B9h PPOcn14DY/xBJQcfTxgCUxOhTjSuv+E5pC8LKn9dnDFVIFlt9MoWlLKWbd5uZzf+4SQz 4xGA== X-Gm-Message-State: ALQs6tDp1irFv2OlhBD6moMdFLRrmNiknBbFXh0p2KgtoKWsWXLlyNwT JUk3E1rplMBFsJhyOhu+B3Xw+Q== X-Received: by 10.101.100.132 with SMTP id e4mr14581844pgv.102.1524562798760; Tue, 24 Apr 2018 02:39:58 -0700 (PDT) Received: from localhost ([122.172.61.40]) by smtp.gmail.com with ESMTPSA id l129sm21884767pgl.89.2018.04.24.02.39.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Apr 2018 02:39:58 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , Miquel Raynal , Jason Cooper , Andrew Lunn , Gregory Clement , Sebastian Hesselbarth Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , linux-arm-kernel@lists.infradead.org Subject: [PATCH V3 3/3] cpufreq: add suspend/resume support in Armada 37xx DVFS driver Date: Tue, 24 Apr 2018 15:09:47 +0530 Message-Id: X-Mailer: git-send-email 2.15.0.194.g9af6a3dea062 In-Reply-To: References: In-Reply-To: References: Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org From: Miquel Raynal Add suspend/resume hooks in Armada 37xx DVFS driver to handle S2RAM operations. As there is currently no 'driver' structure, create one to store both the regmap and the register values during suspend operation. Signed-off-by: Miquel Raynal Signed-off-by: Viresh Kumar --- drivers/cpufreq/armada-37xx-cpufreq.c | 67 +++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) -- 2.15.0.194.g9af6a3dea062 diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c index 1d5db6f6ace9..5b808882ac8b 100644 --- a/drivers/cpufreq/armada-37xx-cpufreq.c +++ b/drivers/cpufreq/armada-37xx-cpufreq.c @@ -23,6 +23,8 @@ #include #include +#include "cpufreq-dt.h" + /* Power management in North Bridge register set */ #define ARMADA_37XX_NB_L0L1 0x18 #define ARMADA_37XX_NB_L2L3 0x1C @@ -56,6 +58,16 @@ */ #define LOAD_LEVEL_NR 4 +struct armada37xx_cpufreq_state { + struct regmap *regmap; + u32 nb_l0l1; + u32 nb_l2l3; + u32 nb_dyn_mod; + u32 nb_cpu_load; +}; + +static struct armada37xx_cpufreq_state *armada37xx_cpufreq_state; + struct armada_37xx_dvfs { u32 cpu_freq_max; u8 divider[LOAD_LEVEL_NR]; @@ -136,7 +148,7 @@ static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base, clk_set_parent(clk, parent); } -static void __init armada37xx_cpufreq_disable_dvfs(struct regmap *base) +static void armada37xx_cpufreq_disable_dvfs(struct regmap *base) { unsigned int reg = ARMADA_37XX_NB_DYN_MOD, mask = ARMADA_37XX_NB_DFS_EN; @@ -162,8 +174,44 @@ static void __init armada37xx_cpufreq_enable_dvfs(struct regmap *base) regmap_update_bits(base, reg, mask, mask); } +static int armada37xx_cpufreq_suspend(struct cpufreq_policy *policy) +{ + struct armada37xx_cpufreq_state *state = armada37xx_cpufreq_state; + + regmap_read(state->regmap, ARMADA_37XX_NB_L0L1, &state->nb_l0l1); + regmap_read(state->regmap, ARMADA_37XX_NB_L2L3, &state->nb_l2l3); + regmap_read(state->regmap, ARMADA_37XX_NB_CPU_LOAD, + &state->nb_cpu_load); + regmap_read(state->regmap, ARMADA_37XX_NB_DYN_MOD, &state->nb_dyn_mod); + + return 0; +} + +static int armada37xx_cpufreq_resume(struct cpufreq_policy *policy) +{ + struct armada37xx_cpufreq_state *state = armada37xx_cpufreq_state; + + /* Ensure DVFS is disabled otherwise the following registers are RO */ + armada37xx_cpufreq_disable_dvfs(state->regmap); + + regmap_write(state->regmap, ARMADA_37XX_NB_L0L1, state->nb_l0l1); + regmap_write(state->regmap, ARMADA_37XX_NB_L2L3, state->nb_l2l3); + regmap_write(state->regmap, ARMADA_37XX_NB_CPU_LOAD, + state->nb_cpu_load); + + /* + * NB_DYN_MOD register is the one that actually enable back DVFS if it + * was enabled before the suspend operation. This must be done last + * otherwise other registers are not writable. + */ + regmap_write(state->regmap, ARMADA_37XX_NB_DYN_MOD, state->nb_dyn_mod); + + return 0; +} + static int __init armada37xx_cpufreq_driver_init(void) { + struct cpufreq_dt_platform_data pdata; struct armada_37xx_dvfs *dvfs; struct platform_device *pdev; unsigned long freq; @@ -213,6 +261,15 @@ static int __init armada37xx_cpufreq_driver_init(void) return -EINVAL; } + armada37xx_cpufreq_state = kmalloc(sizeof(*armada37xx_cpufreq_state), + GFP_KERNEL); + if (!armada37xx_cpufreq_state) { + ret = -ENOMEM; + goto put_clk; + } + + armada37xx_cpufreq_state->regmap = nb_pm_base; + armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider); clk_put(clk); @@ -228,7 +285,11 @@ static int __init armada37xx_cpufreq_driver_init(void) /* Now that everything is setup, enable the DVFS at hardware level */ armada37xx_cpufreq_enable_dvfs(nb_pm_base); - pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0); + pdata.suspend = armada37xx_cpufreq_suspend; + pdata.resume = armada37xx_cpufreq_resume; + + pdev = platform_device_register_data(NULL, "cpufreq-dt", -1, &pdata, + sizeof(pdata)); ret = PTR_ERR_OR_ZERO(pdev); if (ret) goto disable_dvfs; @@ -244,6 +305,8 @@ static int __init armada37xx_cpufreq_driver_init(void) dev_pm_opp_remove(cpu_dev, freq); } + kfree(armada37xx_cpufreq_state); + return ret; } /* late_initcall, to guarantee the driver is loaded after A37xx clock driver */