All of lore.kernel.org
 help / color / mirror / Atom feed
From: Niklas Cassel <niklas.cassel@linaro.org>
To: Andy Gross <agross@kernel.org>, Ilia Lin <ilia.lin@kernel.org>,
	"Rafael J. Wysocki" <rjw@rjwysocki.net>,
	Viresh Kumar <viresh.kumar@linaro.org>
Cc: linux-arm-msm@vger.kernel.org, jorge.ramirez-ortiz@linaro.org,
	sboyd@kernel.org, vireshk@kernel.org, bjorn.andersson@linaro.org,
	ulf.hansson@linaro.org, Niklas Cassel <niklas.cassel@linaro.org>,
	linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 04/13] cpufreq: qcom: Refactor the driver to make it easier to extend
Date: Fri,  5 Jul 2019 11:57:15 +0200	[thread overview]
Message-ID: <20190705095726.21433-5-niklas.cassel@linaro.org> (raw)
In-Reply-To: <20190705095726.21433-1-niklas.cassel@linaro.org>

Refactor the driver to make it easier to extend in a later commit.

Create a driver struct to collect all common resources, in order to make
it easier to free up all common resources.
Create a driver match_data struct to make it easier to extend the driver
with support for new features that might only be supported on certain SoCs.

Co-developed-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
Signed-off-by: Niklas Cassel <niklas.cassel@linaro.org>
---
Changes since RFC:
-Changed type of versions to u32 from u32*.
-Make the driver use a match_data struct, so that different SoC can have
different features.
-Fixed error handling.

 drivers/cpufreq/qcom-cpufreq-nvmem.c | 123 +++++++++++++++++----------
 1 file changed, 79 insertions(+), 44 deletions(-)

diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c
index fad6509eecb5..c0377b0eb2f4 100644
--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
@@ -43,6 +43,20 @@ enum _msm8996_version {
 	NUM_OF_MSM8996_VERSIONS,
 };
 
+struct qcom_cpufreq_drv;
+
+struct qcom_cpufreq_match_data {
+	int (*get_version)(struct device *cpu_dev,
+			   struct nvmem_cell *speedbin_nvmem,
+			   struct qcom_cpufreq_drv *drv);
+};
+
+struct qcom_cpufreq_drv {
+	struct opp_table **opp_tables;
+	u32 versions;
+	const struct qcom_cpufreq_match_data *data;
+};
+
 static struct platform_device *cpufreq_dt_pdev, *cpufreq_pdev;
 
 static enum _msm8996_version qcom_cpufreq_get_msm_id(void)
