Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b62baa3 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "Revert "PM / devfreq: Modify the device name as devfreq(X) for sysfs""

parents 53a14d0c 90094c0c
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -4,7 +4,7 @@ arm-memlat-mon is a device that represents the use of the PMU in ARM cores
to measure the parameters for latency driven memory access patterns.
to measure the parameters for latency driven memory access patterns.


Required properties:
Required properties:
- compatible:			Must be "qcom,arm-memlat-mon"
- compatible:			Must be "qcom,arm-memlat-mon" or "qcom,arm-cpu-mon"
- qcom,cpulist:			List of CPU phandles to be monitored in a cluster
- qcom,cpulist:			List of CPU phandles to be monitored in a cluster
- qcom,target-dev:		The DT device that corresponds to this master port
- qcom,target-dev:		The DT device that corresponds to this master port
- qcom,core-dev-table:		A mapping table of core frequency to a required bandwidth vote at the
- qcom,core-dev-table:		A mapping table of core frequency to a required bandwidth vote at the
+34 −12
Original line number Original line Diff line number Diff line
@@ -23,6 +23,7 @@
#include "governor.h"
#include "governor.h"
#include "governor_memlat.h"
#include "governor_memlat.h"
#include <linux/perf_event.h>
#include <linux/perf_event.h>
#include <linux/of_device.h>


enum ev_index {
enum ev_index {
	INST_IDX,
	INST_IDX,
@@ -52,6 +53,10 @@ struct cpu_grp_info {
	struct memlat_hwmon hw;
	struct memlat_hwmon hw;
};
};


struct memlat_mon_spec {
	bool is_compute;
};

#define to_cpustats(cpu_grp, cpu) \
#define to_cpustats(cpu_grp, cpu) \
	(&cpu_grp->cpustats[cpu - cpumask_first(&cpu_grp->cpus)])
	(&cpu_grp->cpustats[cpu - cpumask_first(&cpu_grp->cpus)])
#define to_devstats(cpu_grp, cpu) \
#define to_devstats(cpu_grp, cpu) \
@@ -83,6 +88,9 @@ static inline unsigned long read_event(struct event_data *event)
	unsigned long ev_count;
	unsigned long ev_count;
	u64 total, enabled, running;
	u64 total, enabled, running;


	if (!event->pevent)
		return 0;

	total = perf_event_read_value(event->pevent, &enabled, &running);
	total = perf_event_read_value(event->pevent, &enabled, &running);
	ev_count = total - event->prev_count;
	ev_count = total - event->prev_count;
	event->prev_count = total;
	event->prev_count = total;
@@ -249,6 +257,7 @@ static int arm_memlat_mon_driver_probe(struct platform_device *pdev)
	struct device *dev = &pdev->dev;
	struct device *dev = &pdev->dev;
	struct memlat_hwmon *hw;
	struct memlat_hwmon *hw;
	struct cpu_grp_info *cpu_grp;
	struct cpu_grp_info *cpu_grp;
	const struct memlat_mon_spec *spec;
	int cpu, ret;
	int cpu, ret;
	u32 event_id;
	u32 event_id;


@@ -282,6 +291,22 @@ static int arm_memlat_mon_driver_probe(struct platform_device *pdev)


	cpu_grp->event_ids[CYC_IDX] = CYC_EV;
	cpu_grp->event_ids[CYC_IDX] = CYC_EV;


	for_each_cpu(cpu, &cpu_grp->cpus)
		to_devstats(cpu_grp, cpu)->id = cpu;

	hw->start_hwmon = &start_hwmon;
	hw->stop_hwmon = &stop_hwmon;
	hw->get_cnt = &get_cnt;

	spec = of_device_get_match_data(dev);
	if (spec && spec->is_compute) {
		ret = register_compute(dev, hw);
		if (ret)
			pr_err("Compute Gov registration failed\n");

		return ret;
	}

