1 /* 2 * OpenRISC irq.c 3 * 4 * Linux architectural port borrowing liberally from similar works of 5 * others. All original copyrights apply as per the original source 6 * declaration. 7 * 8 * Modifications for the OpenRISC architecture: 9 * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se> 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License 13 * as published by the Free Software Foundation; either version 14 * 2 of the License, or (at your option) any later version. 15 */ 16 17 #include <linux/interrupt.h> 18 #include <linux/init.h> 19 #include <linux/of.h> 20 #include <linux/ftrace.h> 21 #include <linux/irq.h> 22 #include <linux/export.h> 23 #include <linux/irqdomain.h> 24 #include <linux/irqflags.h> 25 26 /* read interrupt enabled status */ 27 unsigned long arch_local_save_flags(void) 28 { 29 return mfspr(SPR_SR) & (SPR_SR_IEE|SPR_SR_TEE); 30 } 31 EXPORT_SYMBOL(arch_local_save_flags); 32 33 /* set interrupt enabled status */ 34 void arch_local_irq_restore(unsigned long flags) 35 { 36 mtspr(SPR_SR, ((mfspr(SPR_SR) & ~(SPR_SR_IEE|SPR_SR_TEE)) | flags)); 37 } 38 EXPORT_SYMBOL(arch_local_irq_restore); 39 40 41 /* OR1K PIC implementation */ 42 43 /* We're a couple of cycles faster than the generic implementations with 44 * these 'fast' versions. 45 */ 46 47 static void or1k_pic_mask(struct irq_data *data) 48 { 49 mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->hwirq)); 50 } 51 52 static void or1k_pic_unmask(struct irq_data *data) 53 { 54 mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (1UL << data->hwirq)); 55 } 56 57 static void or1k_pic_ack(struct irq_data *data) 58 { 59 /* EDGE-triggered interrupts need to be ack'ed in order to clear 60 * the latch. 61 * LEVEL-triggered interrupts do not need to be ack'ed; however, 62 * ack'ing the interrupt has no ill-effect and is quicker than 63 * trying to figure out what type it is... 64 */ 65 66 /* The OpenRISC 1000 spec says to write a 1 to the bit to ack the 67 * interrupt, but the OR1200 does this backwards and requires a 0 68 * to be written... 69 */ 70 71 #ifdef CONFIG_OR1K_1200 72 /* There are two oddities with the OR1200 PIC implementation: 73 * i) LEVEL-triggered interrupts are latched and need to be cleared 74 * ii) the interrupt latch is cleared by writing a 0 to the bit, 75 * as opposed to a 1 as mandated by the spec 76 */ 77 78 mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->hwirq)); 79 #else 80 WARN(1, "Interrupt handling possibly broken\n"); 81 mtspr(SPR_PICSR, (1UL << data->hwirq)); 82 #endif 83 } 84 85 static void or1k_pic_mask_ack(struct irq_data *data) 86 { 87 /* Comments for pic_ack apply here, too */ 88 89 #ifdef CONFIG_OR1K_1200 90 mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(1UL << data->hwirq)); 91 mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(1UL << data->hwirq)); 92 #else 93 WARN(1, "Interrupt handling possibly broken\n"); 94 mtspr(SPR_PICMR, (1UL << data->hwirq)); 95 mtspr(SPR_PICSR, (1UL << data->hwirq)); 96 #endif 97 } 98 99 #if 0 100 static int or1k_pic_set_type(struct irq_data *data, unsigned int flow_type) 101 { 102 /* There's nothing to do in the PIC configuration when changing 103 * flow type. Level and edge-triggered interrupts are both 104 * supported, but it's PIC-implementation specific which type 105 * is handled. */ 106 107 return irq_setup_alt_chip(data, flow_type); 108 } 109 #endif 110 111 static struct irq_chip or1k_dev = { 112 .name = "or1k-PIC", 113 .irq_unmask = or1k_pic_unmask, 114 .irq_mask = or1k_pic_mask, 115 .irq_ack = or1k_pic_ack, 116 .irq_mask_ack = or1k_pic_mask_ack, 117 }; 118 119 static struct irq_domain *root_domain; 120 121 static inline int pic_get_irq(int first) 122 { 123 int hwirq; 124 125 hwirq = ffs(mfspr(SPR_PICSR) >> first); 126 if (!hwirq) 127 return NO_IRQ; 128 else 129 hwirq = hwirq + first -1; 130 131 return irq_find_mapping(root_domain, hwirq); 132 } 133 134 135 static int or1k_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) 136 { 137 irq_set_chip_and_handler_name(irq, &or1k_dev, 138 handle_level_irq, "level"); 139 irq_set_status_flags(irq, IRQ_LEVEL | IRQ_NOPROBE); 140 141 return 0; 142 } 143 144 static const struct irq_domain_ops or1k_irq_domain_ops = { 145 .xlate = irq_domain_xlate_onecell, 146 .map = or1k_map, 147 }; 148 149 /* 150 * This sets up the IRQ domain for the PIC built in to the OpenRISC 151 * 1000 CPU. This is the "root" domain as these are the interrupts 152 * that directly trigger an exception in the CPU. 153 */ 154 static void __init or1k_irq_init(void) 155 { 156 struct device_node *intc = NULL; 157 158 /* The interrupt controller device node is mandatory */ 159 intc = of_find_compatible_node(NULL, NULL, "opencores,or1k-pic"); 160 BUG_ON(!intc); 161 162 /* Disable all interrupts until explicitly requested */ 163 mtspr(SPR_PICMR, (0UL)); 164 165 root_domain = irq_domain_add_linear(intc, 32, 166 &or1k_irq_domain_ops, NULL); 167 } 168 169 void __init init_IRQ(void) 170 { 171 or1k_irq_init(); 172 } 173 174 void __irq_entry do_IRQ(struct pt_regs *regs) 175 { 176 int irq = -1; 177 struct pt_regs *old_regs = set_irq_regs(regs); 178 179 irq_enter(); 180 181 while ((irq = pic_get_irq(irq + 1)) != NO_IRQ) 182 generic_handle_irq(irq); 183 184 irq_exit(); 185 set_irq_regs(old_regs); 186 } 187