Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2015 Dmitry Eremin-Solenikov
0004  * Copyright (C) 1999-2001 Nicolas Pitre
0005  *
0006  * Generic IRQ handling for the SA11x0.
0007  */
0008 #include <linux/init.h>
0009 #include <linux/module.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/io.h>
0012 #include <linux/irq.h>
0013 #include <linux/irqdomain.h>
0014 #include <linux/syscore_ops.h>
0015 #include <linux/irqchip/irq-sa11x0.h>
0016 
0017 #include <soc/sa1100/pwer.h>
0018 
0019 #include <asm/exception.h>
0020 
0021 #define ICIP    0x00  /* IC IRQ Pending reg. */
0022 #define ICMR    0x04  /* IC Mask Reg.        */
0023 #define ICLR    0x08  /* IC Level Reg.       */
0024 #define ICCR    0x0C  /* IC Control Reg.     */
0025 #define ICFP    0x10  /* IC FIQ Pending reg. */
0026 #define ICPR    0x20  /* IC Pending Reg.     */
0027 
0028 static void __iomem *iobase;
0029 
0030 /*
0031  * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
0032  * this is for internal IRQs i.e. from IRQ LCD to RTCAlrm.
0033  */
0034 static void sa1100_mask_irq(struct irq_data *d)
0035 {
0036     u32 reg;
0037 
0038     reg = readl_relaxed(iobase + ICMR);
0039     reg &= ~BIT(d->hwirq);
0040     writel_relaxed(reg, iobase + ICMR);
0041 }
0042 
0043 static void sa1100_unmask_irq(struct irq_data *d)
0044 {
0045     u32 reg;
0046 
0047     reg = readl_relaxed(iobase + ICMR);
0048     reg |= BIT(d->hwirq);
0049     writel_relaxed(reg, iobase + ICMR);
0050 }
0051 
0052 static int sa1100_set_wake(struct irq_data *d, unsigned int on)
0053 {
0054     return sa11x0_sc_set_wake(d->hwirq, on);
0055 }
0056 
0057 static struct irq_chip sa1100_normal_chip = {
0058     .name       = "SC",
0059     .irq_ack    = sa1100_mask_irq,
0060     .irq_mask   = sa1100_mask_irq,
0061     .irq_unmask = sa1100_unmask_irq,
0062     .irq_set_wake   = sa1100_set_wake,
0063 };
0064 
0065 static int sa1100_normal_irqdomain_map(struct irq_domain *d,
0066         unsigned int irq, irq_hw_number_t hwirq)
0067 {
0068     irq_set_chip_and_handler(irq, &sa1100_normal_chip,
0069                  handle_level_irq);
0070 
0071     return 0;
0072 }
0073 
0074 static const struct irq_domain_ops sa1100_normal_irqdomain_ops = {
0075     .map = sa1100_normal_irqdomain_map,
0076     .xlate = irq_domain_xlate_onetwocell,
0077 };
0078 
0079 static struct irq_domain *sa1100_normal_irqdomain;
0080 
0081 static struct sa1100irq_state {
0082     unsigned int    saved;
0083     unsigned int    icmr;
0084     unsigned int    iclr;
0085     unsigned int    iccr;
0086 } sa1100irq_state;
0087 
0088 static int sa1100irq_suspend(void)
0089 {
0090     struct sa1100irq_state *st = &sa1100irq_state;
0091 
0092     st->saved = 1;
0093     st->icmr = readl_relaxed(iobase + ICMR);
0094     st->iclr = readl_relaxed(iobase + ICLR);
0095     st->iccr = readl_relaxed(iobase + ICCR);
0096 
0097     /*
0098      * Disable all GPIO-based interrupts.
0099      */
0100     writel_relaxed(st->icmr & 0xfffff000, iobase + ICMR);
0101 
0102     return 0;
0103 }
0104 
0105 static void sa1100irq_resume(void)
0106 {
0107     struct sa1100irq_state *st = &sa1100irq_state;
0108 
0109     if (st->saved) {
0110         writel_relaxed(st->iccr, iobase + ICCR);
0111         writel_relaxed(st->iclr, iobase + ICLR);
0112 
0113         writel_relaxed(st->icmr, iobase + ICMR);
0114     }
0115 }
0116 
0117 static struct syscore_ops sa1100irq_syscore_ops = {
0118     .suspend    = sa1100irq_suspend,
0119     .resume     = sa1100irq_resume,
0120 };
0121 
0122 static int __init sa1100irq_init_devicefs(void)
0123 {
0124     register_syscore_ops(&sa1100irq_syscore_ops);
0125     return 0;
0126 }
0127 
0128 device_initcall(sa1100irq_init_devicefs);
0129 
0130 static asmlinkage void __exception_irq_entry
0131 sa1100_handle_irq(struct pt_regs *regs)
0132 {
0133     uint32_t icip, icmr, mask;
0134 
0135     do {
0136         icip = readl_relaxed(iobase + ICIP);
0137         icmr = readl_relaxed(iobase + ICMR);
0138         mask = icip & icmr;
0139 
0140         if (mask == 0)
0141             break;
0142 
0143         generic_handle_domain_irq(sa1100_normal_irqdomain,
0144                       ffs(mask) - 1);
0145     } while (1);
0146 }
0147 
0148 void __init sa11x0_init_irq_nodt(int irq_start, resource_size_t io_start)
0149 {
0150     iobase = ioremap(io_start, SZ_64K);
0151     if (WARN_ON(!iobase))
0152         return;
0153 
0154     /* disable all IRQs */
0155     writel_relaxed(0, iobase + ICMR);
0156 
0157     /* all IRQs are IRQ, not FIQ */
0158     writel_relaxed(0, iobase + ICLR);
0159 
0160     /*
0161      * Whatever the doc says, this has to be set for the wait-on-irq
0162      * instruction to work... on a SA1100 rev 9 at least.
0163      */
0164     writel_relaxed(1, iobase + ICCR);
0165 
0166     sa1100_normal_irqdomain = irq_domain_add_simple(NULL,
0167             32, irq_start,
0168             &sa1100_normal_irqdomain_ops, NULL);
0169 
0170     set_handle_irq(sa1100_handle_irq);
0171 }