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 */ 23int 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 */ 55void __init 56init_IRQ(void) 57{ 58 /* nothing... */ 59} 60 61/* 62 * Switch to the asynchronous interrupt stack for softirq execution. 63 */ 64asmlinkage 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 99void 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