root/arch/sh/boards/mach-se/7724/irq.c

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

DEFINITIONS

This source file includes following definitions.
  1. fpga2irq
  2. get_fpga_irq
  3. disable_se7724_irq
  4. enable_se7724_irq
  5. se7724_irq_demux
  6. init_se7724_IRQ

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * linux/arch/sh/boards/se/7724/irq.c
   4  *
   5  * Copyright (C) 2009 Renesas Solutions Corp.
   6  *
   7  * Kuninori Morimoto <morimoto.kuninori@renesas.com>
   8  *
   9  * Based on  linux/arch/sh/boards/se/7722/irq.c
  10  * Copyright (C) 2007  Nobuhiro Iwamatsu
  11  *
  12  * Hitachi UL SolutionEngine 7724 Support.
  13  */
  14 #include <linux/init.h>
  15 #include <linux/irq.h>
  16 #include <linux/interrupt.h>
  17 #include <linux/export.h>
  18 #include <linux/topology.h>
  19 #include <linux/io.h>
  20 #include <linux/err.h>
  21 #include <mach-se/mach/se7724.h>
  22 
  23 struct fpga_irq {
  24         unsigned long  sraddr;
  25         unsigned long  mraddr;
  26         unsigned short mask;
  27         unsigned int   base;
  28 };
  29 
  30 static unsigned int fpga2irq(unsigned int irq)
  31 {
  32         if (irq >= IRQ0_BASE &&
  33             irq <= IRQ0_END)
  34                 return IRQ0_IRQ;
  35         else if (irq >= IRQ1_BASE &&
  36                  irq <= IRQ1_END)
  37                 return IRQ1_IRQ;
  38         else
  39                 return IRQ2_IRQ;
  40 }
  41 
  42 static struct fpga_irq get_fpga_irq(unsigned int irq)
  43 {
  44         struct fpga_irq set;
  45 
  46         switch (irq) {
  47         case IRQ0_IRQ:
  48                 set.sraddr = IRQ0_SR;
  49                 set.mraddr = IRQ0_MR;
  50                 set.mask   = IRQ0_MASK;
  51                 set.base   = IRQ0_BASE;
  52                 break;
  53         case IRQ1_IRQ:
  54                 set.sraddr = IRQ1_SR;
  55                 set.mraddr = IRQ1_MR;
  56                 set.mask   = IRQ1_MASK;
  57                 set.base   = IRQ1_BASE;
  58                 break;
  59         default:
  60                 set.sraddr = IRQ2_SR;
  61                 set.mraddr = IRQ2_MR;
  62                 set.mask   = IRQ2_MASK;
  63                 set.base   = IRQ2_BASE;
  64                 break;
  65         }
  66 
  67         return set;
  68 }
  69 
  70 static void disable_se7724_irq(struct irq_data *data)
  71 {
  72         unsigned int irq = data->irq;
  73         struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
  74         unsigned int bit = irq - set.base;
  75         __raw_writew(__raw_readw(set.mraddr) | 0x0001 << bit, set.mraddr);
  76 }
  77 
  78 static void enable_se7724_irq(struct irq_data *data)
  79 {
  80         unsigned int irq = data->irq;
  81         struct fpga_irq set = get_fpga_irq(fpga2irq(irq));
  82         unsigned int bit = irq - set.base;
  83         __raw_writew(__raw_readw(set.mraddr) & ~(0x0001 << bit), set.mraddr);
  84 }
  85 
  86 static struct irq_chip se7724_irq_chip __read_mostly = {
  87         .name           = "SE7724-FPGA",
  88         .irq_mask       = disable_se7724_irq,
  89         .irq_unmask     = enable_se7724_irq,
  90 };
  91 
  92 static void se7724_irq_demux(struct irq_desc *desc)
  93 {
  94         unsigned int irq = irq_desc_get_irq(desc);
  95         struct fpga_irq set = get_fpga_irq(irq);
  96         unsigned short intv = __raw_readw(set.sraddr);
  97         unsigned int ext_irq = set.base;
  98 
  99         intv &= set.mask;
 100 
 101         for (; intv; intv >>= 1, ext_irq++) {
 102                 if (!(intv & 1))
 103                         continue;
 104 
 105                 generic_handle_irq(ext_irq);
 106         }
 107 }
 108 
 109 /*
 110  * Initialize IRQ setting
 111  */
 112 void __init init_se7724_IRQ(void)
 113 {
 114         int irq_base, i;
 115 
 116         __raw_writew(0xffff, IRQ0_MR);  /* mask all */
 117         __raw_writew(0xffff, IRQ1_MR);  /* mask all */
 118         __raw_writew(0xffff, IRQ2_MR);  /* mask all */
 119         __raw_writew(0x0000, IRQ0_SR);  /* clear irq */
 120         __raw_writew(0x0000, IRQ1_SR);  /* clear irq */
 121         __raw_writew(0x0000, IRQ2_SR);  /* clear irq */
 122         __raw_writew(0x002a, IRQ_MODE); /* set irq type */
 123 
 124         irq_base = irq_alloc_descs(SE7724_FPGA_IRQ_BASE, SE7724_FPGA_IRQ_BASE,
 125                                    SE7724_FPGA_IRQ_NR, numa_node_id());
 126         if (IS_ERR_VALUE(irq_base)) {
 127                 pr_err("%s: failed hooking irqs for FPGA\n", __func__);
 128                 return;
 129         }
 130 
 131         for (i = 0; i < SE7724_FPGA_IRQ_NR; i++)
 132                 irq_set_chip_and_handler_name(irq_base + i, &se7724_irq_chip,
 133                                               handle_level_irq, "level");
 134 
 135         irq_set_chained_handler(IRQ0_IRQ, se7724_irq_demux);
 136         irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
 137 
 138         irq_set_chained_handler(IRQ1_IRQ, se7724_irq_demux);
 139         irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);
 140 
 141         irq_set_chained_handler(IRQ2_IRQ, se7724_irq_demux);
 142         irq_set_irq_type(IRQ2_IRQ, IRQ_TYPE_LEVEL_LOW);
 143 }

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