root/drivers/irqchip/irq-sa11x0.c

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

DEFINITIONS

This source file includes following definitions.
  1. sa1100_mask_irq
  2. sa1100_unmask_irq
  3. sa1100_set_wake
  4. sa1100_normal_irqdomain_map
  5. sa1100irq_suspend
  6. sa1100irq_resume
  7. sa1100irq_init_devicefs
  8. sa1100_handle_irq
  9. sa11x0_init_irq_nodt

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2015 Dmitry Eremin-Solenikov
   4  * Copyright (C) 1999-2001 Nicolas Pitre
   5  *
   6  * Generic IRQ handling for the SA11x0.
   7  */
   8 #include <linux/init.h>
   9 #include <linux/module.h>
  10 #include <linux/interrupt.h>
  11 #include <linux/io.h>
  12 #include <linux/irq.h>
  13 #include <linux/irqdomain.h>
  14 #include <linux/syscore_ops.h>
  15 #include <linux/irqchip/irq-sa11x0.h>
  16 
  17 #include <soc/sa1100/pwer.h>
  18 
  19 #include <asm/exception.h>
  20 
  21 #define ICIP    0x00  /* IC IRQ Pending reg. */
  22 #define ICMR    0x04  /* IC Mask Reg.        */
  23 #define ICLR    0x08  /* IC Level Reg.       */
  24 #define ICCR    0x0C  /* IC Control Reg.     */
  25 #define ICFP    0x10  /* IC FIQ Pending reg. */
  26 #define ICPR    0x20  /* IC Pending Reg.     */
  27 
  28 static void __iomem *iobase;
  29 
  30 /*
  31  * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
  32  * this is for internal IRQs i.e. from IRQ LCD to RTCAlrm.
  33  */
  34 static void sa1100_mask_irq(struct irq_data *d)
  35 {
  36         u32 reg;
  37 
  38         reg = readl_relaxed(iobase + ICMR);
  39         reg &= ~BIT(d->hwirq);
  40         writel_relaxed(reg, iobase + ICMR);
  41 }
  42 
  43 static void sa1100_unmask_irq(struct irq_data *d)
  44 {
  45         u32 reg;
  46 
  47         reg = readl_relaxed(iobase + ICMR);
  48         reg |= BIT(d->hwirq);
  49         writel_relaxed(reg, iobase + ICMR);
  50 }
  51 
  52 static int sa1100_set_wake(struct irq_data *d, unsigned int on)
  53 {
  54         return sa11x0_sc_set_wake(d->hwirq, on);
  55 }
  56 
  57 static struct irq_chip sa1100_normal_chip = {
  58         .name           = "SC",
  59         .irq_ack        = sa1100_mask_irq,
  60         .irq_mask       = sa1100_mask_irq,
  61         .irq_unmask     = sa1100_unmask_irq,
  62         .irq_set_wake   = sa1100_set_wake,
  63 };
  64 
  65 static int sa1100_normal_irqdomain_map(struct irq_domain *d,
  66                 unsigned int irq, irq_hw_number_t hwirq)
  67 {
  68         irq_set_chip_and_handler(irq, &sa1100_normal_chip,
  69                                  handle_level_irq);
  70 
  71         return 0;
  72 }
  73 
  74 static const struct irq_domain_ops sa1100_normal_irqdomain_ops = {
  75         .map = sa1100_normal_irqdomain_map,
  76         .xlate = irq_domain_xlate_onetwocell,
  77 };
  78 
  79 static struct irq_domain *sa1100_normal_irqdomain;
  80 
  81 static struct sa1100irq_state {
  82         unsigned int    saved;
  83         unsigned int    icmr;
  84         unsigned int    iclr;
  85         unsigned int    iccr;
  86 } sa1100irq_state;
  87 
  88 static int sa1100irq_suspend(void)
  89 {
  90         struct sa1100irq_state *st = &sa1100irq_state;
  91 
  92         st->saved = 1;
  93         st->icmr = readl_relaxed(iobase + ICMR);
  94         st->iclr = readl_relaxed(iobase + ICLR);
  95         st->iccr = readl_relaxed(iobase + ICCR);
  96 
  97         /*
  98          * Disable all GPIO-based interrupts.
  99          */
 100         writel_relaxed(st->icmr & 0xfffff000, iobase + ICMR);
 101 
 102         return 0;
 103 }
 104 
 105 static void sa1100irq_resume(void)
 106 {
 107         struct sa1100irq_state *st = &sa1100irq_state;
 108 
 109         if (st->saved) {
 110                 writel_relaxed(st->iccr, iobase + ICCR);
 111                 writel_relaxed(st->iclr, iobase + ICLR);
 112 
 113                 writel_relaxed(st->icmr, iobase + ICMR);
 114         }
 115 }
 116 
 117 static struct syscore_ops sa1100irq_syscore_ops = {
 118         .suspend        = sa1100irq_suspend,
 119         .resume         = sa1100irq_resume,
 120 };
 121 
 122 static int __init sa1100irq_init_devicefs(void)
 123 {
 124         register_syscore_ops(&sa1100irq_syscore_ops);
 125         return 0;
 126 }
 127 
 128 device_initcall(sa1100irq_init_devicefs);
 129 
 130 static asmlinkage void __exception_irq_entry
 131 sa1100_handle_irq(struct pt_regs *regs)
 132 {
 133         uint32_t icip, icmr, mask;
 134 
 135         do {
 136                 icip = readl_relaxed(iobase + ICIP);
 137                 icmr = readl_relaxed(iobase + ICMR);
 138                 mask = icip & icmr;
 139 
 140                 if (mask == 0)
 141                         break;
 142 
 143                 handle_domain_irq(sa1100_normal_irqdomain,
 144                                 ffs(mask) - 1, regs);
 145         } while (1);
 146 }
 147 
 148 void __init sa11x0_init_irq_nodt(int irq_start, resource_size_t io_start)
 149 {
 150         iobase = ioremap(io_start, SZ_64K);
 151         if (WARN_ON(!iobase))
 152                 return;
 153 
 154         /* disable all IRQs */
 155         writel_relaxed(0, iobase + ICMR);
 156 
 157         /* all IRQs are IRQ, not FIQ */
 158         writel_relaxed(0, iobase + ICLR);
 159 
 160         /*
 161          * Whatever the doc says, this has to be set for the wait-on-irq
 162          * instruction to work... on a SA1100 rev 9 at least.
 163          */
 164         writel_relaxed(1, iobase + ICCR);
 165 
 166         sa1100_normal_irqdomain = irq_domain_add_simple(NULL,
 167                         32, irq_start,
 168                         &sa1100_normal_irqdomain_ops, NULL);
 169 
 170         set_handle_irq(sa1100_handle_irq);
 171 }

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