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 if (i == 0) { 29 seq_puts(p, " "); 30 for_each_online_cpu(j) 31 seq_printf(p, "CPU%d ",j); 32 seq_putc(p, '\n'); 33 } 34 35 if (i < NR_IRQS) { 36 seq_printf(p, "%s: ", intrclass_names[i]); 37 #ifndef CONFIG_SMP 38 seq_printf(p, "%10u ", kstat_irqs(i)); 39 #else 40 for_each_online_cpu(j) 41 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 42 #endif 43 seq_putc(p, '\n'); 44 45 } 46 47 return 0; 48 } 49 50 /* 51 * For compatibilty only. S/390 specific setup of interrupts et al. is done 52 * much later in init_channel_subsystem(). 53 */ 54 void __init 55 init_IRQ(void) 56 { 57 /* nothing... */ 58 } 59 60 /* 61 * Switch to the asynchronous interrupt stack for softirq execution. 62 */ 63 extern void __do_softirq(void); 64 65 asmlinkage void do_softirq(void) 66 { 67 unsigned long flags, old, new; 68 69 if (in_interrupt()) 70 return; 71 72 local_irq_save(flags); 73 74 if (local_softirq_pending()) { 75 /* Get current stack pointer. */ 76 asm volatile("la %0,0(15)" : "=a" (old)); 77 /* Check against async. stack address range. */ 78 new = S390_lowcore.async_stack; 79 if (((new - old) >> (PAGE_SHIFT + THREAD_ORDER)) != 0) { 80 /* Need to switch to the async. stack. */ 81 new -= STACK_FRAME_OVERHEAD; 82 ((struct stack_frame *) new)->back_chain = old; 83 84 asm volatile(" la 15,0(%0)\n" 85 " basr 14,%2\n" 86 " la 15,0(%1)\n" 87 : : "a" (new), "a" (old), 88 "a" (__do_softirq) 89 : "0", "1", "2", "3", "4", "5", "14", 90 "cc", "memory" ); 91 } else 92 /* We are already on the async stack. */ 93 __do_softirq(); 94 } 95 96 local_irq_restore(flags); 97 } 98 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