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-2005 Silicon Graphics, Inc. All rights reserved. 7 */ 8 9#ifdef CONFIG_PROC_FS 10#include <linux/proc_fs.h> 11#include <linux/seq_file.h> 12#include <asm/uaccess.h> 13#include <asm/sn/sn_sal.h> 14 15static int partition_id_show(struct seq_file *s, void *p) 16{ 17 seq_printf(s, "%d\n", sn_partition_id); 18 return 0; 19} 20 21static int partition_id_open(struct inode *inode, struct file *file) 22{ 23 return single_open(file, partition_id_show, NULL); 24} 25 26static int system_serial_number_show(struct seq_file *s, void *p) 27{ 28 seq_printf(s, "%s\n", sn_system_serial_number()); 29 return 0; 30} 31 32static int system_serial_number_open(struct inode *inode, struct file *file) 33{ 34 return single_open(file, system_serial_number_show, NULL); 35} 36 37static int licenseID_show(struct seq_file *s, void *p) 38{ 39 seq_printf(s, "0x%lx\n", sn_partition_serial_number_val()); 40 return 0; 41} 42 43static int licenseID_open(struct inode *inode, struct file *file) 44{ 45 return single_open(file, licenseID_show, NULL); 46} 47 48/* 49 * Enable forced interrupt by default. 50 * When set, the sn interrupt handler writes the force interrupt register on 51 * the bridge chip. The hardware will then send an interrupt message if the 52 * interrupt line is active. This mimics a level sensitive interrupt. 53 */ 54extern int sn_force_interrupt_flag; 55 56static int sn_force_interrupt_show(struct seq_file *s, void *p) 57{ 58 seq_printf(s, "Force interrupt is %s\n", 59 sn_force_interrupt_flag ? "enabled" : "disabled"); 60 return 0; 61} 62 63static ssize_t sn_force_interrupt_write_proc(struct file *file, 64 const char __user *buffer, size_t count, loff_t *data) 65{ 66 char val; 67 68 if (copy_from_user(&val, buffer, 1)) 69 return -EFAULT; 70 71 sn_force_interrupt_flag = (val == '0') ? 0 : 1; 72 return count; 73} 74 75static int sn_force_interrupt_open(struct inode *inode, struct file *file) 76{ 77 return single_open(file, sn_force_interrupt_show, NULL); 78} 79 80static int coherence_id_show(struct seq_file *s, void *p) 81{ 82 seq_printf(s, "%d\n", partition_coherence_id()); 83 84 return 0; 85} 86 87static int coherence_id_open(struct inode *inode, struct file *file) 88{ 89 return single_open(file, coherence_id_show, NULL); 90} 91 92/* /proc/sgi_sn/sn_topology uses seq_file, see sn_hwperf.c */ 93extern int sn_topology_open(struct inode *, struct file *); 94extern int sn_topology_release(struct inode *, struct file *); 95 96static const struct file_operations proc_partition_id_fops = { 97 .open = partition_id_open, 98 .read = seq_read, 99 .llseek = seq_lseek, 100 .release = single_release, 101}; 102 103static const struct file_operations proc_system_sn_fops = { 104 .open = system_serial_number_open, 105 .read = seq_read, 106 .llseek = seq_lseek, 107 .release = single_release, 108}; 109 110static const struct file_operations proc_license_id_fops = { 111 .open = licenseID_open, 112 .read = seq_read, 113 .llseek = seq_lseek, 114 .release = single_release, 115}; 116 117static const struct file_operations proc_sn_force_intr_fops = { 118 .open = sn_force_interrupt_open, 119 .read = seq_read, 120 .write = sn_force_interrupt_write_proc, 121 .llseek = seq_lseek, 122 .release = single_release, 123}; 124 125static const struct file_operations proc_coherence_id_fops = { 126 .open = coherence_id_open, 127 .read = seq_read, 128 .llseek = seq_lseek, 129 .release = single_release, 130}; 131 132static const struct file_operations proc_sn_topo_fops = { 133 .open = sn_topology_open, 134 .read = seq_read, 135 .llseek = seq_lseek, 136 .release = sn_topology_release, 137}; 138 139void register_sn_procfs(void) 140{ 141 static struct proc_dir_entry *sgi_proc_dir = NULL; 142 struct proc_dir_entry *pde; 143 144 BUG_ON(sgi_proc_dir != NULL); 145 if (!(sgi_proc_dir = proc_mkdir("sgi_sn", NULL))) 146 return; 147 148 pde = create_proc_entry("partition_id", 0444, sgi_proc_dir); 149 if (pde) 150 pde->proc_fops = &proc_partition_id_fops; 151 pde = create_proc_entry("system_serial_number", 0444, sgi_proc_dir); 152 if (pde) 153 pde->proc_fops = &proc_system_sn_fops; 154 pde = create_proc_entry("licenseID", 0444, sgi_proc_dir); 155 if (pde) 156 pde->proc_fops = &proc_license_id_fops; 157 pde = create_proc_entry("sn_force_interrupt", 0644, sgi_proc_dir); 158 if (pde) 159 pde->proc_fops = &proc_sn_force_intr_fops; 160 pde = create_proc_entry("coherence_id", 0444, sgi_proc_dir); 161 if (pde) 162 pde->proc_fops = &proc_coherence_id_fops; 163 pde = create_proc_entry("sn_topology", 0444, sgi_proc_dir); 164 if (pde) 165 pde->proc_fops = &proc_sn_topo_fops; 166} 167 168#endif /* CONFIG_PROC_FS */ 169