From e92cf67a4c06990212217d6682c884ecde503e01 Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Fri, 12 Aug 2016 18:25:39 +0800 Subject: [PATCH] PM / devfreq: rockchip: rk3399 dmc get opp table from dts Get opp table from device node for rk3399 dmc table. Change-Id: I689078d60ebdadf0954b60de70d05bc56a8d6597 Signed-off-by: Jianqun Xu --- drivers/devfreq/rk3399_dmc.c | 52 ++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c index b73a73cd2a29..e89098a7463b 100644 --- a/drivers/devfreq/rk3399_dmc.c +++ b/drivers/devfreq/rk3399_dmc.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -348,6 +349,45 @@ err: return timing; } +static int of_get_opp_table(struct device *dev, + struct devfreq_dev_profile *devp) +{ + int count; + int i = 0; + unsigned long freq = 0; + struct dev_pm_opp *opp; + + rcu_read_lock(); + count = dev_pm_opp_get_opp_count(dev); + if (count < 0) { + rcu_read_unlock(); + return count; + } + rcu_read_unlock(); + + devp->freq_table = kmalloc_array(count, sizeof(devp->freq_table[0]), + GFP_KERNEL); + if (!devp->freq_table) + return -ENOMEM; + + rcu_read_lock(); + for (i = 0; i < count; i++, freq++) { + opp = dev_pm_opp_find_freq_ceil(dev, &freq); + if (IS_ERR(opp)) + break; + + devp->freq_table[i] = freq; + } + rcu_read_unlock(); + + if (count != i) + dev_warn(dev, "Unable to enumerate all OPPs (%d!=%d)\n", + count, i); + + devp->max_state = i; + return 0; +} + static int rk3399_dmcfreq_probe(struct platform_device *pdev) { struct arm_smccc_res res; @@ -357,6 +397,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) int ret, irq, index, size; uint32_t *timing; struct dev_pm_opp *opp; + struct devfreq_dev_profile *devp = &rk3399_devfreq_dmc_profile; irq = platform_get_irq(pdev, 0); if (irq < 0) { @@ -437,6 +478,9 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) return -EINVAL; } + if (of_get_opp_table(dev, devp)) + return -EFAULT; + of_property_read_u32(np, "upthreshold", &data->ondemand_data.upthreshold); of_property_read_u32(np, "downdifferential", @@ -451,12 +495,10 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) return PTR_ERR(opp); } rcu_read_unlock(); - data->curr_opp = opp; - rk3399_devfreq_dmc_profile.initial_freq = data->rate; - - data->devfreq = devfreq_add_device(dev, - &rk3399_devfreq_dmc_profile, + data->curr_opp = opp; + devp->initial_freq = data->rate; + data->devfreq = devfreq_add_device(dev, devp, "simple_ondemand", &data->ondemand_data); if (IS_ERR(data->devfreq)) -- 2.34.1