diff options
Diffstat (limited to 'arch/ia64/sn/kernel/sn2/sn_proc_fs.c')
-rw-r--r-- | arch/ia64/sn/kernel/sn2/sn_proc_fs.c | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c new file mode 100644 index 000000000000..6a80fca807b9 --- /dev/null +++ b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved. | ||
7 | */ | ||
8 | #include <linux/config.h> | ||
9 | #include <asm/uaccess.h> | ||
10 | |||
11 | #ifdef CONFIG_PROC_FS | ||
12 | #include <linux/proc_fs.h> | ||
13 | #include <linux/seq_file.h> | ||
14 | #include <asm/sn/sn_sal.h> | ||
15 | |||
16 | static int partition_id_show(struct seq_file *s, void *p) | ||
17 | { | ||
18 | seq_printf(s, "%d\n", sn_local_partid()); | ||
19 | return 0; | ||
20 | } | ||
21 | |||
22 | static int partition_id_open(struct inode *inode, struct file *file) | ||
23 | { | ||
24 | return single_open(file, partition_id_show, NULL); | ||
25 | } | ||
26 | |||
27 | static int system_serial_number_show(struct seq_file *s, void *p) | ||
28 | { | ||
29 | seq_printf(s, "%s\n", sn_system_serial_number()); | ||
30 | return 0; | ||
31 | } | ||
32 | |||
33 | static int system_serial_number_open(struct inode *inode, struct file *file) | ||
34 | { | ||
35 | return single_open(file, system_serial_number_show, NULL); | ||
36 | } | ||
37 | |||
38 | static int licenseID_show(struct seq_file *s, void *p) | ||
39 | { | ||
40 | seq_printf(s, "0x%lx\n", sn_partition_serial_number_val()); | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | static int licenseID_open(struct inode *inode, struct file *file) | ||
45 | { | ||
46 | return single_open(file, licenseID_show, NULL); | ||
47 | } | ||
48 | |||
49 | /* | ||
50 | * Enable forced interrupt by default. | ||
51 | * When set, the sn interrupt handler writes the force interrupt register on | ||
52 | * the bridge chip. The hardware will then send an interrupt message if the | ||
53 | * interrupt line is active. This mimics a level sensitive interrupt. | ||
54 | */ | ||
55 | int sn_force_interrupt_flag = 1; | ||
56 | |||
57 | static int sn_force_interrupt_show(struct seq_file *s, void *p) | ||
58 | { | ||
59 | seq_printf(s, "Force interrupt is %s\n", | ||
60 | sn_force_interrupt_flag ? "enabled" : "disabled"); | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static ssize_t sn_force_interrupt_write_proc(struct file *file, | ||
65 | const char __user *buffer, size_t count, loff_t *data) | ||
66 | { | ||
67 | char val; | ||
68 | |||
69 | if (copy_from_user(&val, buffer, 1)) | ||
70 | return -EFAULT; | ||
71 | |||
72 | sn_force_interrupt_flag = (val == '0') ? 0 : 1; | ||
73 | return count; | ||
74 | } | ||
75 | |||
76 | static int sn_force_interrupt_open(struct inode *inode, struct file *file) | ||
77 | { | ||
78 | return single_open(file, sn_force_interrupt_show, NULL); | ||
79 | } | ||
80 | |||
81 | static int coherence_id_show(struct seq_file *s, void *p) | ||
82 | { | ||
83 | seq_printf(s, "%d\n", partition_coherence_id()); | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static int coherence_id_open(struct inode *inode, struct file *file) | ||
89 | { | ||
90 | return single_open(file, coherence_id_show, NULL); | ||
91 | } | ||
92 | |||
93 | static struct proc_dir_entry *sn_procfs_create_entry( | ||
94 | const char *name, struct proc_dir_entry *parent, | ||
95 | int (*openfunc)(struct inode *, struct file *), | ||
96 | int (*releasefunc)(struct inode *, struct file *)) | ||
97 | { | ||
98 | struct proc_dir_entry *e = create_proc_entry(name, 0444, parent); | ||
99 | |||
100 | if (e) { | ||
101 | e->proc_fops = (struct file_operations *)kmalloc( | ||
102 | sizeof(struct file_operations), GFP_KERNEL); | ||
103 | if (e->proc_fops) { | ||
104 | memset(e->proc_fops, 0, sizeof(struct file_operations)); | ||
105 | e->proc_fops->open = openfunc; | ||
106 | e->proc_fops->read = seq_read; | ||
107 | e->proc_fops->llseek = seq_lseek; | ||
108 | e->proc_fops->release = releasefunc; | ||
109 | } | ||
110 | } | ||
111 | |||
112 | return e; | ||
113 | } | ||
114 | |||
115 | /* /proc/sgi_sn/sn_topology uses seq_file, see sn_hwperf.c */ | ||
116 | extern int sn_topology_open(struct inode *, struct file *); | ||
117 | extern int sn_topology_release(struct inode *, struct file *); | ||
118 | |||
119 | void register_sn_procfs(void) | ||
120 | { | ||
121 | static struct proc_dir_entry *sgi_proc_dir = NULL; | ||
122 | struct proc_dir_entry *e; | ||
123 | |||
124 | BUG_ON(sgi_proc_dir != NULL); | ||
125 | if (!(sgi_proc_dir = proc_mkdir("sgi_sn", NULL))) | ||
126 | return; | ||
127 | |||
128 | sn_procfs_create_entry("partition_id", sgi_proc_dir, | ||
129 | partition_id_open, single_release); | ||
130 | |||
131 | sn_procfs_create_entry("system_serial_number", sgi_proc_dir, | ||
132 | system_serial_number_open, single_release); | ||
133 | |||
134 | sn_procfs_create_entry("licenseID", sgi_proc_dir, | ||
135 | licenseID_open, single_release); | ||
136 | |||
137 | e = sn_procfs_create_entry("sn_force_interrupt", sgi_proc_dir, | ||
138 | sn_force_interrupt_open, single_release); | ||
139 | if (e) | ||
140 | e->proc_fops->write = sn_force_interrupt_write_proc; | ||
141 | |||
142 | sn_procfs_create_entry("coherence_id", sgi_proc_dir, | ||
143 | coherence_id_open, single_release); | ||
144 | |||
145 | sn_procfs_create_entry("sn_topology", sgi_proc_dir, | ||
146 | sn_topology_open, sn_topology_release); | ||
147 | } | ||
148 | |||
149 | #endif /* CONFIG_PROC_FS */ | ||