diff --git a/drivers/devfreq/arm-memlat-mon.c b/drivers/devfreq/arm-memlat-mon.c index 4bec02c4b2c9..7eb3ad45e4ce 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_devbw.c b/drivers/devfreq/devfreq_devbw.c index 22c3a13f979f..af8440bc0ba8 100644 --- a/drivers/devfreq/devfreq_devbw.c +++ b/drivers/devfreq/devfreq_devbw.c @@ -17,7 +17,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -101,6 +103,8 @@ int devfreq_add_devbw(struct device *dev) u32 ports[MAX_PATHS * 2]; const char *gov_name; int ret, len, i, num_paths; + struct opp_table *opp_table; + u32 version; d = devm_kzalloc(dev, sizeof(*d), GFP_KERNEL); if (!d) @@ -147,6 +151,15 @@ int devfreq_add_devbw(struct device *dev) p->target = devbw_target; p->get_dev_status = devbw_get_dev_status; + if (of_device_is_compatible(dev->of_node, "qcom,devbw-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) dev_err(dev, "Couldn't parse OPP table:%d\n", ret); @@ -203,6 +216,8 @@ static int devfreq_devbw_remove(struct platform_device *pdev) } static const struct of_device_id devbw_match_table[] = { + { .compatible = "qcom,devbw-llcc" }, + { .compatible = "qcom,devbw-ddr" }, { .compatible = "qcom,devbw" }, {} }; diff --git a/drivers/devfreq/governor_memlat.c b/drivers/devfreq/governor_memlat.c index c279ec824031..ba14cb3fc330 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" @@ -419,14 +420,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); @@ -440,13 +445,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) 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) return NULL; @@ -463,6 +468,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); @@ -474,7 +480,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 c3c71a32c9fe..f09625ef2645 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;