	ret = of_property_read_u32(dev->of_node, "qcom,cachemiss-ev",
	ret = of_property_read_u32(dev->of_node, "qcom,cachemiss-ev",
				   &event_id);
				   &event_id);
	if (ret) {
	if (ret) {
@@ -306,24 +331,21 @@ static int arm_memlat_mon_driver_probe(struct platform_device *pdev)
	else
	else
		cpu_grp->event_ids[STALL_CYC_IDX] = event_id;
		cpu_grp->event_ids[STALL_CYC_IDX] = event_id;


	for_each_cpu(cpu, &cpu_grp->cpus)
		to_devstats(cpu_grp, cpu)->id = cpu;

	hw->start_hwmon = &start_hwmon;
	hw->stop_hwmon = &stop_hwmon;
	hw->get_cnt = &get_cnt;

	ret = register_memlat(dev, hw);
	ret = register_memlat(dev, hw);
	if (ret) {
	if (ret)
		pr_err("Mem Latency Gov registration failed\n");
		pr_err("Mem Latency Gov registration failed\n");

	return ret;
	return ret;
}
}


	return 0;
static const struct memlat_mon_spec spec[] = {
}
	[0] = { false },
	[1] = { true },
};


static const struct of_device_id memlat_match_table[] = {
static const struct of_device_id memlat_match_table[] = {
	{ .compatible = "qcom,arm-memlat-mon" },
	{ .compatible = "qcom,arm-memlat-mon", .data = &spec[0] },
	{ .compatible = "qcom,arm-cpu-mon", .data = &spec[1] },
	{}
	{}
};
};


+17 −1
Original line number Original line Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-License-Identifier: GPL-2.0-only
/*
/*
 * Copyright (c) 2014-2017, 2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2014-2018, 2019, The Linux Foundation. All rights reserved.
 */
 */


#define pr_fmt(fmt) "bimc-bwmon: " fmt
#define pr_fmt(fmt) "bimc-bwmon: " fmt
@@ -168,6 +168,14 @@ void mon_clear(struct bwmon *m, bool clear_all, enum mon_reg_type type)
			writel_relaxed(MON_CLEAR_ALL_BIT, MON3_CLEAR(m));
			writel_relaxed(MON_CLEAR_ALL_BIT, MON3_CLEAR(m));
		else
		else
			writel_relaxed(MON_CLEAR_BIT, MON3_CLEAR(m));
			writel_relaxed(MON_CLEAR_BIT, MON3_CLEAR(m));
		/*
		 * In some hardware versions since MON3_CLEAR(m) register does
		 * not have self-clearing capability it needs to be cleared
		 * explicitly. But we also need to ensure the writes to it
		 * are successful before clearing it.
		 */
		wmb();
		writel_relaxed(0, MON3_CLEAR(m));
		break;
		break;
	}
	}
	/*
	/*
@@ -357,6 +365,14 @@ void mon_irq_clear(struct bwmon *m, enum mon_reg_type type)
		break;
		break;
	case MON3:
	case MON3:
		writel_relaxed(MON3_INT_STATUS_MASK, MON3_INT_CLR(m));
		writel_relaxed(MON3_INT_STATUS_MASK, MON3_INT_CLR(m));
		/*
		 * In some hardware versions since MON3_INT_CLEAR(m) register
		 * does not have self-clearing capability it needs to be
		 * cleared explicitly. But we also need to ensure the writes
		 * to it are successful before clearing it.
		 */
		wmb();
		writel_relaxed(0, MON3_INT_CLR(m));
		break;
		break;
	}
	}
}
}
+1 −3
Original line number Original line Diff line number Diff line
@@ -560,7 +560,6 @@ struct devfreq *devfreq_add_device(struct device *dev,
{
{
	struct devfreq *devfreq;
	struct devfreq *devfreq;
	struct devfreq_governor *governor;
	struct devfreq_governor *governor;
	static atomic_t devfreq_no = ATOMIC_INIT(-1);
	int err = 0;
	int err = 0;


	if (!dev || !profile || !governor_name) {
	if (!dev || !profile || !governor_name) {
@@ -620,8 +619,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
	}
	}
	devfreq->max_freq = devfreq->scaling_max_freq;
	devfreq->max_freq = devfreq->scaling_max_freq;


	dev_set_name(&devfreq->dev, "devfreq%d",
	dev_set_name(&devfreq->dev, "%s", dev_name(dev));
				atomic_inc_return(&devfreq_no));
	err = device_register(&devfreq->dev);
	err = device_register(&devfreq->dev);
	if (err) {
	if (err) {
		mutex_unlock(&devfreq->lock);
		mutex_unlock(&devfreq->lock);
+77 −16
Original line number Original line Diff line number Diff line
@@ -40,7 +40,8 @@ struct memlat_node {
static LIST_HEAD(memlat_list);
static LIST_HEAD(memlat_list);
static DEFINE_MUTEX(list_lock);
static DEFINE_MUTEX(list_lock);


static int use_cnt;
static int memlat_use_cnt;
static int compute_use_cnt;
static DEFINE_MUTEX(state_lock);
static DEFINE_MUTEX(state_lock);


#define show_attr(name) \
#define show_attr(name) \
@@ -232,8 +233,7 @@ static int devfreq_memlat_get_freq(struct devfreq *df,
		if (hw->core_stats[i].mem_count)
		if (hw->core_stats[i].mem_count)
			ratio /= hw->core_stats[i].mem_count;
			ratio /= hw->core_stats[i].mem_count;


		if (!hw->core_stats[i].inst_count
		if (!hw->core_stats[i].freq)
		    || !hw->core_stats[i].freq)
			continue;
			continue;


		trace_memlat_dev_meas(dev_name(df->dev.parent),
		trace_memlat_dev_meas(dev_name(df->dev.parent),
@@ -272,16 +272,26 @@ static int devfreq_memlat_get_freq(struct devfreq *df,
gov_attr(ratio_ceil, 1U, 10000U);
gov_attr(ratio_ceil, 1U, 10000U);
gov_attr(stall_floor, 0U, 100U);
gov_attr(stall_floor, 0U, 100U);


static struct attribute *dev_attr[] = {
static struct attribute *memlat_dev_attr[] = {
	&dev_attr_ratio_ceil.attr,
	&dev_attr_ratio_ceil.attr,
	&dev_attr_stall_floor.attr,
	&dev_attr_stall_floor.attr,
	&dev_attr_freq_map.attr,
	&dev_attr_freq_map.attr,
	NULL,
	NULL,
};
};


static struct attribute_group dev_attr_group = {
static struct attribute *compute_dev_attr[] = {
	&dev_attr_freq_map.attr,
	NULL,
};

static struct attribute_group memlat_dev_attr_group = {
	.name = "mem_latency",
	.name = "mem_latency",
	.attrs = dev_attr,
	.attrs = memlat_dev_attr,
};

static struct attribute_group compute_dev_attr_group = {
	.name = "compute",
	.attrs = compute_dev_attr,
};
};


#define MIN_MS	10U
#define MIN_MS	10U
@@ -330,6 +340,12 @@ static struct devfreq_governor devfreq_gov_memlat = {
	.event_handler = devfreq_memlat_ev_handler,
	.event_handler = devfreq_memlat_ev_handler,
};
};


static struct devfreq_governor devfreq_gov_compute = {
	.name = "compute",
	.get_target_freq = devfreq_memlat_get_freq,
	.event_handler = devfreq_memlat_ev_handler,
};

#define NUM_COLS	2
#define NUM_COLS	2
static struct core_dev_map *init_core_dev_map(struct device *dev,
static struct core_dev_map *init_core_dev_map(struct device *dev,
		char *prop_name)
		char *prop_name)
@@ -372,20 +388,17 @@ static struct core_dev_map *init_core_dev_map(struct device *dev,
	return tbl;
	return tbl;
}
}


int register_memlat(struct device *dev, struct memlat_hwmon *hw)
static struct memlat_node *register_common(struct device *dev,
					   struct memlat_hwmon *hw)
{
{
	int ret = 0;
	struct memlat_node *node;
	struct memlat_node *node;


	if (!hw->dev && !hw->of_node)
	if (!hw->dev && !hw->of_node)
		return -EINVAL;
		return ERR_PTR(-EINVAL);


	node = devm_kzalloc(dev, sizeof(*node), GFP_KERNEL);
	node = devm_kzalloc(dev, sizeof(*node), GFP_KERNEL);
	if (!node)
	if (!node)
		return -ENOMEM;
		return ERR_PTR(-ENOMEM);

	node->gov = &devfreq_gov_memlat;
	node->attr_grp = &dev_attr_group;


	node->ratio_ceil = 10;
	node->ratio_ceil = 10;
	node->hw = hw;
	node->hw = hw;
@@ -393,20 +406,68 @@ int register_memlat(struct device *dev, struct memlat_hwmon *hw)
	hw->freq_map = init_core_dev_map(dev, "qcom,core-dev-table");
	hw->freq_map = init_core_dev_map(dev, "qcom,core-dev-table");
	if (!hw->freq_map) {
	if (!hw->freq_map) {
		dev_err(dev, "Couldn't find the core-dev freq table!\n");
		dev_err(dev, "Couldn't find the core-dev freq table!\n");
		return -EINVAL;
		return ERR_PTR(-EINVAL);
	}
	}


	mutex_lock(&list_lock);
	mutex_lock(&list_lock);
	list_add_tail(&node->list, &memlat_list);
	list_add_tail(&node->list, &memlat_list);
	mutex_unlock(&list_lock);
	mutex_unlock(&list_lock);


	return node;
}

int register_compute(struct device *dev, struct memlat_hwmon *hw)
{
	struct memlat_node *node;
	int ret = 0;

	node = register_common(dev, hw);
	if (IS_ERR(node)) {
		ret = PTR_ERR(node);
		goto out;
	}

	mutex_lock(&state_lock);
	mutex_lock(&state_lock);
	if (!use_cnt)
	node->gov = &devfreq_gov_compute;
	node->attr_grp = &compute_dev_attr_group;

	if (!compute_use_cnt)
		ret = devfreq_add_governor(&devfreq_gov_compute);
	if (!ret)
		compute_use_cnt++;
	mutex_unlock(&state_lock);

out:
	if (!ret)
		dev_info(dev, "Compute governor registered.\n");
	else
		dev_err(dev, "Compute governor registration failed!\n");

	return ret;
}

int register_memlat(struct device *dev, struct memlat_hwmon *hw)
{
	struct memlat_node *node;
	int ret = 0;

	node = register_common(dev, hw);
	if (IS_ERR(node)) {
		ret = PTR_ERR(node);
		goto out;
	}

	mutex_lock(&state_lock);
	node->gov = &devfreq_gov_memlat;
	node->attr_grp = &memlat_dev_attr_group;

	if (!memlat_use_cnt)
		ret = devfreq_add_governor(&devfreq_gov_memlat);
		ret = devfreq_add_governor(&devfreq_gov_memlat);
	if (!ret)
	if (!ret)
		use_cnt++;
		memlat_use_cnt++;
	mutex_unlock(&state_lock);
	mutex_unlock(&state_lock);


out:
	if (!ret)
	if (!ret)
		dev_info(dev, "Memory Latency governor registered.\n");
		dev_info(dev, "Memory Latency governor registered.\n");
	else
	else
Loading