root/arch/mips/pmcs-msp71xx/msp_irq_slp.c

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

DEFINITIONS

This source file includes following definitions.
  1. unmask_msp_slp_irq
  2. mask_msp_slp_irq
  3. ack_msp_slp_irq
  4. msp_slp_irq_init
  5. msp_slp_irq_dispatch

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * This file define the irq handler for MSP SLM subsystem interrupts.
   4  *
   5  * Copyright 2005-2006 PMC-Sierra, Inc, derived from irq_cpu.c
   6  * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com
   7  */
   8 
   9 #include <linux/init.h>
  10 #include <linux/interrupt.h>
  11 #include <linux/kernel.h>
  12 #include <linux/bitops.h>
  13 
  14 #include <asm/mipsregs.h>
  15 
  16 #include <msp_slp_int.h>
  17 #include <msp_regs.h>
  18 
  19 static inline void unmask_msp_slp_irq(struct irq_data *d)
  20 {
  21         unsigned int irq = d->irq;
  22 
  23         /* check for PER interrupt range */
  24         if (irq < MSP_PER_INTBASE)
  25                 *SLP_INT_MSK_REG |= (1 << (irq - MSP_SLP_INTBASE));
  26         else
  27                 *PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE));
  28 }
  29 
  30 static inline void mask_msp_slp_irq(struct irq_data *d)
  31 {
  32         unsigned int irq = d->irq;
  33 
  34         /* check for PER interrupt range */
  35         if (irq < MSP_PER_INTBASE)
  36                 *SLP_INT_MSK_REG &= ~(1 << (irq - MSP_SLP_INTBASE));
  37         else
  38                 *PER_INT_MSK_REG &= ~(1 << (irq - MSP_PER_INTBASE));
  39 }
  40 
  41 /*
  42  * While we ack the interrupt interrupts are disabled and thus we don't need
  43  * to deal with concurrency issues.  Same for msp_slp_irq_end.
  44  */
  45 static inline void ack_msp_slp_irq(struct irq_data *d)
  46 {
  47         unsigned int irq = d->irq;
  48 
  49         /* check for PER interrupt range */
  50         if (irq < MSP_PER_INTBASE)
  51                 *SLP_INT_STS_REG = (1 << (irq - MSP_SLP_INTBASE));
  52         else
  53                 *PER_INT_STS_REG = (1 << (irq - MSP_PER_INTBASE));
  54 }
  55 
  56 static struct irq_chip msp_slp_irq_controller = {
  57         .name = "MSP_SLP",
  58         .irq_ack = ack_msp_slp_irq,
  59         .irq_mask = mask_msp_slp_irq,
  60         .irq_unmask = unmask_msp_slp_irq,
  61 };
  62 
  63 void __init msp_slp_irq_init(void)
  64 {
  65         int i;
  66 
  67         /* Mask/clear interrupts. */
  68         *SLP_INT_MSK_REG = 0x00000000;
  69         *PER_INT_MSK_REG = 0x00000000;
  70         *SLP_INT_STS_REG = 0xFFFFFFFF;
  71         *PER_INT_STS_REG = 0xFFFFFFFF;
  72 
  73         /* initialize all the IRQ descriptors */
  74         for (i = MSP_SLP_INTBASE; i < MSP_PER_INTBASE + 32; i++)
  75                 irq_set_chip_and_handler(i, &msp_slp_irq_controller,
  76                                          handle_level_irq);
  77 }
  78 
  79 void msp_slp_irq_dispatch(void)
  80 {
  81         u32 pending;
  82         int intbase;
  83 
  84         intbase = MSP_SLP_INTBASE;
  85         pending = *SLP_INT_STS_REG & *SLP_INT_MSK_REG;
  86 
  87         /* check for PER interrupt */
  88         if (pending == (1 << (MSP_INT_PER - MSP_SLP_INTBASE))) {
  89                 intbase = MSP_PER_INTBASE;
  90                 pending = *PER_INT_STS_REG & *PER_INT_MSK_REG;
  91         }
  92 
  93         /* check for spurious interrupt */
  94         if (pending == 0x00000000) {
  95                 printk(KERN_ERR "Spurious %s interrupt?\n",
  96                         (intbase == MSP_SLP_INTBASE) ? "SLP" : "PER");
  97                 return;
  98         }
  99 
 100         /* dispatch the irq */
 101         do_IRQ(ffs(pending) + intbase - 1);
 102 }

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