1/* 2 * Portions copyright (C) 2005-2009 Scientific Atlanta 3 * Portions copyright (C) 2009 Cisco Systems, Inc. 4 * 5 * Modified from arch/mips/kernel/irq-rm7000.c: 6 * Copyright (C) 2003 Ralf Baechle 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 */ 13#include <linux/init.h> 14#include <linux/interrupt.h> 15#include <linux/kernel.h> 16 17#include <asm/irq_cpu.h> 18#include <asm/mipsregs.h> 19#include <asm/system.h> 20 21#include <asm/mach-powertv/asic_regs.h> 22 23static inline void unmask_asic_irq(unsigned int irq) 24{ 25 unsigned long enable_bit; 26 27 enable_bit = (1 << (irq & 0x1f)); 28 29 switch (irq >> 5) { 30 case 0: 31 asic_write(asic_read(ien_int_0) | enable_bit, ien_int_0); 32 break; 33 case 1: 34 asic_write(asic_read(ien_int_1) | enable_bit, ien_int_1); 35 break; 36 case 2: 37 asic_write(asic_read(ien_int_2) | enable_bit, ien_int_2); 38 break; 39 case 3: 40 asic_write(asic_read(ien_int_3) | enable_bit, ien_int_3); 41 break; 42 default: 43 BUG(); 44 } 45} 46 47static inline void mask_asic_irq(unsigned int irq) 48{ 49 unsigned long disable_mask; 50 51 disable_mask = ~(1 << (irq & 0x1f)); 52 53 switch (irq >> 5) { 54 case 0: 55 asic_write(asic_read(ien_int_0) & disable_mask, ien_int_0); 56 break; 57 case 1: 58 asic_write(asic_read(ien_int_1) & disable_mask, ien_int_1); 59 break; 60 case 2: 61 asic_write(asic_read(ien_int_2) & disable_mask, ien_int_2); 62 break; 63 case 3: 64 asic_write(asic_read(ien_int_3) & disable_mask, ien_int_3); 65 break; 66 default: 67 BUG(); 68 } 69} 70 71static struct irq_chip asic_irq_chip = { 72 .name = "ASIC Level", 73 .ack = mask_asic_irq, 74 .mask = mask_asic_irq, 75 .mask_ack = mask_asic_irq, 76 .unmask = unmask_asic_irq, 77 .eoi = unmask_asic_irq, 78}; 79 80void __init asic_irq_init(void) 81{ 82 int i; 83 84 /* set priority to 0 */ 85 write_c0_status(read_c0_status() & ~(0x0000fc00)); 86 87 asic_write(0, ien_int_0); 88 asic_write(0, ien_int_1); 89 asic_write(0, ien_int_2); 90 asic_write(0, ien_int_3); 91 92 asic_write(0x0fffffff, int_level_3_3); 93 asic_write(0xffffffff, int_level_3_2); 94 asic_write(0xffffffff, int_level_3_1); 95 asic_write(0xffffffff, int_level_3_0); 96 asic_write(0xffffffff, int_level_2_3); 97 asic_write(0xffffffff, int_level_2_2); 98 asic_write(0xffffffff, int_level_2_1); 99 asic_write(0xffffffff, int_level_2_0); 100 asic_write(0xffffffff, int_level_1_3); 101 asic_write(0xffffffff, int_level_1_2); 102 asic_write(0xffffffff, int_level_1_1); 103 asic_write(0xffffffff, int_level_1_0); 104 asic_write(0xffffffff, int_level_0_3); 105 asic_write(0xffffffff, int_level_0_2); 106 asic_write(0xffffffff, int_level_0_1); 107 asic_write(0xffffffff, int_level_0_0); 108 109 asic_write(0xf, int_int_scan); 110 111 /* 112 * Initialize interrupt handlers. 113 */ 114 for (i = 0; i < NR_IRQS; i++) 115 set_irq_chip_and_handler(i, &asic_irq_chip, handle_level_irq); 116} 117