2 * linux/arch/arm/kernel/sysfs.c
4 * Copyright (C) 2008 Mans Rullgard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/kernel.h>
12 #include <linux/cpu.h>
13 #include <linux/sysdev.h>
16 asm(".arch_extension sec\n");
18 #define SETBITS(val, bits, new) \
24 #define SHOW_REG(name, opc1, crn, crm, opc2) \
25 static ssize_t name##_show(struct sys_device *dev, \
26 struct sysdev_attribute *attr, \
30 asm ("mrc p15,"#opc1", %0,"#crn","#crm","#opc2 : "=r"(val)); \
31 return snprintf(buf, PAGE_SIZE, "%08x\n", val); \
34 #define STORE_REG(name, opc1, crn, crm, opc2, bits) \
35 static ssize_t name##_store(struct sys_device *dev, \
36 struct sysdev_attribute *attr, \
37 const char *buf, size_t size) \
40 unsigned new = simple_strtoul(buf, &end, 0); \
46 asm ("mrc p15,"#opc1", %0,"#crn","#crm","#opc2 : "=r"(val)); \
47 SETBITS(val, bits, new); \
48 asm ("mcr p15,"#opc1", %0,"#crn","#crm","#opc2 :: "r"(val)); \
53 #define RD_REG(name, opc1, crn, crm, opc2) \
54 SHOW_REG(name, opc1, crn, crm, opc2) \
55 static SYSDEV_ATTR(name, S_IRUGO|S_IWUSR, name##_show, NULL)
57 #define RDWR_REG(name, opc1, crn, crm, opc2, bits) \
58 SHOW_REG(name, opc1, crn, crm, opc2) \
59 STORE_REG(name, opc1, crn, crm, opc2, bits) \
60 static SYSDEV_ATTR(name, S_IRUGO|S_IWUSR, name##_show, name##_store)
62 RDWR_REG(control, 0, c1, c0, 0, 0x802);
64 SHOW_REG(aux_ctl, 0, c1, c0, 1)
66 #ifdef CONFIG_ARCH_OMAP34XX
67 static ssize_t aux_ctl_store(struct sys_device *dev,
68 struct sysdev_attribute *attr,
69 const char *buf, size_t size)
72 unsigned new = simple_strtoul(buf, &end, 0);
78 asm ("mrc p15, 0, %0, c1, c0, 1" : "=r"(val));
79 SETBITS(val, 0xff8, new);
81 asm ("mov r0, %0 \n\t"
84 :: "r"(val) : "r0", "r12");
88 #define AUX_WR S_IWUSR
90 #define aux_ctl_store NULL
94 static SYSDEV_ATTR(aux_control, S_IRUGO|AUX_WR, aux_ctl_show, aux_ctl_store);
96 SHOW_REG(l2_aux_ctl, 1, c9, c0, 2)
98 #ifdef CONFIG_ARCH_OMAP34XX
99 static ssize_t l2_aux_ctl_store(struct sys_device *dev,
100 struct sysdev_attribute *attr,
101 const char *buf, size_t size)
104 unsigned new = simple_strtoul(buf, &end, 0);
110 asm ("mrc p15, 1, %0, c9, c0, 2" : "=r"(val));
111 SETBITS(val, 0xbc00000, new);
112 asm ("mov r0, %0 \n\t"
115 :: "r"(val) : "r0", "r12");
119 #define L2AUX_WR S_IWUSR
121 #define l2_aux_ctl_store NULL
125 static SYSDEV_ATTR(l2_aux_control, S_IRUGO|L2AUX_WR,
126 l2_aux_ctl_show, l2_aux_ctl_store);
128 RDWR_REG(pmon_pmnc, 0, c9, c12, 0, 0x3f)
129 RDWR_REG(pmon_cntens, 0, c9, c12, 1, 0x8000000f)
130 RDWR_REG(pmon_cntenc, 0, c9, c12, 2, 0x8000000f)
131 RDWR_REG(pmon_ccnt, 0, c9, c13, 0, 0xffffffff)
132 RDWR_REG(pmon_useren, 0, c9, c14, 0, 1)
134 #define REG_ATTR(sysdev, name) \
136 int err = sysfs_create_file(&sysdev->kobj, &name.attr); \
140 static int __init cpu_sysfs_init(void)
142 struct sys_device *sysdev;
145 for_each_possible_cpu(cpu) {
146 sysdev = get_cpu_sysdev(cpu);
147 REG_ATTR(sysdev, attr_control);
148 REG_ATTR(sysdev, attr_aux_control);
149 REG_ATTR(sysdev, attr_l2_aux_control);
150 REG_ATTR(sysdev, attr_pmon_pmnc);
151 REG_ATTR(sysdev, attr_pmon_cntens);
152 REG_ATTR(sysdev, attr_pmon_cntenc);
153 REG_ATTR(sysdev, attr_pmon_ccnt);
154 REG_ATTR(sysdev, attr_pmon_useren);
159 device_initcall(cpu_sysfs_init);