diff options
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.patch | 202 |
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 @@ | |||
1 | From 9eeb533964f73b661d23f7b145b96aa5d247e950 Mon Sep 17 00:00:00 2001 | ||
2 | From: Mans Rullgard <mans@mansr.com> | ||
3 | Date: Tue, 10 Nov 2009 00:39:21 +0000 | ||
4 | Subject: [PATCH 38/45] ARM: Expose some CPU control registers via sysfs | ||
5 | |||
6 | This creates sysfs files under /sys/devices/system/cpu/cpuN | ||
7 | exposing the values of the control register, auxiliary control | ||
8 | register, and L2 cache auxiliary control register. Writing to | ||
9 | the files allows setting the value of bits which are safe to | ||
10 | change at any time. | ||
11 | |||
12 | Signed-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 | |||
20 | diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig | ||
21 | index 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" | ||
36 | diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile | ||
37 | index 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 | ||
48 | diff --git a/arch/arm/kernel/sysfs_v7.c b/arch/arm/kernel/sysfs_v7.c | ||
49 | new file mode 100644 | ||
50 | index 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 | -- | ||
201 | 1.6.6.1 | ||
202 | |||