irq.c (1742B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * arch/arm/mach-iop32x/irq.c 4 * 5 * Generic IOP32X IRQ handling functionality 6 * 7 * Author: Rory Bolt <rorybolt@pacbell.net> 8 * Copyright (C) 2002 Rory Bolt 9 */ 10 11#include <linux/init.h> 12#include <linux/interrupt.h> 13#include <linux/list.h> 14#include <asm/mach/irq.h> 15#include <asm/irq.h> 16#include <asm/mach-types.h> 17 18#include "hardware.h" 19 20static u32 iop32x_mask; 21 22static void intctl_write(u32 val) 23{ 24 asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val)); 25} 26 27static void intstr_write(u32 val) 28{ 29 asm volatile("mcr p6, 0, %0, c4, c0, 0" : : "r" (val)); 30} 31 32static u32 iintsrc_read(void) 33{ 34 int irq; 35 36 asm volatile("mrc p6, 0, %0, c8, c0, 0" : "=r" (irq)); 37 38 return irq; 39} 40 41static void 42iop32x_irq_mask(struct irq_data *d) 43{ 44 iop32x_mask &= ~(1 << (d->irq - 1)); 45 intctl_write(iop32x_mask); 46} 47 48static void 49iop32x_irq_unmask(struct irq_data *d) 50{ 51 iop32x_mask |= 1 << (d->irq - 1); 52 intctl_write(iop32x_mask); 53} 54 55struct irq_chip ext_chip = { 56 .name = "IOP32x", 57 .irq_ack = iop32x_irq_mask, 58 .irq_mask = iop32x_irq_mask, 59 .irq_unmask = iop32x_irq_unmask, 60}; 61 62static void iop_handle_irq(struct pt_regs *regs) 63{ 64 u32 mask; 65 66 iop_enable_cp6(); 67 68 do { 69 mask = iintsrc_read(); 70 if (mask) 71 generic_handle_irq(fls(mask)); 72 } while (mask); 73} 74 75void __init iop32x_init_irq(void) 76{ 77 int i; 78 79 iop_init_cp6_handler(); 80 set_handle_irq(iop_handle_irq); 81 82 intctl_write(0); 83 intstr_write(0); 84 if (machine_is_glantank() || 85 machine_is_iq80321() || 86 machine_is_iq31244() || 87 machine_is_n2100() || 88 machine_is_em7210()) 89 *IOP3XX_PCIIRSR = 0x0f; 90 91 for (i = 1; i < NR_IRQS; i++) { 92 irq_set_chip_and_handler(i, &ext_chip, handle_level_irq); 93 irq_clear_status_flags(i, IRQ_NOREQUEST | IRQ_NOPROBE); 94 } 95}