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 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.

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,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
+34 −12
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include "governor.h"
#include "governor_memlat.h"
#include <linux/perf_event.h>
#include <linux/of_device.h>

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

struct memlat_mon_spec {
	bool is_compute;
};

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

	if (!event->pevent)
		return 0;

	total = perf_event_read_value(event->pevent, &enabled, &running);
	ev_count = total - event->prev_count;
	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 memlat_hwmon *hw;
	struct cpu_grp_info *cpu_grp;
	const struct memlat_mon_spec *spec;
	int cpu, ret;
	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;

	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",
				   &event_id);
	if (ret) {
@@ -306,24 +331,21 @@ static int arm_memlat_mon_driver_probe(struct platform_device *pdev)
	else
		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);
	if (ret) {
	if (ret)
		pr_err("Mem Latency Gov registration failed\n");

	return ret;
}

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

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 Diff line number Diff line
// 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
@@ -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));
		else
			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;
	}
	/*
@@ -357,6 +365,14 @@ void mon_irq_clear(struct bwmon *m, enum mon_reg_type type)
		break;
	case MON3:
		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;
	}
}
+1 −3
Original line number Diff line number Diff line
@@ -560,7 +560,6 @@ struct devfreq *devfreq_add_device(struct device *dev,
{
	struct devfreq *devfreq;
	struct devfreq_governor *governor;
	static atomic_t devfreq_no = ATOMIC_INIT(-1);
	int err = 0;

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

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

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

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

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

		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(stall_floor, 0U, 100U);

static struct attribute *dev_attr[] = {
static struct attribute *memlat_dev_attr[] = {
	&dev_attr_ratio_ceil.attr,
	&dev_attr_stall_floor.attr,
	&dev_attr_freq_map.attr,
	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",
	.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
@@ -330,6 +340,12 @@ static struct devfreq_governor devfreq_gov_memlat = {
	.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
static struct core_dev_map *init_core_dev_map(struct device *dev,
		char *prop_name)
@@ -372,20 +388,17 @@ static struct core_dev_map *init_core_dev_map(struct device *dev,
	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;

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

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

	node->gov = &devfreq_gov_memlat;
	node->attr_grp = &dev_attr_group;
		return ERR_PTR(-ENOMEM);

	node->ratio_ceil = 10;
	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");
	if (!hw->freq_map) {
		dev_err(dev, "Couldn't find the core-dev freq table!\n");
		return -EINVAL;
		return ERR_PTR(-EINVAL);
	}

	mutex_lock(&list_lock);
	list_add_tail(&node->list, &memlat_list);
	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);
	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);
	if (!ret)
		use_cnt++;
		memlat_use_cnt++;
	mutex_unlock(&state_lock);

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