Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * arch/arm/mach-iop32x/irq.c
0004  *
0005  * Generic IOP32X IRQ handling functionality
0006  *
0007  * Author: Rory Bolt <rorybolt@pacbell.net>
0008  * Copyright (C) 2002 Rory Bolt
0009  */
0010 
0011 #include <linux/init.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/list.h>
0014 #include <asm/mach/irq.h>
0015 #include <asm/irq.h>
0016 #include <asm/mach-types.h>
0017 
0018 #include "hardware.h"
0019 
0020 static u32 iop32x_mask;
0021 
0022 static void intctl_write(u32 val)
0023 {
0024     asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val));
0025 }
0026 
0027 static void intstr_write(u32 val)
0028 {
0029     asm volatile("mcr p6, 0, %0, c4, c0, 0" : : "r" (val));
0030 }
0031 
0032 static u32 iintsrc_read(void)
0033 {
0034     int irq;
0035 
0036     asm volatile("mrc p6, 0, %0, c8, c0, 0" : "=r" (irq));
0037 
0038     return irq;
0039 }
0040 
0041 static void
0042 iop32x_irq_mask(struct irq_data *d)
0043 {
0044     iop32x_mask &= ~(1 << (d->irq - 1));
0045     intctl_write(iop32x_mask);
0046 }
0047 
0048 static void
0049 iop32x_irq_unmask(struct irq_data *d)
0050 {
0051     iop32x_mask |= 1 << (d->irq - 1);
0052     intctl_write(iop32x_mask);
0053 }
0054 
0055 struct irq_chip ext_chip = {
0056     .name       = "IOP32x",
0057     .irq_ack    = iop32x_irq_mask,
0058     .irq_mask   = iop32x_irq_mask,
0059     .irq_unmask = iop32x_irq_unmask,
0060 };
0061 
0062 static void iop_handle_irq(struct pt_regs *regs)
0063 {
0064     u32 mask;
0065 
0066     iop_enable_cp6();
0067 
0068     do {
0069         mask = iintsrc_read();
0070         if (mask)
0071             generic_handle_irq(fls(mask));
0072     } while (mask);
0073 }
0074 
0075 void __init iop32x_init_irq(void)
0076 {
0077     int i;
0078 
0079     iop_init_cp6_handler();
0080     set_handle_irq(iop_handle_irq);
0081 
0082     intctl_write(0);
0083     intstr_write(0);
0084     if (machine_is_glantank() ||
0085         machine_is_iq80321() ||
0086         machine_is_iq31244() ||
0087         machine_is_n2100() ||
0088         machine_is_em7210())
0089         *IOP3XX_PCIIRSR = 0x0f;
0090 
0091     for (i = 1; i < NR_IRQS; i++) {
0092         irq_set_chip_and_handler(i, &ext_chip, handle_level_irq);
0093         irq_clear_status_flags(i, IRQ_NOREQUEST | IRQ_NOPROBE);
0094     }
0095 }