1 /* 2 * arch/s390/kernel/irq.c 3 * 4 * Copyright IBM Corp. 2004,2007 5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), 6 * Thomas Spatzier (tspat@de.ibm.com) 7 * 8 * This file contains interrupt related functions. 9 */ 10 11 #include <linux/module.h> 12 #include <linux/kernel.h> 13 #include <linux/kernel_stat.h> 14 #include <linux/interrupt.h> 15 #include <linux/seq_file.h> 16 #include <linux/cpu.h> 17 #include <linux/proc_fs.h> 18 #include <linux/profile.h> 19 20 /* 21 * show_interrupts is needed by /proc/interrupts. 22 */ 23 int show_interrupts(struct seq_file *p, void *v) 24 { 25 static const char *intrclass_names[] = { "EXT", "I/O", }; 26 int i = *(loff_t *) v, j; 27 28 get_online_cpus(); 29 if (i == 0) { 30 seq_puts(p, " "); 31 for_each_online_cpu(j) 32 seq_printf(p, "CPU%d ",j); 33 seq_putc(p, '\n'); 34 } 35 36 if (i < NR_IRQS) { 37 seq_printf(p, "%s: ", intrclass_names[i]); 38 #ifndef CONFIG_SMP 39 seq_printf(p, "%10u ", kstat_irqs(i)); 40 #else 41 for_each_online_cpu(j) 42 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 43 #endif 44 seq_putc(p, '\n'); 45 46 } 47 put_online_cpus(); 48 return 0; 49 } 50 51 /* 52 * For compatibilty only. S/390 specific setup of interrupts et al. is done 53 * much later in init_channel_subsystem(). 54 */ 55 void __init 56 init_IRQ(void) 57 { 58 /* nothing... */ 59 } 60 61 /* 62 * Switch to the asynchronous interrupt stack for softirq execution. 63 */ 64 asmlinkage void do_softirq(void) 65 { 66 unsigned long flags, old, new; 67 68 if (in_interrupt()) 69 return; 70 71 local_irq_save(flags); 72 73 if (local_softirq_pending()) { 74 /* Get current stack pointer. */ 75 asm volatile("la %0,0(15)" : "=a" (old)); 76 /* Check against async. stack address range. */ 77 new = S390_lowcore.async_stack; 78 if (((new - old) >> (PAGE_SHIFT + THREAD_ORDER)) != 0) { 79 /* Need to switch to the async. stack. */ 80 new -= STACK_FRAME_OVERHEAD; 81 ((struct stack_frame *) new)->back_chain = old; 82 83 asm volatile(" la 15,0(%0)\n" 84 " basr 14,%2\n" 85 " la 15,0(%1)\n" 86 : : "a" (new), "a" (old), 87 "a" (__do_softirq) 88 : "0", "1", "2", "3", "4", "5", "14", 89 "cc", "memory" ); 90 } else 91 /* We are already on the async stack. */ 92 __do_softirq(); 93 } 94 95 local_irq_restore(flags); 96 } 97 98 #ifdef CONFIG_PROC_FS 99 void init_irq_proc(void) 100 { 101 struct proc_dir_entry *root_irq_dir; 102 103 root_irq_dir = proc_mkdir("irq", NULL); 104 create_prof_cpu_mask(root_irq_dir); 105 } 106 #endif 107