Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
0004  */
0005 
0006 #include <linux/interrupt.h>
0007 #include <linux/irq.h>
0008 #include <asm/irq_cpu.h>
0009 
0010 #include <loongson1.h>
0011 #include <irq.h>
0012 
0013 #define LS1X_INTC_REG(n, x) \
0014         ((void __iomem *)KSEG1ADDR(LS1X_INTC_BASE + (n * 0x18) + (x)))
0015 
0016 #define LS1X_INTC_INTISR(n)     LS1X_INTC_REG(n, 0x0)
0017 #define LS1X_INTC_INTIEN(n)     LS1X_INTC_REG(n, 0x4)
0018 #define LS1X_INTC_INTSET(n)     LS1X_INTC_REG(n, 0x8)
0019 #define LS1X_INTC_INTCLR(n)     LS1X_INTC_REG(n, 0xc)
0020 #define LS1X_INTC_INTPOL(n)     LS1X_INTC_REG(n, 0x10)
0021 #define LS1X_INTC_INTEDGE(n)        LS1X_INTC_REG(n, 0x14)
0022 
0023 static void ls1x_irq_ack(struct irq_data *d)
0024 {
0025     unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f;
0026     unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5;
0027 
0028     __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n))
0029             | (1 << bit), LS1X_INTC_INTCLR(n));
0030 }
0031 
0032 static void ls1x_irq_mask(struct irq_data *d)
0033 {
0034     unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f;
0035     unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5;
0036 
0037     __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n))
0038             & ~(1 << bit), LS1X_INTC_INTIEN(n));
0039 }
0040 
0041 static void ls1x_irq_mask_ack(struct irq_data *d)
0042 {
0043     unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f;
0044     unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5;
0045 
0046     __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n))
0047             & ~(1 << bit), LS1X_INTC_INTIEN(n));
0048     __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n))
0049             | (1 << bit), LS1X_INTC_INTCLR(n));
0050 }
0051 
0052 static void ls1x_irq_unmask(struct irq_data *d)
0053 {
0054     unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f;
0055     unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5;
0056 
0057     __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n))
0058             | (1 << bit), LS1X_INTC_INTIEN(n));
0059 }
0060 
0061 static int ls1x_irq_settype(struct irq_data *d, unsigned int type)
0062 {
0063     unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f;
0064     unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5;
0065 
0066     switch (type) {
0067     case IRQ_TYPE_LEVEL_HIGH:
0068         __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n))
0069             | (1 << bit), LS1X_INTC_INTPOL(n));
0070         __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n))
0071             & ~(1 << bit), LS1X_INTC_INTEDGE(n));
0072         break;
0073     case IRQ_TYPE_LEVEL_LOW:
0074         __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n))
0075             & ~(1 << bit), LS1X_INTC_INTPOL(n));
0076         __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n))
0077             & ~(1 << bit), LS1X_INTC_INTEDGE(n));
0078         break;
0079     case IRQ_TYPE_EDGE_RISING:
0080         __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n))
0081             | (1 << bit), LS1X_INTC_INTPOL(n));
0082         __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n))
0083             | (1 << bit), LS1X_INTC_INTEDGE(n));
0084         break;
0085     case IRQ_TYPE_EDGE_FALLING:
0086         __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n))
0087             & ~(1 << bit), LS1X_INTC_INTPOL(n));
0088         __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n))
0089             | (1 << bit), LS1X_INTC_INTEDGE(n));
0090         break;
0091     case IRQ_TYPE_EDGE_BOTH:
0092         __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n))
0093             & ~(1 << bit), LS1X_INTC_INTPOL(n));
0094         __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n))
0095             | (1 << bit), LS1X_INTC_INTEDGE(n));
0096         break;
0097     case IRQ_TYPE_NONE:
0098         break;
0099     default:
0100         return -EINVAL;
0101     }
0102 
0103     return 0;
0104 }
0105 
0106 static struct irq_chip ls1x_irq_chip = {
0107     .name       = "LS1X-INTC",
0108     .irq_ack    = ls1x_irq_ack,
0109     .irq_mask   = ls1x_irq_mask,
0110     .irq_mask_ack   = ls1x_irq_mask_ack,
0111     .irq_unmask = ls1x_irq_unmask,
0112     .irq_set_type   = ls1x_irq_settype,
0113 };
0114 
0115 static void ls1x_irq_dispatch(int n)
0116 {
0117     u32 int_status, irq;
0118 
0119     /* Get pending sources, masked by current enables */
0120     int_status = __raw_readl(LS1X_INTC_INTISR(n)) &
0121             __raw_readl(LS1X_INTC_INTIEN(n));
0122 
0123     if (int_status) {
0124         irq = LS1X_IRQ(n, __ffs(int_status));
0125         do_IRQ(irq);
0126     }
0127 }
0128 
0129 asmlinkage void plat_irq_dispatch(void)
0130 {
0131     unsigned int pending;
0132 
0133     pending = read_c0_cause() & read_c0_status() & ST0_IM;
0134 
0135     if (pending & CAUSEF_IP7)
0136         do_IRQ(TIMER_IRQ);
0137     else if (pending & CAUSEF_IP2)
0138         ls1x_irq_dispatch(0); /* INT0 */
0139     else if (pending & CAUSEF_IP3)
0140         ls1x_irq_dispatch(1); /* INT1 */
0141     else if (pending & CAUSEF_IP4)
0142         ls1x_irq_dispatch(2); /* INT2 */
0143     else if (pending & CAUSEF_IP5)
0144         ls1x_irq_dispatch(3); /* INT3 */
0145     else if (pending & CAUSEF_IP6)
0146         ls1x_irq_dispatch(4); /* INT4 */
0147     else
0148         spurious_interrupt();
0149 
0150 }
0151 
0152 static void __init ls1x_irq_init(int base)
0153 {
0154     int n;
0155 
0156     /* Disable interrupts and clear pending,
0157      * setup all IRQs as high level triggered
0158      */
0159     for (n = 0; n < INTN; n++) {
0160         __raw_writel(0x0, LS1X_INTC_INTIEN(n));
0161         __raw_writel(0xffffffff, LS1X_INTC_INTCLR(n));
0162         __raw_writel(0xffffffff, LS1X_INTC_INTPOL(n));
0163         /* set DMA0, DMA1 and DMA2 to edge trigger */
0164         __raw_writel(n ? 0x0 : 0xe000, LS1X_INTC_INTEDGE(n));
0165     }
0166 
0167 
0168     for (n = base; n < NR_IRQS; n++) {
0169         irq_set_chip_and_handler(n, &ls1x_irq_chip,
0170                      handle_level_irq);
0171     }
0172 
0173     if (request_irq(INT0_IRQ, no_action, IRQF_NO_THREAD, "cascade", NULL))
0174         pr_err("Failed to request irq %d (cascade)\n", INT0_IRQ);
0175     if (request_irq(INT1_IRQ, no_action, IRQF_NO_THREAD, "cascade", NULL))
0176         pr_err("Failed to request irq %d (cascade)\n", INT1_IRQ);
0177     if (request_irq(INT2_IRQ, no_action, IRQF_NO_THREAD, "cascade", NULL))
0178         pr_err("Failed to request irq %d (cascade)\n", INT2_IRQ);
0179     if (request_irq(INT3_IRQ, no_action, IRQF_NO_THREAD, "cascade", NULL))
0180         pr_err("Failed to request irq %d (cascade)\n", INT3_IRQ);
0181 #if defined(CONFIG_LOONGSON1_LS1C)
0182     if (request_irq(INT4_IRQ, no_action, IRQF_NO_THREAD, "cascade", NULL))
0183         pr_err("Failed to request irq %d (cascade)\n", INT4_IRQ);
0184 #endif
0185 }
0186 
0187 void __init arch_init_irq(void)
0188 {
0189     mips_cpu_irq_init();
0190     ls1x_irq_init(LS1X_IRQ_BASE);
0191 }