1/* 2 * arch/score/kernel/irq.c 3 * 4 * Score Processor version. 5 * 6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd. 7 * Chen Liqin <liqin.chen@sunplusct.com> 8 * Lennox Wu <lennox.wu@sunplusct.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, see the file COPYING, or write 22 * to the Free Software Foundation, Inc., 23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 */ 25 26#include <linux/interrupt.h> 27#include <linux/kernel_stat.h> 28#include <linux/seq_file.h> 29 30#include <asm/io.h> 31 32/* the interrupt controller is hardcoded at this address */ 33#define SCORE_PIC ((u32 __iomem __force *)0x95F50000) 34 35#define INT_PNDL 0 36#define INT_PNDH 1 37#define INT_PRIORITY_M 2 38#define INT_PRIORITY_SG0 4 39#define INT_PRIORITY_SG1 5 40#define INT_PRIORITY_SG2 6 41#define INT_PRIORITY_SG3 7 42#define INT_MASKL 8 43#define INT_MASKH 9 44 45/* 46 * handles all normal device IRQs 47 */ 48asmlinkage void do_IRQ(int irq) 49{ 50 irq_enter(); 51 generic_handle_irq(irq); 52 irq_exit(); 53} 54 55static void score_mask(struct irq_data *d) 56{ 57 unsigned int irq_source = 63 - d->irq; 58 59 if (irq_source < 32) 60 __raw_writel((__raw_readl(SCORE_PIC + INT_MASKL) | \ 61 (1 << irq_source)), SCORE_PIC + INT_MASKL); 62 else 63 __raw_writel((__raw_readl(SCORE_PIC + INT_MASKH) | \ 64 (1 << (irq_source - 32))), SCORE_PIC + INT_MASKH); 65} 66 67static void score_unmask(struct irq_data *d) 68{ 69 unsigned int irq_source = 63 - d->irq; 70 71 if (irq_source < 32) 72 __raw_writel((__raw_readl(SCORE_PIC + INT_MASKL) & \ 73 ~(1 << irq_source)), SCORE_PIC + INT_MASKL); 74 else 75 __raw_writel((__raw_readl(SCORE_PIC + INT_MASKH) & \ 76 ~(1 << (irq_source - 32))), SCORE_PIC + INT_MASKH); 77} 78 79struct irq_chip score_irq_chip = { 80 .name = "Score7-level", 81 .irq_mask = score_mask, 82 .irq_mask_ack = score_mask, 83 .irq_unmask = score_unmask, 84}; 85 86/* 87 * initialise the interrupt system 88 */ 89void __init init_IRQ(void) 90{ 91 int index; 92 unsigned long target_addr; 93 94 for (index = 0; index < NR_IRQS; ++index) 95 irq_set_chip_and_handler(index, &score_irq_chip, 96 handle_level_irq); 97 98 for (target_addr = IRQ_VECTOR_BASE_ADDR; 99 target_addr <= IRQ_VECTOR_END_ADDR; 100 target_addr += IRQ_VECTOR_SIZE) 101 memcpy((void *)target_addr, \ 102 interrupt_exception_vector, IRQ_VECTOR_SIZE); 103 104 __raw_writel(0xffffffff, SCORE_PIC + INT_MASKL); 105 __raw_writel(0xffffffff, SCORE_PIC + INT_MASKH); 106 107 __asm__ __volatile__( 108 "mtcr %0, cr3\n\t" 109 : : "r" (EXCEPTION_VECTOR_BASE_ADDR | \ 110 VECTOR_ADDRESS_OFFSET_MODE16)); 111} 112