From patchwork Wed Oct 11 07:24:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 115519 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp438902qgn; Wed, 11 Oct 2017 00:26:29 -0700 (PDT) X-Received: by 10.159.252.201 with SMTP id o9mr14741828pls.135.1507706789093; Wed, 11 Oct 2017 00:26:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507706789; cv=none; d=google.com; s=arc-20160816; b=GFGA7o1Q0xEVT5YS3KPf3gdFBTY8X7dP9jXgx9dTxWYi92y/3a8Z8ujo8UPUlVYVjf koUP0ffzyzOcX4GMXuIc8v439toG/n7iKf2fd4/10PBQlIgEJ+Kr/cpymh9PRdsytjaW 9Bps37MF7LQ0aILa73o9FTUDJ+5Gxds6vFVMf4BmP9fI8+f58AoCWX/rwDR9FRuOFPSx hUhv1uArMPG5BG54cgoFuVkvDRXfNh2Xo6xLy64t+mohy+oeT5oz8+3rKnkbGvKi6sSi KN1bg0gWbM3vjZdS5X7E3AVFeVYmthSIiQqC6IeQQqLqQVIjVRDCwLgvp/uRLlFVmUnS E7ng== 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=5UNmw5XhWc4sdD6s9fZ/RUhfQt6/3++VRNGKkxIUVoc=; b=nE3WjYXiDHGk1s4pdoP3USL9+4K74JjjDxBYgtf6/sXegMiIsBkTjpPJ41j1DCXlG/ UWrotCcq18mjiG3IsuqOYS7ddE+4OxmW2kMFrad5wSHSiHaLHYw3+KF4StE/Xp5ibLJa bAbRdoLb1G3ddUdN0dlZ0U8nr1ToYAx/TvHIe79CviLOgCjofD4kr3xNyAZwl3GrYBOo faJ0UOJh7DvELSDzuq1j74zP+3IcNGhTY5D4QQlpTkRllbtuhb0fzFy5tPAJXhF420mv ZjZC2bB96oamykHvisLP2RfuczZ0NYt0n2PE+hPwFut0rOnLl+zWbTyCLGvQV+8TsozZ qiVA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Qpl5ObWg; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 9si9600295ple.543.2017.10.11.00.26.28; Wed, 11 Oct 2017 00:26:29 -0700 (PDT) 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 header.s=google header.b=Qpl5ObWg; 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 S932644AbdJKH01 (ORCPT + 26 others); Wed, 11 Oct 2017 03:26:27 -0400 Received: from mail-pg0-f42.google.com ([74.125.83.42]:57007 "EHLO mail-pg0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756767AbdJKHYx (ORCPT ); Wed, 11 Oct 2017 03:24:53 -0400 Received: by mail-pg0-f42.google.com with SMTP id m18so554485pgd.13 for ; Wed, 11 Oct 2017 00:24:53 -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=5UNmw5XhWc4sdD6s9fZ/RUhfQt6/3++VRNGKkxIUVoc=; b=Qpl5ObWguh6N0sT4m8FlcN8e/XDMqbYFaixIe83hE8mwFGdX1O6VLymMTffKjM6Ir4 L40Z+3z6PcT/jb6jCybiThGgqppFL7PTPY+jz3J9UQGPqoZ2QGgllI18pqhS811614rM aPmOqHQNDPHIoUebw4b1QePM0UeydmD+r2Y/s= 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=5UNmw5XhWc4sdD6s9fZ/RUhfQt6/3++VRNGKkxIUVoc=; b=H2GRg3OMeN+o06XkBJLZghq2Na+px8h3FxQKGXTynCobgGJvXqXhoLBYVlBIvZdt85 zMp79tfgzcMatwOUMi+HGSK4WHQilS/LMtcATkHF7FLB+DtDsOTpMD0BP2Vbpi5qN4GV YCyVEmVFxtApVcB8+5RZLnzce7tFgPcDI3G2fMDfAz7oxDLLkQszdweYAB+o+Nq/sr2a Y8SEVFqknv6fL5oTMu8wc0ESpns0fXDNXJJEGUpxHWI7C0T++Xl601cFk01V0ta41GjO V+w5OyLgVThCv7la+Rz3s+ueWRtdzfYw1Squ2JVulwiTS7vv9p7dMG+XmatI03POMQWB eIdw== X-Gm-Message-State: AMCzsaW27q+iR26lZOJgSg8Vu6IwudFq66txEV/RcldRt9gK4vkhYh+b 70Wopv9vf11Mk+1xzhc+Dd5Bsg== X-Google-Smtp-Source: AOwi7QADSLDeXL+6a+jmeLGsIZeQ9CrireRUC7sbQNx1Fm+bMEUO1djJ+9J5tlbaLN73Y3ILXEmapQ== X-Received: by 10.84.231.133 with SMTP id g5mr14142645plk.188.1507706692566; Wed, 11 Oct 2017 00:24:52 -0700 (PDT) Received: from localhost ([122.172.169.205]) by smtp.gmail.com with ESMTPSA id a7sm5384108pgt.39.2017.10.11.00.24.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Oct 2017 00:24:52 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Stephen Boyd Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, sudeep.holla@arm.com, linux-kernel@vger.kernel.org, Len Brown , Pavel Machek , Andy Gross , David Brown Subject: [PATCH V11 2/7] OPP: Support updating performance state of device's power domain Date: Wed, 11 Oct 2017 12:54:14 +0530 Message-Id: <7a774b46d24856d6899f507e7d41fa0f7cace336.1507703370.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.15.0.rc1.236.g92ea95045093 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 The genpd framework now provides an API to request device's power domain to update its performance state. Use that interface from the OPP core for devices whose power domains support performance states. Note that this commit doesn't add any mechanism by which performance states are made available to the OPP core. That would be done by a later commit. Note that the current implementation is restricted to the case where the device doesn't have separate regulators for itself. We shouldn't over engineer the code before we have real use case for them. We can always come back and add more code to support such cases later on. Tested-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- drivers/opp/core.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++- drivers/opp/debugfs.c | 3 +++ drivers/opp/opp.h | 4 ++++ 3 files changed, 63 insertions(+), 1 deletion(-) -- 2.7.4 diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 80c21207e48c..0ce8069d6843 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "opp.h" @@ -535,6 +536,44 @@ _generic_set_opp_clk_only(struct device *dev, struct clk *clk, return ret; } +static inline int +_generic_set_opp_domain(struct device *dev, struct clk *clk, + unsigned long old_freq, unsigned long freq, + unsigned int old_pstate, unsigned int new_pstate) +{ + int ret; + + /* Scaling up? Scale domain performance state before frequency */ + if (freq > old_freq) { + ret = dev_pm_genpd_set_performance_state(dev, new_pstate); + if (ret) + return ret; + } + + ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); + if (ret) + goto restore_domain_state; + + /* Scaling down? Scale domain performance state after frequency */ + if (freq < old_freq) { + ret = dev_pm_genpd_set_performance_state(dev, new_pstate); + if (ret) + goto restore_freq; + } + + return 0; + +restore_freq: + if (_generic_set_opp_clk_only(dev, clk, freq, old_freq)) + dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n", + __func__, old_freq); +restore_domain_state: + if (freq > old_freq) + dev_pm_genpd_set_performance_state(dev, old_pstate); + + return ret; +} + static int _generic_set_opp_regulator(const struct opp_table *opp_table, struct device *dev, unsigned long old_freq, @@ -653,7 +692,16 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) /* Only frequency scaling */ if (!opp_table->regulators) { - ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); + /* + * We don't support devices with both regulator and + * domain performance-state for now. + */ + if (opp_table->genpd_performance_state) + ret = _generic_set_opp_domain(dev, clk, old_freq, freq, + IS_ERR(old_opp) ? 0 : old_opp->pstate, + opp->pstate); + else + ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); } else if (!opp_table->set_opp) { ret = _generic_set_opp_regulator(opp_table, dev, old_freq, freq, IS_ERR(old_opp) ? NULL : old_opp->supplies, @@ -1706,6 +1754,13 @@ void _dev_pm_opp_remove_table(struct opp_table *opp_table, struct device *dev, if (remove_all || !opp->dynamic) dev_pm_opp_put(opp); } + + /* + * The OPP table is getting removed, drop the performance state + * constraints. + */ + if (opp_table->genpd_performance_state) + dev_pm_genpd_set_performance_state(dev, 0); } else { _remove_opp_dev(_find_opp_dev(dev, opp_table), opp_table); } diff --git a/drivers/opp/debugfs.c b/drivers/opp/debugfs.c index 9318848f3c67..b03c03576a62 100644 --- a/drivers/opp/debugfs.c +++ b/drivers/opp/debugfs.c @@ -99,6 +99,9 @@ int opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table) if (!debugfs_create_bool("suspend", S_IRUGO, d, &opp->suspend)) return -ENOMEM; + if (!debugfs_create_u32("performance_state", S_IRUGO, d, &opp->pstate)) + return -ENOMEM; + if (!debugfs_create_ulong("rate_hz", S_IRUGO, d, &opp->rate)) return -ENOMEM; diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h index 166eef990599..e8f767ab5814 100644 --- a/drivers/opp/opp.h +++ b/drivers/opp/opp.h @@ -58,6 +58,7 @@ extern struct list_head opp_tables; * @dynamic: not-created from static DT entries. * @turbo: true if turbo (boost) OPP * @suspend: true if suspend OPP + * @pstate: Device's power domain's performance state. * @rate: Frequency in hertz * @supplies: Power supplies voltage/current values * @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's @@ -76,6 +77,7 @@ struct dev_pm_opp { bool dynamic; bool turbo; bool suspend; + unsigned int pstate; unsigned long rate; struct dev_pm_opp_supply *supplies; @@ -135,6 +137,7 @@ enum opp_table_access { * @clk: Device's clock handle * @regulators: Supply regulators * @regulator_count: Number of power supply regulators + * @genpd_performance_state: Device's power domain support performance state. * @set_opp: Platform specific set_opp callback * @set_opp_data: Data to be passed to set_opp callback * @dentry: debugfs dentry pointer of the real device directory (not links). @@ -170,6 +173,7 @@ struct opp_table { struct clk *clk; struct regulator **regulators; unsigned int regulator_count; + bool genpd_performance_state; int (*set_opp)(struct dev_pm_set_opp_data *data); struct dev_pm_set_opp_data *set_opp_data; From patchwork Wed Oct 11 07:24:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 115515 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp438002qgn; Wed, 11 Oct 2017 00:25:10 -0700 (PDT) X-Received: by 10.99.96.140 with SMTP id u134mr14567735pgb.191.1507706710224; Wed, 11 Oct 2017 00:25:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507706710; cv=none; d=google.com; s=arc-20160816; b=0cngqVINqAO7AubKsYVz5QLbkccZFTdDcMcNrncwKUXu61jG6rGL43FbRAPor9L3hF 1EU2F7cEACTovsmLnrTrR5Xhx6M1E+2Wu/v7TDCzrPs9s1rcOjTvuQv7dQyY13Pfgmjj NKyPWOLVpPwYNIr6xSzqz2pwW/vvrYVlLkjxVIDAG8t/lzk9pfqNB2bYMqaPusM25xnG /Weq3woVq0kZ+vn2SXn63LC00VGpfWLh3xRaohnUcYCB50Nz9iqmpSzOWanOA43mqcfy CW1C5YH5QHVIt5/qGvGASnPbXqSBL3kbX/sLdWI4mFg6kaX32iI5aAG0EThX5GJbFD93 I8Jg== 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=+f5+QUFkS35RwcgwIT5eMXmRywpl4nq8yoLJDvVqpxE=; b=hnPlCQjSCxTrKCLa1apDurXtf0VtOZQ34rp+y3fv+VfrLGT8UzqbYmu3agJ0p54upX 3KglHuHqu6udJb/lJqSuQ97X/s5ZCkjkC+qMAPpn/BWE0YY50hmWfXY+Z02vJlijo1A6 URU+M2aCOAkucFmtlWDglIuEmOVODtD9KifNlKivvkcgy0CyYy0LWFtSIgQvwOQdPx4A XoX4X5TVRGSbOLMGvImCWQJUueqz8CmA5DIS7BHU45S92Buezw+Wa8A0Qm8dYi87RHt/ RfDZzwMyts6ZE8JlILTEdOsYB5S1bkUaBgaDKw4M5Gt3fRl5MwS9qSWjUwDR1v2JmSx3 5d/Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=HCm7OA/g; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i184si10573120pfc.575.2017.10.11.00.25.10; Wed, 11 Oct 2017 00:25:10 -0700 (PDT) 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 header.s=google header.b=HCm7OA/g; 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 S1757163AbdJKHZG (ORCPT + 26 others); Wed, 11 Oct 2017 03:25:06 -0400 Received: from mail-pf0-f169.google.com ([209.85.192.169]:54537 "EHLO mail-pf0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757030AbdJKHZD (ORCPT ); Wed, 11 Oct 2017 03:25:03 -0400 Received: by mail-pf0-f169.google.com with SMTP id m28so678060pfi.11 for ; Wed, 11 Oct 2017 00:25:03 -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=+f5+QUFkS35RwcgwIT5eMXmRywpl4nq8yoLJDvVqpxE=; b=HCm7OA/gYp0whS6lFwXeYxdBR7hTbBdGHBmT/cx1C5LPcT/2ryThk2xJ4pqLDdxLen XlnOqOAIbQ7SjFEolUvujWrpbYRDdXhXTeeP4BW48NBaMa040/qsncKA0KFQnJZspH4h rO6qyIub9PvDfqCOTdSZAVPVMbStO18IfSVC0= 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=+f5+QUFkS35RwcgwIT5eMXmRywpl4nq8yoLJDvVqpxE=; b=qUdaY3OSMyXyb0lqNkHMySNi4+Jg1GYPvfL6Vh9KtfdMr1wplbBdMSYJ/FzG8k8PVY oURXOZdwPEZHU30EcpkhG6rslRTMb9tKi4nS407Fgp3Ab5bRg3mH4R1QZ4UWyBu+XDAv UmlINKmexZjbKYYJjAYAbs0hIsrQrBW/Znz5m3tfId01f7OHHgqI/nzQPzEosXw+lPos s1qxNU59CfOmNQNSWuUB8s4IlfbtbppvRWuGMuGGXL7Jk9weK37jAidSALLQNk7YIiP/ VqX6qBmd7xxzLRTKFyw3FA0ySB7PC2sDsm0KcCpu9mFRDrfBiokR1v7WFFXe2aQVJmcw 5Q7w== X-Gm-Message-State: AMCzsaUnIRXJqF9hIKDc1Nma3SWb0TbRce541oSwkvFj1LLLxicje3w4 wQRFvpXoEOa2a3QFk2DsPEAJgg== X-Google-Smtp-Source: AOwi7QBZDVdpjqlFdMhF/1luF1LQleByF3xsoCla7LLkm2++fJMRm5SoD/112IG++QsYkjuAiSCBnw== X-Received: by 10.159.211.4 with SMTP id bc4mr7152218plb.160.1507706702926; Wed, 11 Oct 2017 00:25:02 -0700 (PDT) Received: from localhost ([122.172.169.205]) by smtp.gmail.com with ESMTPSA id n19sm22964629pfj.52.2017.10.11.00.25.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Oct 2017 00:25:02 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , ulf.hansson@linaro.org, Kevin Hilman , Stephen Boyd Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , Nishanth Menon , robh+dt@kernel.org, lina.iyer@linaro.org, rnayak@codeaurora.org, sudeep.holla@arm.com, linux-kernel@vger.kernel.org, Len Brown , Pavel Machek , Andy Gross , David Brown Subject: [PATCH V11 6/7] OPP: qcom: Add support to get performance states corresponding to OPPs Date: Wed, 11 Oct 2017 12:54:18 +0530 Message-Id: <18686bc52546e9d73e5a08d6875dd80828cdd95e.1507703370.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.15.0.rc1.236.g92ea95045093 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 NOT FOR MERGE. The OPP core needs to know the performance state for each OPP that the device supports, if we want to update performance states of the device's PM domain. Add support for Qualcomm's rpmpd for the same. Signed-off-by: Rajendra Nayak Signed-off-by: Viresh Kumar --- drivers/opp/Makefile | 2 + drivers/opp/qcom-rpmpd.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 drivers/opp/qcom-rpmpd.c -- 2.7.4 diff --git a/drivers/opp/Makefile b/drivers/opp/Makefile index e70ceb406fe9..b565031ce10f 100644 --- a/drivers/opp/Makefile +++ b/drivers/opp/Makefile @@ -2,3 +2,5 @@ ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG obj-y += core.o cpu.o obj-$(CONFIG_OF) += of.o obj-$(CONFIG_DEBUG_FS) += debugfs.o + +obj-$(CONFIG_QCOM_RPMPD) += qcom-rpmpd.o diff --git a/drivers/opp/qcom-rpmpd.c b/drivers/opp/qcom-rpmpd.c new file mode 100644 index 000000000000..ef301d7003d8 --- /dev/null +++ b/drivers/opp/qcom-rpmpd.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +struct device; + +enum rpmpd_levels { + NONE, + LOWER, /* SVS2 */ + LOW, /* SVS */ + NOMINAL, /* NOMINAL */ + HIGH, /* Turbo */ + MAX_LEVEL, +}; + +struct rpmpd_freq_map { + struct device *dev; + unsigned long freq[MAX_LEVEL]; +}; + +enum msm8996_devices { + SDHCI, +}; + +static struct rpmpd_freq_map msm8996_rpmpd_freq_map[] = { + [SDHCI] = { + .freq[LOWER] = 19200000, + .freq[LOW] = 200000000, + .freq[NOMINAL] = 400000000, + }, +}; + +static int get_pstate(struct device *dev, unsigned long rate) +{ + int i, j; + + for (i = 0; i < ARRAY_SIZE(msm8996_rpmpd_freq_map); i++) { + if (dev != msm8996_rpmpd_freq_map[i].dev) + continue; + + for (j = 0; j < MAX_LEVEL; j++) { + if (msm8996_rpmpd_freq_map[i].freq[j] >= rate) + return j; + } + + return MAX_LEVEL; + } + + /* Bug */ + WARN_ON(1); + + return 0; +} + +static const struct of_device_id devices[] = { + { .compatible = "qcom,sdhci-msm-v4", .data = (void *)SDHCI }, + { } +}; + +static int __init rpmpd_opp_init(void) +{ + struct platform_device *pdev; + struct device_node *np; + int i, index; + + if (!of_machine_is_compatible("qcom,msm8996-mtp")) + return 0; + + for (i = 0; i < ARRAY_SIZE(devices); i++) { + np = of_find_compatible_node(NULL, NULL, devices[i].compatible); + if (!np) + continue; + + pdev = of_find_device_by_node(np); + if (!pdev) + pdev = of_platform_device_create(np, NULL, NULL); + + of_node_put(np); + + if (!pdev) + continue; + + index = (enum msm8996_devices)(devices[i].data); + msm8996_rpmpd_freq_map[index].dev = &pdev->dev; + + dev_pm_opp_register_get_pstate_helper(&pdev->dev, get_pstate); + } + + return 0; +} +subsys_initcall(rpmpd_opp_init);