aboutsummaryrefslogtreecommitdiff
path: root/drivers/misc/mediatek/kernel/sched/cputopo.c
blob: 76e29facd7e5595dfd32e89f5cafa239af2a65a2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <linux/device.h>
#include <linux/proc_fs.h>
#include <linux/topology.h>

#define MAX_LONG_SIZE 24

struct kobject *cputopo_glb_kobj;

/*
 * nr_clusters attribute
 */
static ssize_t nr_clusters_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{
	return snprintf(buf, MAX_LONG_SIZE, "%u\n", arch_get_nr_clusters());
}
static struct kobj_attribute nr_clusters_attr = __ATTR_RO(nr_clusters);

/*
 * is_big_little attribute
 */
static ssize_t is_big_little_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{
	return snprintf(buf, MAX_LONG_SIZE, "%u\n", arch_is_big_little());
}
static struct kobj_attribute is_big_little_attr = __ATTR_RO(is_big_little);

/*
 * is_multi_cluster attribute
 */
static ssize_t is_multi_cluster_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{
	return snprintf(buf, MAX_LONG_SIZE, "%u\n", arch_is_multi_cluster());
}
static struct kobj_attribute is_multi_cluster_attr = __ATTR_RO(is_multi_cluster);

/*
 * little_cpumask attribute
 */
static ssize_t little_cpumask_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{
	struct cpumask big, little;

	arch_get_big_little_cpus(&big, &little);
	return snprintf(buf, MAX_LONG_SIZE, "%02lx\n", *cpumask_bits(&little));
}
static struct kobj_attribute little_cpumask_attr = __ATTR_RO(little_cpumask);

/*
 * big_cpumask attribute
 */
static ssize_t big_cpumask_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{
	struct cpumask big, little;

	arch_get_big_little_cpus(&big, &little);
	return snprintf(buf, MAX_LONG_SIZE, "%02lx\n", *cpumask_bits(&big));
}
static struct kobj_attribute big_cpumask_attr = __ATTR_RO(big_cpumask);


/*
 * glbinfo attribute
 */
static ssize_t glbinfo_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{
	int len = 0;
	struct cpumask big, little;

	arch_get_big_little_cpus(&big, &little);
	len += snprintf(buf + len, PAGE_SIZE - len - 1, "big/little arch: %s\n",
					arch_is_big_little() ? "yes" : "no");
	len += snprintf(buf + len, PAGE_SIZE - len - 1, "big/little cpumask:%0lx/%0lx\n",
					*cpumask_bits(&big), *cpumask_bits(&little));
	len += snprintf(buf + len, PAGE_SIZE - len - 1, "nr_cups: %u\n",
					nr_cpu_ids);
	len += snprintf(buf + len, PAGE_SIZE - len - 1, "nr_clusters: %u\n",
					arch_get_nr_clusters());

	return len;
}
static struct kobj_attribute glbinfo_attr = __ATTR_RO(glbinfo);



static struct attribute *cputopo_attrs[] = {
	&nr_clusters_attr.attr,
	&is_big_little_attr.attr,
	&is_multi_cluster_attr.attr,
	&little_cpumask_attr.attr,
	&big_cpumask_attr.attr,
	&glbinfo_attr.attr,
	NULL,
};

static struct attribute_group cputopo_attr_group = {
	.attrs = cputopo_attrs,
};

static int init_cputopo_attribs(void)
{
	int err;

	/* Create /sys/devices/system/cpu/cputopo/... */
	cputopo_glb_kobj = kobject_create_and_add("cputopo", &cpu_subsys.dev_root->kobj);
	if (!cputopo_glb_kobj)
		return -ENOMEM;

	err = sysfs_create_group(cputopo_glb_kobj, &cputopo_attr_group);
	if (err)
		kobject_put(cputopo_glb_kobj);

	return err;
}

static int __init cputopo_info_init(void)
{
	int ret = 0;

	ret = init_cputopo_attribs();

	return ret;
}

core_initcall(cputopo_info_init);