@@ -76,7 +90,7 @@ static enum _msm8996_version qcom_cpufreq_get_msm_id(void)
 
 static int qcom_cpufreq_kryo_name_version(struct device *cpu_dev,
 					  struct nvmem_cell *speedbin_nvmem,
-					  u32 *versions)
+					  struct qcom_cpufreq_drv *drv)
 {
 	size_t len;
 	u8 *speedbin;
@@ -94,10 +108,10 @@ static int qcom_cpufreq_kryo_name_version(struct device *cpu_dev,
 
 	switch (msm8996_version) {
 	case MSM8996_V3:
-		*versions = 1 << (unsigned int)(*speedbin);
+		drv->versions = 1 << (unsigned int)(*speedbin);
 		break;
 	case MSM8996_SG:
-		*versions = 1 << ((unsigned int)(*speedbin) + 4);
+		drv->versions = 1 << ((unsigned int)(*speedbin) + 4);
 		break;
 	default:
 		BUG();
@@ -108,17 +122,17 @@ static int qcom_cpufreq_kryo_name_version(struct device *cpu_dev,
 	return 0;
 }
 
+static const struct qcom_cpufreq_match_data match_data_kryo = {
+	.get_version = qcom_cpufreq_kryo_name_version,
+};
+
 static int qcom_cpufreq_probe(struct platform_device *pdev)
 {
-	struct opp_table **opp_tables;
-	int (*get_version)(struct device *cpu_dev,
-			   struct nvmem_cell *speedbin_nvmem,
-			   u32 *versions);
+	struct qcom_cpufreq_drv *drv;
 	struct nvmem_cell *speedbin_nvmem;
 	struct device_node *np;
 	struct device *cpu_dev;
 	unsigned cpu;
-	u32 versions;
 	const struct of_device_id *match;
 	int ret;
 
@@ -126,11 +140,6 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
 	if (!cpu_dev)
 		return -ENODEV;
 
-	match = pdev->dev.platform_data;
-	get_version = match->data;
-	if (!get_version)
-		return -ENODEV;
-
 	np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
 	if (!np)
 		return -ENOENT;
@@ -141,23 +150,43 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
 		return -ENOENT;
 	}
 
-	speedbin_nvmem = of_nvmem_cell_get(np, NULL);
-	of_node_put(np);
-	if (IS_ERR(speedbin_nvmem)) {
-		if (PTR_ERR(speedbin_nvmem) != -EPROBE_DEFER)
-			dev_err(cpu_dev, "Could not get nvmem cell: %ld\n",
-				PTR_ERR(speedbin_nvmem));
-		return PTR_ERR(speedbin_nvmem);
+	drv = kzalloc(sizeof(*drv), GFP_KERNEL);
+	if (!drv)
+		return -ENOMEM;
+
+	match = pdev->dev.platform_data;
+	drv->data = match->data;
+	if (!drv->data) {
+		ret = -ENODEV;
+		goto free_drv;
 	}
 
-	ret = get_version(cpu_dev, speedbin_nvmem, &versions);
-	nvmem_cell_put(speedbin_nvmem);
-	if (ret)
-		return ret;
+	if (drv->data->get_version) {
+		speedbin_nvmem = of_nvmem_cell_get(np, NULL);
+		of_node_put(np);
+		if (IS_ERR(speedbin_nvmem)) {
+			if (PTR_ERR(speedbin_nvmem) != -EPROBE_DEFER)
+				dev_err(cpu_dev,
+					"Could not get nvmem cell: %ld\n",
+					PTR_ERR(speedbin_nvmem));
+			ret = PTR_ERR(speedbin_nvmem);
+			goto free_drv;
+		}
 
-	opp_tables = kcalloc(num_possible_cpus(), sizeof(*opp_tables), GFP_KERNEL);
-	if (!opp_tables)
-		return -ENOMEM;
+		ret = drv->data->get_version(cpu_dev, speedbin_nvmem, drv);
+		if (ret) {
+			nvmem_cell_put(speedbin_nvmem);
+			goto free_drv;
+		}
+		nvmem_cell_put(speedbin_nvmem);
+	}
+
+	drv->opp_tables = kcalloc(num_possible_cpus(), sizeof(*drv->opp_tables),
+				  GFP_KERNEL);
+	if (!drv->opp_tables) {
+		ret = -ENOMEM;
+		goto free_drv;
+	}
 
 	for_each_possible_cpu(cpu) {
 		cpu_dev = get_cpu_device(cpu);
@@ -166,19 +195,23 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
 			goto free_opp;
 		}
 
-		opp_tables[cpu] = dev_pm_opp_set_supported_hw(cpu_dev,
-							      &versions, 1);
-		if (IS_ERR(opp_tables[cpu])) {
-			ret = PTR_ERR(opp_tables[cpu]);
-			dev_err(cpu_dev, "Failed to set supported hardware\n");
-			goto free_opp;
+		if (drv->data->get_version) {
+			drv->opp_tables[cpu] =
+				dev_pm_opp_set_supported_hw(cpu_dev,
+							    &drv->versions, 1);
+			if (IS_ERR(drv->opp_tables[cpu])) {
+				ret = PTR_ERR(drv->opp_tables[cpu]);
+				dev_err(cpu_dev,
+					"Failed to set supported hardware\n");
+				goto free_opp;
+			}
 		}
 	}
 
 	cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1,
 							  NULL, 0);
 	if (!IS_ERR(cpufreq_dt_pdev)) {
-		platform_set_drvdata(pdev, opp_tables);
+		platform_set_drvdata(pdev, drv);
 		return 0;
 	}
 
@@ -187,26 +220,30 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
 
 free_opp:
 	for_each_possible_cpu(cpu) {
-		if (IS_ERR_OR_NULL(opp_tables[cpu]))
+		if (IS_ERR_OR_NULL(drv->opp_tables[cpu]))
 			break;
-		dev_pm_opp_put_supported_hw(opp_tables[cpu]);
+		dev_pm_opp_put_supported_hw(drv->opp_tables[cpu]);
 	}
-	kfree(opp_tables);
+	kfree(drv->opp_tables);
+free_drv:
+	kfree(drv);
 
 	return ret;
 }
 
 static int qcom_cpufreq_remove(struct platform_device *pdev)
 {
-	struct opp_table **opp_tables = platform_get_drvdata(pdev);
+	struct qcom_cpufreq_drv *drv = platform_get_drvdata(pdev);
 	unsigned int cpu;
 
 	platform_device_unregister(cpufreq_dt_pdev);
 
 	for_each_possible_cpu(cpu)
-		dev_pm_opp_put_supported_hw(opp_tables[cpu]);
+		if (drv->opp_tables[cpu])
+			dev_pm_opp_put_supported_hw(drv->opp_tables[cpu]);
 
-	kfree(opp_tables);
+	kfree(drv->opp_tables);
+	kfree(drv);
 
 	return 0;
 }
@@ -220,10 +257,8 @@ static struct platform_driver qcom_cpufreq_driver = {
 };
 
 static const struct of_device_id qcom_cpufreq_match_list[] __initconst = {
-	{ .compatible = "qcom,apq8096",
-	  .data = qcom_cpufreq_kryo_name_version },
-	{ .compatible = "qcom,msm8996",
-	  .data = qcom_cpufreq_kryo_name_version },
+	{ .compatible = "qcom,apq8096", .data = &match_data_kryo },
+	{ .compatible = "qcom,msm8996", .data = &match_data_kryo },
 	{},
 };
 
-- 
2.21.0


  parent reply	other threads:[~2019-07-05  9:58 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-05  9:57 [PATCH 00/13] Add support for QCOM Core Power Reduction Niklas Cassel
2019-07-05  9:57 ` Niklas Cassel
2019-07-05  9:57 ` [PATCH 01/13] dt-bindings: cpufreq: Re-organise kryo cpufreq to use it for other nvmem based qcom socs Niklas Cassel
2019-07-08  6:28   ` Ilia Lin
2019-07-24 14:53   ` Rob Herring
2019-07-24 14:53     ` Rob Herring
2019-07-05  9:57 ` [PATCH 02/13] cpufreq: qcom: " Niklas Cassel
2019-07-08  6:27   ` Ilia Lin
2019-07-10  6:18   ` Viresh Kumar
2019-07-16 11:11     ` Niklas Cassel
2019-07-05  9:57 ` [PATCH 03/13] dt-bindings: cpufreq: qcom-nvmem: Make speedbin related properties optional Niklas Cassel
2019-07-08  6:28   ` Ilia Lin
2019-07-24 14:56   ` Rob Herring
2019-07-24 14:56     ` Rob Herring
2019-07-05  9:57 ` Niklas Cassel [this message]
2019-07-08  6:30   ` [PATCH 04/13] cpufreq: qcom: Refactor the driver to make it easier to extend Ilia Lin
2019-07-10  6:30   ` Viresh Kumar
2019-07-16 11:11     ` Niklas Cassel
2019-07-05  9:57 ` [PATCH 05/13] dt-bindings: cpufreq: qcom-nvmem: Support pstates provided by a power domain Niklas Cassel
2019-07-24 15:26   ` Rob Herring
2019-07-05  9:57 ` [PATCH 06/13] cpufreq: qcom: Add support for qcs404 on nvmem driver Niklas Cassel
2019-07-05  9:57 ` [PATCH 07/13] cpufreq: Add qcs404 to cpufreq-dt-platdev blacklist Niklas Cassel
2019-07-05  9:57 ` [PATCH 08/13] dt-bindings: opp: Add qcom-opp bindings with properties needed for CPR Niklas Cassel
2019-07-24 16:03   ` Rob Herring
2019-07-05  9:57 ` [PATCH 09/13] dt-bindings: power: avs: Add support for CPR (Core Power Reduction) Niklas Cassel
2019-07-24 16:06   ` Rob Herring
2019-07-24 16:06     ` Rob Herring
2019-07-05  9:57 ` [PATCH 10/13] " Niklas Cassel
2019-07-05  9:57 ` [PATCH 11/13] arm64: dts: qcom: qcs404: Add CPR and populate OPP table Niklas Cassel
2019-07-10  9:03   ` Viresh Kumar
2019-07-15 13:24     ` Niklas Cassel
2019-07-16 10:34       ` Viresh Kumar
2019-07-16 10:53         ` Niklas Cassel
2019-07-17  4:49           ` Viresh Kumar
2019-07-19 15:45             ` Niklas Cassel
2019-07-23  1:56               ` Viresh Kumar
2019-07-25 10:40                 ` Niklas Cassel
2019-07-05  9:57 ` [PATCH 12/13] arm64: defconfig: enable CONFIG_QCOM_CPR Niklas Cassel
2019-07-05  9:57   ` Niklas Cassel
2019-07-05  9:57 ` [PATCH 13/13] arm64: defconfig: enable CONFIG_ARM_QCOM_CPUFREQ_NVMEM Niklas Cassel
2019-07-05  9:57   ` Niklas Cassel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190705095726.21433-5-niklas.cassel@linaro.org \
    --to=niklas.cassel@linaro.org \
    --cc=agross@kernel.org \
    --cc=bjorn.andersson@linaro.org \
    --cc=ilia.lin@kernel.org \
    --cc=jorge.ramirez-ortiz@linaro.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=rjw@rjwysocki.net \
    --cc=sboyd@kernel.org \
    --cc=ulf.hansson@linaro.org \
    --cc=viresh.kumar@linaro.org \
    --cc=vireshk@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.