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