linux/arch/s390/kernel/irq.c
<<
>>
Prefs
   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
  98void init_irq_proc(void)
  99{
 100        struct proc_dir_entry *root_irq_dir;
 101
 102        root_irq_dir = proc_mkdir("irq", NULL);
 103        create_prof_cpu_mask(root_irq_dir);
 104}
 105