root/arch/mips/lasat/interrupt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. disable_lasat_irq
  2. enable_lasat_irq
  3. ls1bit32
  4. get_int_status_100
  5. get_int_status_200
  6. plat_irq_dispatch
  7. arch_init_irq

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Carsten Langgaard, carstenl@mips.com
   4  * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
   5  *
   6  * Routines for generic manipulation of the interrupts found on the
   7  * Lasat boards.
   8  */
   9 #include <linux/init.h>
  10 #include <linux/interrupt.h>
  11 #include <linux/irq.h>
  12 
  13 #include <asm/irq_cpu.h>
  14 #include <asm/lasat/lasat.h>
  15 #include <asm/lasat/lasatint.h>
  16 
  17 #include <irq.h>
  18 
  19 static volatile int *lasat_int_status;
  20 static volatile int *lasat_int_mask;
  21 static volatile int lasat_int_mask_shift;
  22 
  23 void disable_lasat_irq(struct irq_data *d)
  24 {
  25         unsigned int irq_nr = d->irq - LASAT_IRQ_BASE;
  26 
  27         *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift;
  28 }
  29 
  30 void enable_lasat_irq(struct irq_data *d)
  31 {
  32         unsigned int irq_nr = d->irq - LASAT_IRQ_BASE;
  33 
  34         *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift;
  35 }
  36 
  37 static struct irq_chip lasat_irq_type = {
  38         .name = "Lasat",
  39         .irq_mask = disable_lasat_irq,
  40         .irq_unmask = enable_lasat_irq,
  41 };
  42 
  43 static inline int ls1bit32(unsigned int x)
  44 {
  45         int b = 31, s;
  46 
  47         s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
  48         s =  8; if (x <<  8 == 0) s = 0; b -= s; x <<= s;
  49         s =  4; if (x <<  4 == 0) s = 0; b -= s; x <<= s;
  50         s =  2; if (x <<  2 == 0) s = 0; b -= s; x <<= s;
  51         s =  1; if (x <<  1 == 0) s = 0; b -= s;
  52 
  53         return b;
  54 }
  55 
  56 static unsigned long (*get_int_status)(void);
  57 
  58 static unsigned long get_int_status_100(void)
  59 {
  60         return *lasat_int_status & *lasat_int_mask;
  61 }
  62 
  63 static unsigned long get_int_status_200(void)
  64 {
  65         unsigned long int_status;
  66 
  67         int_status = *lasat_int_status;
  68         int_status &= (int_status >> LASATINT_MASK_SHIFT_200) & 0xffff;
  69         return int_status;
  70 }
  71 
  72 asmlinkage void plat_irq_dispatch(void)
  73 {
  74         unsigned long int_status;
  75         unsigned int cause = read_c0_cause();
  76         int irq;
  77 
  78         if (cause & CAUSEF_IP7) {       /* R4000 count / compare IRQ */
  79                 do_IRQ(7);
  80                 return;
  81         }
  82 
  83         int_status = get_int_status();
  84 
  85         /* if int_status == 0, then the interrupt has already been cleared */
  86         if (int_status) {
  87                 irq = LASAT_IRQ_BASE + ls1bit32(int_status);
  88 
  89                 do_IRQ(irq);
  90         }
  91 }
  92 
  93 static struct irqaction cascade = {
  94         .handler        = no_action,
  95         .name           = "cascade",
  96         .flags          = IRQF_NO_THREAD,
  97 };
  98 
  99 void __init arch_init_irq(void)
 100 {
 101         int i;
 102 
 103         if (IS_LASAT_200()) {
 104                 lasat_int_status = (void *)LASAT_INT_STATUS_REG_200;
 105                 lasat_int_mask = (void *)LASAT_INT_MASK_REG_200;
 106                 lasat_int_mask_shift = LASATINT_MASK_SHIFT_200;
 107                 get_int_status = get_int_status_200;
 108                 *lasat_int_mask &= 0xffff;
 109         } else {
 110                 lasat_int_status = (void *)LASAT_INT_STATUS_REG_100;
 111                 lasat_int_mask = (void *)LASAT_INT_MASK_REG_100;
 112                 lasat_int_mask_shift = LASATINT_MASK_SHIFT_100;
 113                 get_int_status = get_int_status_100;
 114                 *lasat_int_mask = 0;
 115         }
 116 
 117         mips_cpu_irq_init();
 118 
 119         for (i = LASAT_IRQ_BASE; i <= LASAT_IRQ_END; i++)
 120                 irq_set_chip_and_handler(i, &lasat_irq_type, handle_level_irq);
 121 
 122         setup_irq(LASAT_CASCADE_IRQ, &cascade);
 123 }

/* [<][>][^][v][top][bottom][index][help] */