Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARC: Interrupt Handling

This contains:
-bootup arch IRQ init: init_IRQ(), arc_init_IRQ()
-generic IRQ subsystem glue: arch_do_IRQ()
-basic IRQ chip setup for in-core intc

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Cc: Thomas Gleixner <tglx@linutronix.de>

+152 -2
+3
arch/arc/include/asm/arcregs.h
··· 11 11 12 12 #ifdef __KERNEL__ 13 13 14 + /* Build Configuration Registers */ 15 + #define ARC_REG_VECBASE_BCR 0x68 16 + 14 17 /* status32 Bits Positions */ 15 18 #define STATUS_H_BIT 0 /* CPU Halted */ 16 19 #define STATUS_E1_BIT 1 /* Int 1 enable */
+7
arch/arc/include/asm/hw_irq.h
··· 1 + /* 2 + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */
+22
arch/arc/include/asm/irq.h
··· 1 + /* 2 + * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #ifndef __ASM_ARC_IRQ_H 10 + #define __ASM_ARC_IRQ_H 11 + 12 + /* Platform Independent IRQs */ 13 + #define TIMER0_IRQ 3 14 + #define TIMER1_IRQ 4 15 + 16 + #include <asm-generic/irq.h> 17 + 18 + extern void __init arc_init_IRQ(void); 19 + extern void __init plat_init_IRQ(void); 20 + extern int __init get_hw_config_num_irq(void); 21 + 22 + #endif
+105 -2
arch/arc/kernel/irq.c
··· 9 9 10 10 #include <linux/interrupt.h> 11 11 #include <linux/module.h> 12 - #include <asm/irqflags.h> 13 - #include <asm/arcregs.h> 12 + #include <asm/sections.h> 13 + #include <asm/irq.h> 14 + 15 + /* 16 + * Early Hardware specific Interrupt setup 17 + * -Called very early (start_kernel -> setup_arch -> setup_processor) 18 + * -Platform Independent (must for any ARC700) 19 + * -Needed for each CPU (hence not foldable into init_IRQ) 20 + * 21 + * what it does ? 22 + * -setup Vector Table Base Reg - in case Linux not linked at 0x8000_0000 23 + * -Disable all IRQs (on CPU side) 24 + */ 25 + void __init arc_init_IRQ(void) 26 + { 27 + int level_mask = level_mask; 28 + 29 + write_aux_reg(AUX_INTR_VEC_BASE, _int_vec_base_lds); 30 + 31 + /* Disable all IRQs: enable them as devices request */ 32 + write_aux_reg(AUX_IENABLE, 0); 33 + } 34 + 35 + /* 36 + * ARC700 core includes a simple on-chip intc supporting 37 + * -per IRQ enable/disable 38 + * -2 levels of interrupts (high/low) 39 + * -all interrupts being level triggered 40 + * 41 + * To reduce platform code, we assume all IRQs directly hooked-up into intc. 42 + * Platforms with external intc, hence cascaded IRQs, are free to over-ride 43 + * below, per IRQ. 44 + */ 45 + 46 + static void arc_mask_irq(struct irq_data *data) 47 + { 48 + arch_mask_irq(data->irq); 49 + } 50 + 51 + static void arc_unmask_irq(struct irq_data *data) 52 + { 53 + arch_unmask_irq(data->irq); 54 + } 55 + 56 + static struct irq_chip onchip_intc = { 57 + .name = "ARC In-core Intc", 58 + .irq_mask = arc_mask_irq, 59 + .irq_unmask = arc_unmask_irq, 60 + }; 61 + 62 + void __init init_onchip_IRQ(void) 63 + { 64 + int i; 65 + 66 + for (i = 0; i < NR_IRQS; i++) 67 + irq_set_chip_and_handler(i, &onchip_intc, handle_level_irq); 68 + 69 + #ifdef CONFIG_SMP 70 + irq_set_chip_and_handler(TIMER0_IRQ, &onchip_intc, handle_percpu_irq); 71 + #endif 72 + } 73 + 74 + /* 75 + * Late Interrupt system init called from start_kernel for Boot CPU only 76 + * 77 + * Since slab must already be initialized, platforms can start doing any 78 + * needed request_irq( )s 79 + */ 80 + void __init init_IRQ(void) 81 + { 82 + init_onchip_IRQ(); 83 + plat_init_IRQ(); 84 + } 85 + 86 + /* 87 + * "C" Entry point for any ARC ISR, called from low level vector handler 88 + * @irq is the vector number read from ICAUSE reg of on-chip intc 89 + */ 90 + void arch_do_IRQ(unsigned int irq, struct pt_regs *regs) 91 + { 92 + struct pt_regs *old_regs = set_irq_regs(regs); 93 + 94 + irq_enter(); 95 + generic_handle_irq(irq); 96 + irq_exit(); 97 + set_irq_regs(old_regs); 98 + } 99 + 100 + int __init get_hw_config_num_irq(void) 101 + { 102 + uint32_t val = read_aux_reg(ARC_REG_VECBASE_BCR); 103 + 104 + switch (val & 0x03) { 105 + case 0: 106 + return 16; 107 + case 1: 108 + return 32; 109 + case 2: 110 + return 8; 111 + default: 112 + return 0; 113 + } 114 + 115 + return 0; 116 + } 14 117 15 118 void arch_local_irq_enable(void) 16 119 {
+15
arch/arc/plat-arcfpga/irq.c
··· 1 + /* 2 + * ARC FPGA Platform IRQ hookups 3 + * 4 + * Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com) 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <linux/interrupt.h> 12 + 13 + void __init plat_init_IRQ(void) 14 + { 15 + }