|
@@ -51,7 +51,7 @@ Signed-off-by: Christian Marangi <[email protected]>
|
|
|
obj-$(CONFIG_PM_DEVFREQ_EVENT) += event/
|
|
|
--- /dev/null
|
|
|
+++ b/drivers/devfreq/krait-cache-devfreq.c
|
|
|
-@@ -0,0 +1,188 @@
|
|
|
+@@ -0,0 +1,181 @@
|
|
|
+// SPDX-License-Identifier: GPL-2.0
|
|
|
+
|
|
|
+#include <linux/kernel.h>
|
|
@@ -71,28 +71,25 @@ Signed-off-by: Christian Marangi <[email protected]>
|
|
|
+struct krait_cache_data {
|
|
|
+ struct clk *clk;
|
|
|
+ unsigned long idle_freq;
|
|
|
++ int token;
|
|
|
+};
|
|
|
+
|
|
|
-+static int krait_cache_set_opp(struct dev_pm_set_opp_data *data)
|
|
|
++static int krait_cache_config_clk(struct device *dev, struct opp_table *opp_table,
|
|
|
++ struct dev_pm_opp *old_opp, struct dev_pm_opp *opp,
|
|
|
++ void *data, bool scaling_down)
|
|
|
+{
|
|
|
-+ unsigned long old_freq = data->old_opp.rate, freq = data->new_opp.rate;
|
|
|
-+ struct dev_pm_opp_supply *supply = &data->new_opp.supplies[0];
|
|
|
-+ struct regulator *reg = data->regulators[0];
|
|
|
+ struct krait_cache_data *kdata;
|
|
|
-+ struct clk *clk = data->clk;
|
|
|
++ unsigned long old_freq, freq;
|
|
|
+ unsigned long idle_freq;
|
|
|
++ struct clk *clk;
|
|
|
+ int ret;
|
|
|
+
|
|
|
-+ kdata = dev_get_drvdata(data->dev);
|
|
|
++ kdata = dev_get_drvdata(dev);
|
|
|
+ idle_freq = kdata->idle_freq;
|
|
|
++ clk = kdata->clk;
|
|
|
+
|
|
|
-+ if (reg) {
|
|
|
-+ ret = regulator_set_voltage_triplet(reg, supply->u_volt_min,
|
|
|
-+ supply->u_volt,
|
|
|
-+ supply->u_volt_max);
|
|
|
-+ if (ret)
|
|
|
-+ goto exit;
|
|
|
-+ }
|
|
|
++ old_freq = dev_pm_opp_get_freq(old_opp);
|
|
|
++ freq = dev_pm_opp_get_freq(opp);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set to idle bin if switching from normal to high bin
|
|
@@ -104,15 +101,10 @@ Signed-off-by: Christian Marangi <[email protected]>
|
|
|
+ if (likely(freq != idle_freq && old_freq != idle_freq)) {
|
|
|
+ ret = clk_set_rate(clk, idle_freq);
|
|
|
+ if (ret)
|
|
|
-+ goto exit;
|
|
|
++ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
-+ ret = clk_set_rate(clk, freq);
|
|
|
-+ if (ret)
|
|
|
-+ goto exit;
|
|
|
-+
|
|
|
-+exit:
|
|
|
-+ return ret;
|
|
|
++ return clk_set_rate(clk, freq);
|
|
|
+};
|
|
|
+
|
|
|
+static int krait_cache_get_cur_freq(struct device *dev, unsigned long *freq)
|
|
@@ -162,15 +154,13 @@ Signed-off-by: Christian Marangi <[email protected]>
|
|
|
+
|
|
|
+static int krait_cache_probe(struct platform_device *pdev)
|
|
|
+{
|
|
|
++ struct dev_pm_opp_config config = { };
|
|
|
+ struct device *dev = &pdev->dev;
|
|
|
+ struct krait_cache_data *data;
|
|
|
-+ struct opp_table *table;
|
|
|
+ struct devfreq *devfreq;
|
|
|
+ struct dev_pm_opp *opp;
|
|
|
+ struct clk *clk;
|
|
|
-+ int ret;
|
|
|
-+
|
|
|
-+ krait_cache_devfreq_profile.freq_table = NULL;
|
|
|
++ int ret, token;
|
|
|
+
|
|
|
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
|
|
+ if (!data)
|
|
@@ -180,44 +170,47 @@ Signed-off-by: Christian Marangi <[email protected]>
|
|
|
+ if (IS_ERR(clk))
|
|
|
+ return PTR_ERR(clk);
|
|
|
+
|
|
|
-+ table = dev_pm_opp_set_regulators(dev, (const char *[]){ "l2" }, 1);
|
|
|
-+ if (IS_ERR(table)) {
|
|
|
-+ ret = PTR_ERR(table);
|
|
|
-+ dev_err_probe(dev, -EPROBE_DEFER, "failed to set regulators %d\n", ret);
|
|
|
-+ return ret;
|
|
|
-+ }
|
|
|
++ config.regulator_names = (const char *[]){ "l2", NULL };
|
|
|
++ config.clk_names = (const char *[]){ "l2", NULL };
|
|
|
++ config.config_clks = krait_cache_config_clk;
|
|
|
+
|
|
|
-+ ret = PTR_ERR_OR_ZERO(
|
|
|
-+ dev_pm_opp_register_set_opp_helper(dev, krait_cache_set_opp));
|
|
|
-+ if (ret)
|
|
|
-+ return ret;
|
|
|
++ token = dev_pm_opp_set_config(dev, &config);
|
|
|
++ if (token < 0)
|
|
|
++ return token;
|
|
|
+
|
|
|
-+ ret = dev_pm_opp_of_add_table(dev);
|
|
|
-+ if (ret) {
|
|
|
-+ dev_err(dev, "failed to parse L2 freq thresholds\n");
|
|
|
-+ return ret;
|
|
|
-+ }
|
|
|
++ ret = devm_pm_opp_of_add_table(dev);
|
|
|
++ if (ret)
|
|
|
++ goto free_opp;
|
|
|
+
|
|
|
-+ data->clk = clk;
|
|
|
+ opp = dev_pm_opp_find_freq_ceil(dev, &data->idle_freq);
|
|
|
++ if (IS_ERR(opp)) {
|
|
|
++ ret = PTR_ERR(opp);
|
|
|
++ goto free_opp;
|
|
|
++ }
|
|
|
+ dev_pm_opp_put(opp);
|
|
|
+
|
|
|
++ data->token = token;
|
|
|
++ data->clk = clk;
|
|
|
+ dev_set_drvdata(dev, data);
|
|
|
-+
|
|
|
-+ devfreq = devm_devfreq_add_device(&pdev->dev, &krait_cache_devfreq_profile,
|
|
|
++ devfreq = devm_devfreq_add_device(dev, &krait_cache_devfreq_profile,
|
|
|
+ DEVFREQ_GOV_PASSIVE, &devfreq_gov_data);
|
|
|
+ if (IS_ERR(devfreq)) {
|
|
|
-+ dev_pm_opp_remove_table(dev);
|
|
|
-+ dev_pm_opp_put_regulators(table);
|
|
|
-+ dev_pm_opp_unregister_set_opp_helper(table);
|
|
|
++ ret = PTR_ERR(devfreq);
|
|
|
++ goto free_opp;
|
|
|
+ }
|
|
|
+
|
|
|
-+ return PTR_ERR_OR_ZERO(devfreq);
|
|
|
++ return 0;
|
|
|
++
|
|
|
++free_opp:
|
|
|
++ dev_pm_opp_clear_config(token);
|
|
|
++ return ret;
|
|
|
+};
|
|
|
+
|
|
|
+static int krait_cache_remove(struct platform_device *pdev)
|
|
|
+{
|
|
|
-+ dev_pm_opp_remove_table(&pdev->dev);
|
|
|
++ struct krait_cache_data *data = dev_get_drvdata(&pdev->dev);
|
|
|
++
|
|
|
++ dev_pm_opp_clear_config(data->token);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+};
|
|
@@ -238,5 +231,5 @@ Signed-off-by: Christian Marangi <[email protected]>
|
|
|
+module_platform_driver(krait_cache_driver);
|
|
|
+
|
|
|
+MODULE_DESCRIPTION("Krait CPU Cache Scaling driver");
|
|
|
-+MODULE_AUTHOR("Christian 'Ansuel' Marangi <[email protected]>");
|
|
|
++MODULE_AUTHOR("Christian Marangi <[email protected]>");
|
|
|
+MODULE_LICENSE("GPL v2");
|