diff --git a/drivers/devfreq/arm-memlat-mon.c b/drivers/devfreq/arm-memlat-mon.c index 4c79111cf89d..f1d2f3d38fa9 100644 --- a/drivers/devfreq/arm-memlat-mon.c +++ b/drivers/devfreq/arm-memlat-mon.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "governor.h" #include "governor_memlat.h" #include @@ -252,6 +253,26 @@ static int get_mask_from_dev_handle(struct platform_device *pdev, return ret; } +static struct device_node *parse_child_nodes(struct device *dev) +{ + struct device_node *of_child; + int ddr_type_of = -1; + int ddr_type = of_fdt_get_ddrtype(); + int ret; + + for_each_child_of_node(dev->of_node, of_child) { + ret = of_property_read_u32(of_child, "qcom,ddr-type", + &ddr_type_of); + if (!ret && (ddr_type == ddr_type_of)) { + dev_dbg(dev, + "ddr-type = %d, is matching DT entry\n", + ddr_type_of); + return of_child; + } + } + return NULL; +} + static int arm_memlat_mon_driver_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -297,6 +318,8 @@ static int arm_memlat_mon_driver_probe(struct platform_device *pdev) hw->start_hwmon = &start_hwmon; hw->stop_hwmon = &stop_hwmon; hw->get_cnt = &get_cnt; + if (of_get_child_count(dev->of_node)) + hw->get_child_of_node = &parse_child_nodes; spec = of_device_get_match_data(dev); if (spec && spec->is_compute) { diff --git a/drivers/devfreq/devfreq_icc.c b/drivers/devfreq/devfreq_icc.c index d1f1c396b432..a9888faedacc 100644 --- a/drivers/devfreq/devfreq_icc.c +++ b/drivers/devfreq/devfreq_icc.c @@ -17,7 +17,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -87,6 +89,8 @@ int devfreq_add_icc(struct device *dev) struct devfreq_dev_profile *p; const char *gov_name; int ret; + struct opp_table *opp_table; + u32 version; d = devm_kzalloc(dev, sizeof(*d), GFP_KERNEL); if (!d) @@ -98,6 +102,15 @@ int devfreq_add_icc(struct device *dev) p->target = icc_target; p->get_dev_status = icc_get_dev_status; + if (of_device_is_compatible(dev->of_node, "qcom,devfreq-icc-ddr")) { + version = (1 << of_fdt_get_ddrtype()); + opp_table = dev_pm_opp_set_supported_hw(dev, &version, 1); + if (IS_ERR(opp_table)) { + dev_err(dev, "Failed to set supported hardware\n"); + return PTR_ERR(opp_table); + } + } + ret = dev_pm_opp_of_add_table(dev); if (ret < 0) dev_err(dev, "Couldn't parse OPP table:%d\n", ret); @@ -159,6 +172,8 @@ static int devfreq_icc_remove(struct platform_device *pdev) } static const struct of_device_id devfreq_icc_match_table[] = { + { .compatible = "qcom,devfreq-icc-llcc" }, + { .compatible = "qcom,devfreq-icc-ddr" }, { .compatible = "qcom,devfreq-icc" }, {} }; diff --git a/drivers/devfreq/governor_memlat.c b/drivers/devfreq/governor_memlat.c index 8997d0f11f53..04ff9abdefb9 100644 --- a/drivers/devfreq/governor_memlat.c +++ b/drivers/devfreq/governor_memlat.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include "governor.h" @@ -418,14 +419,18 @@ static struct devfreq_governor devfreq_gov_compute = { #define NUM_COLS 2 static struct core_dev_map *init_core_dev_map(struct device *dev, - char *prop_name) + struct device_node *of_node, + char *prop_name) { int len, nf, i, j; u32 data; struct core_dev_map *tbl; int ret; - if (!of_find_property(dev->of_node, prop_name, &len)) + if (!of_node) + of_node = dev->of_node; + + if (!of_find_property(of_node, prop_name, &len)) return NULL; len /= sizeof(data); @@ -439,13 +444,13 @@ static struct core_dev_map *init_core_dev_map(struct device *dev, return NULL; for (i = 0, j = 0; i < nf; i++, j += 2) { - ret = of_property_read_u32_index(dev->of_node, prop_name, j, + ret = of_property_read_u32_index(of_node, prop_name, j, &data); if (ret < 0) return NULL; tbl[i].core_mhz = data / 1000; - ret = of_property_read_u32_index(dev->of_node, prop_name, j + 1, + ret = of_property_read_u32_index(of_node, prop_name, j + 1, &data); if (ret < 0) return NULL; @@ -462,6 +467,7 @@ static struct memlat_node *register_common(struct device *dev, struct memlat_hwmon *hw) { struct memlat_node *node; + struct device_node *of_child; if (!hw->dev && !hw->of_node) return ERR_PTR(-EINVAL); @@ -473,7 +479,14 @@ static struct memlat_node *register_common(struct device *dev, node->ratio_ceil = 10; node->hw = hw; - hw->freq_map = init_core_dev_map(dev, "qcom,core-dev-table"); + if (hw->get_child_of_node) { + of_child = hw->get_child_of_node(dev); + hw->freq_map = init_core_dev_map(dev, of_child, + "qcom,core-dev-table"); + } else { + hw->freq_map = init_core_dev_map(dev, NULL, + "qcom,core-dev-table"); + } if (!hw->freq_map) { dev_err(dev, "Couldn't find the core-dev freq table!\n"); return ERR_PTR(-EINVAL); diff --git a/drivers/devfreq/governor_memlat.h b/drivers/devfreq/governor_memlat.h index c43edddb2695..b1c334018f16 100644 --- a/drivers/devfreq/governor_memlat.h +++ b/drivers/devfreq/governor_memlat.h @@ -54,6 +54,7 @@ struct memlat_hwmon { int (*start_hwmon)(struct memlat_hwmon *hw); void (*stop_hwmon)(struct memlat_hwmon *hw); unsigned long (*get_cnt)(struct memlat_hwmon *hw); + struct device_node *(*get_child_of_node)(struct device *dev); struct device *dev; struct device_node *of_node;