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
6 * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
8 #include <linux/config.h>
9 #include <asm/uaccess.h>
12 #include <linux/proc_fs.h>
13 #include <linux/seq_file.h>
14 #include <asm/sn/sn_sal.h>
16 static int partition_id_show(struct seq_file
*s
, void *p
)
18 seq_printf(s
, "%d\n", sn_local_partid());
22 static int partition_id_open(struct inode
*inode
, struct file
*file
)
24 return single_open(file
, partition_id_show
, NULL
);
27 static int system_serial_number_show(struct seq_file
*s
, void *p
)
29 seq_printf(s
, "%s\n", sn_system_serial_number());
33 static int system_serial_number_open(struct inode
*inode
, struct file
*file
)
35 return single_open(file
, system_serial_number_show
, NULL
);
38 static int licenseID_show(struct seq_file
*s
, void *p
)
40 seq_printf(s
, "0x%lx\n", sn_partition_serial_number_val());
44 static int licenseID_open(struct inode
*inode
, struct file
*file
)
46 return single_open(file
, licenseID_show
, NULL
);
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.
55 int sn_force_interrupt_flag
= 1;
57 static int sn_force_interrupt_show(struct seq_file
*s
, void *p
)
59 seq_printf(s
, "Force interrupt is %s\n",
60 sn_force_interrupt_flag
? "enabled" : "disabled");
64 static ssize_t
sn_force_interrupt_write_proc(struct file
*file
,
65 const char __user
*buffer
, size_t count
, loff_t
*data
)
69 if (copy_from_user(&val
, buffer
, 1))
72 sn_force_interrupt_flag
= (val
== '0') ? 0 : 1;
76 static int sn_force_interrupt_open(struct inode
*inode
, struct file
*file
)
78 return single_open(file
, sn_force_interrupt_show
, NULL
);
81 static int coherence_id_show(struct seq_file
*s
, void *p
)
83 seq_printf(s
, "%d\n", partition_coherence_id());
88 static int coherence_id_open(struct inode
*inode
, struct file
*file
)
90 return single_open(file
, coherence_id_show
, NULL
);
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
*))
98 struct proc_dir_entry
*e
= create_proc_entry(name
, 0444, parent
);
101 e
->proc_fops
= (struct file_operations
*)kmalloc(
102 sizeof(struct file_operations
), GFP_KERNEL
);
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
;
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
*);
119 void register_sn_procfs(void)
121 static struct proc_dir_entry
*sgi_proc_dir
= NULL
;
122 struct proc_dir_entry
*e
;
124 BUG_ON(sgi_proc_dir
!= NULL
);
125 if (!(sgi_proc_dir
= proc_mkdir("sgi_sn", NULL
)))
128 sn_procfs_create_entry("partition_id", sgi_proc_dir
,
129 partition_id_open
, single_release
);
131 sn_procfs_create_entry("system_serial_number", sgi_proc_dir
,
132 system_serial_number_open
, single_release
);
134 sn_procfs_create_entry("licenseID", sgi_proc_dir
,
135 licenseID_open
, single_release
);
137 e
= sn_procfs_create_entry("sn_force_interrupt", sgi_proc_dir
,
138 sn_force_interrupt_open
, single_release
);
140 e
->proc_fops
->write
= sn_force_interrupt_write_proc
;
142 sn_procfs_create_entry("coherence_id", sgi_proc_dir
,
143 coherence_id_open
, single_release
);
145 sn_procfs_create_entry("sn_topology", sgi_proc_dir
,
146 sn_topology_open
, sn_topology_release
);
149 #endif /* CONFIG_PROC_FS */