summaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0038-ARM-Expose-some-CPU-control-registers-via-sysfs.patch
diff options
context:
space:
mode:
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0038-ARM-Expose-some-CPU-control-registers-via-sysfs.patch')
-rw-r--r--extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0038-ARM-Expose-some-CPU-control-registers-via-sysfs.patch202
1 files changed, 202 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0038-ARM-Expose-some-CPU-control-registers-via-sysfs.patch b/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0038-ARM-Expose-some-CPU-control-registers-via-sysfs.patch
new file mode 100644
index 00000000..0b19cb70
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap-psp-2.6.32/0038-ARM-Expose-some-CPU-control-registers-via-sysfs.patch
@@ -0,0 +1,202 @@
1From 9eeb533964f73b661d23f7b145b96aa5d247e950 Mon Sep 17 00:00:00 2001
2From: Mans Rullgard <mans@mansr.com>
3Date: Tue, 10 Nov 2009 00:39:21 +0000
4Subject: [PATCH 38/45] ARM: Expose some CPU control registers via sysfs
5
6This creates sysfs files under /sys/devices/system/cpu/cpuN
7exposing the values of the control register, auxiliary control
8register, and L2 cache auxiliary control register. Writing to
9the files allows setting the value of bits which are safe to
10change at any time.
11
12Signed-off-by: Mans Rullgard <mans@mansr.com>
13---
14 arch/arm/Kconfig | 5 ++
15 arch/arm/kernel/Makefile | 1 +
16 arch/arm/kernel/sysfs_v7.c | 146 ++++++++++++++++++++++++++++++++++++++++++++
17 3 files changed, 152 insertions(+), 0 deletions(-)
18 create mode 100644 arch/arm/kernel/sysfs_v7.c
19
20diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
21index f5ded3c..2d370da 100644
22--- a/arch/arm/Kconfig
23+++ b/arch/arm/Kconfig
24@@ -1252,6 +1252,11 @@ config UACCESS_WITH_MEMCPY
25 However, if the CPU data cache is using a write-allocate mode,
26 this option is unlikely to provide any performance gain.
27
28+config CPU_V7_SYSFS
29+ bool
30+ depends on CPU_V7 && SYSFS
31+ default y
32+
33 endmenu
34
35 menu "Boot options"
36diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
37index dd00f74..ee20134 100644
38--- a/arch/arm/kernel/Makefile
39+++ b/arch/arm/kernel/Makefile
40@@ -38,6 +38,7 @@ obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
41 obj-$(CONFIG_KGDB) += kgdb.o
42 obj-$(CONFIG_ARM_UNWIND) += unwind.o
43 obj-$(CONFIG_HAVE_TCM) += tcm.o
44+obj-$(CONFIG_CPU_V7_SYSFS) += sysfs_v7.o
45
46 obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
47 AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
48diff --git a/arch/arm/kernel/sysfs_v7.c b/arch/arm/kernel/sysfs_v7.c
49new file mode 100644
50index 0000000..c05bf5f
51--- /dev/null
52+++ b/arch/arm/kernel/sysfs_v7.c
53@@ -0,0 +1,146 @@
54+/*
55+ * linux/arch/arm/kernel/sysfs.c
56+ *
57+ * Copyright (C) 2008 Mans Rullgard
58+ *
59+ * This program is free software; you can redistribute it and/or modify
60+ * it under the terms of the GNU General Public License version 2 as
61+ * published by the Free Software Foundation.
62+ */
63+
64+#include <linux/kernel.h>
65+#include <linux/cpu.h>
66+#include <linux/sysdev.h>
67+#include <linux/fs.h>
68+
69+#define SETBITS(val, bits, new) \
70+ do { \
71+ val &= ~bits; \
72+ val |= new & bits; \
73+ } while (0)
74+
75+#define SHOW_REG(name, opc1, crn, crm, opc2) \
76+static ssize_t name##_show(struct sys_device *dev, \
77+ struct sysdev_attribute *attr, \
78+ char *buf) \
79+{ \
80+ unsigned val; \
81+ asm ("mrc p15,"#opc1", %0,"#crn","#crm","#opc2 : "=r"(val)); \
82+ return snprintf(buf, PAGE_SIZE, "%08x\n", val); \
83+}
84+
85+#define STORE_REG(name, opc1, crn, crm, opc2, bits) \
86+static ssize_t name##_store(struct sys_device *dev, \
87+ struct sysdev_attribute *attr, \
88+ const char *buf, size_t size) \
89+{ \
90+ char *end; \
91+ unsigned new = simple_strtoul(buf, &end, 0); \
92+ unsigned val; \
93+ \
94+ if (end == buf) \
95+ return -EINVAL; \
96+ \
97+ asm ("mrc p15,"#opc1", %0,"#crn","#crm","#opc2 : "=r"(val)); \
98+ SETBITS(val, bits, new); \
99+ asm ("mcr p15,"#opc1", %0,"#crn","#crm","#opc2 :: "r"(val)); \
100+ \
101+ return end - buf; \
102+}
103+
104+#define RD_REG(name, opc1, crn, crm, opc2) \
105+ SHOW_REG(name, opc1, crn, crm, opc2) \
106+ static SYSDEV_ATTR(name, S_IRUGO|S_IWUSR, name##_show, NULL)
107+
108+#define RDWR_REG(name, opc1, crn, crm, opc2, bits) \
109+ SHOW_REG(name, opc1, crn, crm, opc2) \
110+ STORE_REG(name, opc1, crn, crm, opc2, bits) \
111+ static SYSDEV_ATTR(name, S_IRUGO|S_IWUSR, name##_show, name##_store)
112+
113+RDWR_REG(control, 0, c1, c0, 0, 0x802);
114+
115+SHOW_REG(aux_ctl, 0, c1, c0, 1)
116+
117+#ifdef CONFIG_ARCH_OMAP34XX
118+static ssize_t aux_ctl_store(struct sys_device *dev,
119+ struct sysdev_attribute *attr,
120+ const char *buf, size_t size)
121+{
122+ char *end;
123+ unsigned new = simple_strtoul(buf, &end, 0);
124+ unsigned val;
125+
126+ if (end == buf)
127+ return -EINVAL;
128+
129+ asm ("mrc p15, 0, %0, c1, c0, 1" : "=r"(val));
130+ SETBITS(val, 0xff8, new);
131+ val &= ~2;
132+ asm ("mov r0, %0 \n\t"
133+ "mov r12, #3 \n\t"
134+ "smc #0 \n\t"
135+ :: "r"(val) : "r0", "r12");
136+
137+ return end - buf;
138+}
139+#define AUX_WR S_IWUSR
140+#else
141+#define aux_ctl_store NULL
142+#define AUX_WR 0
143+#endif
144+
145+static SYSDEV_ATTR(aux_control, S_IRUGO|AUX_WR, aux_ctl_show, aux_ctl_store);
146+
147+SHOW_REG(l2_aux_ctl, 1, c9, c0, 2)
148+
149+#ifdef CONFIG_ARCH_OMAP34XX
150+static ssize_t l2_aux_ctl_store(struct sys_device *dev,
151+ struct sysdev_attribute *attr,
152+ const char *buf, size_t size)
153+{
154+ char *end;
155+ unsigned new = simple_strtoul(buf, &end, 0);
156+ unsigned val;
157+
158+ if (end == buf)
159+ return -EINVAL;
160+
161+ asm ("mrc p15, 1, %0, c9, c0, 2" : "=r"(val));
162+ SETBITS(val, 0xbc00000, new);
163+ asm ("mov r0, %0 \n\t"
164+ "mov r12, #2 \n\t"
165+ "smc #0 \n\t"
166+ :: "r"(val) : "r0", "r12");
167+
168+ return end - buf;
169+}
170+#define L2AUX_WR S_IWUSR
171+#else
172+#define l2_aux_ctl_store NULL
173+#define L2AUX_WR 0
174+#endif
175+
176+static SYSDEV_ATTR(l2_aux_control, S_IRUGO|L2AUX_WR,
177+ l2_aux_ctl_show, l2_aux_ctl_store);
178+
179+#define REG_ATTR(sysdev, name) \
180+ do { \
181+ int err = sysfs_create_file(&sysdev->kobj, &name.attr); \
182+ WARN_ON(err != 0); \
183+ } while (0)
184+
185+static int __init cpu_sysfs_init(void)
186+{
187+ struct sys_device *sysdev;
188+ int cpu;
189+
190+ for_each_possible_cpu(cpu) {
191+ sysdev = get_cpu_sysdev(cpu);
192+ REG_ATTR(sysdev, attr_control);
193+ REG_ATTR(sysdev, attr_aux_control);
194+ REG_ATTR(sysdev, attr_l2_aux_control);
195+ }
196+
197+ return 0;
198+}
199+device_initcall(cpu_sysfs_init);
200--
2011.6.6.1
202