0001
0002
0003
0004
0005 #include <linux/kernel.h>
0006 #include <linux/init.h>
0007 #include <linux/linkage.h>
0008 #include <linux/interrupt.h>
0009 #include <linux/spinlock.h>
0010 #include <linux/smp.h>
0011 #include <linux/mm.h>
0012 #include <linux/kernel_stat.h>
0013
0014 #include <asm/errno.h>
0015 #include <asm/signal.h>
0016 #include <asm/time.h>
0017 #include <asm/io.h>
0018
0019 #include <asm/sibyte/sb1250_regs.h>
0020 #include <asm/sibyte/sb1250_int.h>
0021 #include <asm/sibyte/sb1250_uart.h>
0022 #include <asm/sibyte/sb1250_scd.h>
0023 #include <asm/sibyte/sb1250.h>
0024
0025
0026
0027
0028
0029
0030
0031
0032 #ifdef CONFIG_SIBYTE_HAS_LDT
0033 extern unsigned long ldt_eoi_space;
0034 #endif
0035
0036
0037 int sb1250_irq_owner[SB1250_NR_IRQS];
0038
0039 static DEFINE_RAW_SPINLOCK(sb1250_imr_lock);
0040
0041 void sb1250_mask_irq(int cpu, int irq)
0042 {
0043 unsigned long flags;
0044 u64 cur_ints;
0045
0046 raw_spin_lock_irqsave(&sb1250_imr_lock, flags);
0047 cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
0048 R_IMR_INTERRUPT_MASK));
0049 cur_ints |= (((u64) 1) << irq);
0050 ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
0051 R_IMR_INTERRUPT_MASK));
0052 raw_spin_unlock_irqrestore(&sb1250_imr_lock, flags);
0053 }
0054
0055 void sb1250_unmask_irq(int cpu, int irq)
0056 {
0057 unsigned long flags;
0058 u64 cur_ints;
0059
0060 raw_spin_lock_irqsave(&sb1250_imr_lock, flags);
0061 cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
0062 R_IMR_INTERRUPT_MASK));
0063 cur_ints &= ~(((u64) 1) << irq);
0064 ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
0065 R_IMR_INTERRUPT_MASK));
0066 raw_spin_unlock_irqrestore(&sb1250_imr_lock, flags);
0067 }
0068
0069 #ifdef CONFIG_SMP
0070 static int sb1250_set_affinity(struct irq_data *d, const struct cpumask *mask,
0071 bool force)
0072 {
0073 int i = 0, old_cpu, cpu, int_on;
0074 unsigned int irq = d->irq;
0075 u64 cur_ints;
0076 unsigned long flags;
0077
0078 i = cpumask_first_and(mask, cpu_online_mask);
0079
0080
0081 cpu = cpu_logical_map(i);
0082
0083
0084 raw_spin_lock_irqsave(&sb1250_imr_lock, flags);
0085
0086
0087 old_cpu = sb1250_irq_owner[irq];
0088 cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(old_cpu) +
0089 R_IMR_INTERRUPT_MASK));
0090 int_on = !(cur_ints & (((u64) 1) << irq));
0091 if (int_on) {
0092
0093 cur_ints |= (((u64) 1) << irq);
0094 ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(old_cpu) +
0095 R_IMR_INTERRUPT_MASK));
0096 }
0097 sb1250_irq_owner[irq] = cpu;
0098 if (int_on) {
0099
0100 cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
0101 R_IMR_INTERRUPT_MASK));
0102 cur_ints &= ~(((u64) 1) << irq);
0103 ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
0104 R_IMR_INTERRUPT_MASK));
0105 }
0106 raw_spin_unlock_irqrestore(&sb1250_imr_lock, flags);
0107
0108 return 0;
0109 }
0110 #endif
0111
0112 static void disable_sb1250_irq(struct irq_data *d)
0113 {
0114 unsigned int irq = d->irq;
0115
0116 sb1250_mask_irq(sb1250_irq_owner[irq], irq);
0117 }
0118
0119 static void enable_sb1250_irq(struct irq_data *d)
0120 {
0121 unsigned int irq = d->irq;
0122
0123 sb1250_unmask_irq(sb1250_irq_owner[irq], irq);
0124 }
0125
0126
0127 static void ack_sb1250_irq(struct irq_data *d)
0128 {
0129 unsigned int irq = d->irq;
0130 #ifdef CONFIG_SIBYTE_HAS_LDT
0131 u64 pending;
0132
0133
0134
0135
0136
0137
0138
0139 pending = __raw_readq(IOADDR(A_IMR_REGISTER(sb1250_irq_owner[irq],
0140 R_IMR_LDT_INTERRUPT)));
0141 pending &= ((u64)1 << (irq));
0142 if (pending) {
0143 int i;
0144 for (i=0; i<NR_CPUS; i++) {
0145 int cpu;
0146 #ifdef CONFIG_SMP
0147 cpu = cpu_logical_map(i);
0148 #else
0149 cpu = i;
0150 #endif
0151
0152
0153
0154
0155 __raw_writeq(pending,
0156 IOADDR(A_IMR_REGISTER(cpu,
0157 R_IMR_LDT_INTERRUPT_CLR)));
0158 }
0159
0160
0161
0162
0163
0164
0165
0166 *(uint32_t *)(ldt_eoi_space+(irq<<16)+(7<<2)) = 0;
0167 }
0168 #endif
0169 sb1250_mask_irq(sb1250_irq_owner[irq], irq);
0170 }
0171
0172 static struct irq_chip sb1250_irq_type = {
0173 .name = "SB1250-IMR",
0174 .irq_mask_ack = ack_sb1250_irq,
0175 .irq_unmask = enable_sb1250_irq,
0176 .irq_mask = disable_sb1250_irq,
0177 #ifdef CONFIG_SMP
0178 .irq_set_affinity = sb1250_set_affinity
0179 #endif
0180 };
0181
0182 void __init init_sb1250_irqs(void)
0183 {
0184 int i;
0185
0186 for (i = 0; i < SB1250_NR_IRQS; i++) {
0187 irq_set_chip_and_handler(i, &sb1250_irq_type,
0188 handle_level_irq);
0189 sb1250_irq_owner[i] = 0;
0190 }
0191 }
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214 #define IMR_IP2_VAL K_INT_MAP_I0
0215 #define IMR_IP3_VAL K_INT_MAP_I1
0216 #define IMR_IP4_VAL K_INT_MAP_I2
0217 #define IMR_IP5_VAL K_INT_MAP_I3
0218 #define IMR_IP6_VAL K_INT_MAP_I4
0219
0220 void __init arch_init_irq(void)
0221 {
0222
0223 unsigned int i;
0224 u64 tmp;
0225 unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
0226 STATUSF_IP1 | STATUSF_IP0;
0227
0228
0229 for (i = 0; i < SB1250_NR_IRQS; i++) {
0230 __raw_writeq(IMR_IP2_VAL,
0231 IOADDR(A_IMR_REGISTER(0,
0232 R_IMR_INTERRUPT_MAP_BASE) +
0233 (i << 3)));
0234 __raw_writeq(IMR_IP2_VAL,
0235 IOADDR(A_IMR_REGISTER(1,
0236 R_IMR_INTERRUPT_MAP_BASE) +
0237 (i << 3)));
0238 }
0239
0240 init_sb1250_irqs();
0241
0242
0243
0244
0245
0246
0247 __raw_writeq(IMR_IP3_VAL,
0248 IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
0249 (K_INT_MBOX_0 << 3)));
0250 __raw_writeq(IMR_IP3_VAL,
0251 IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
0252 (K_INT_MBOX_0 << 3)));
0253
0254
0255 __raw_writeq(0xffffffffffffffffULL,
0256 IOADDR(A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU)));
0257 __raw_writeq(0xffffffffffffffffULL,
0258 IOADDR(A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU)));
0259
0260
0261 tmp = ~((u64) 0) ^ (((u64) 1) << K_INT_MBOX_0);
0262 __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)));
0263 __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)));
0264
0265
0266
0267
0268
0269
0270
0271
0272 change_c0_status(ST0_IM, imask);
0273 }
0274
0275 extern void sb1250_mailbox_interrupt(void);
0276
0277 static inline void dispatch_ip2(void)
0278 {
0279 unsigned int cpu = smp_processor_id();
0280 unsigned long long mask;
0281
0282
0283
0284
0285
0286
0287 mask = __raw_readq(IOADDR(A_IMR_REGISTER(cpu,
0288 R_IMR_INTERRUPT_STATUS_BASE)));
0289 if (mask)
0290 do_IRQ(fls64(mask) - 1);
0291 }
0292
0293 asmlinkage void plat_irq_dispatch(void)
0294 {
0295 unsigned int cpu = smp_processor_id();
0296 unsigned int pending;
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308 pending = read_c0_cause() & read_c0_status() & ST0_IM;
0309
0310 if (pending & CAUSEF_IP7)
0311 do_IRQ(MIPS_CPU_IRQ_BASE + 7);
0312 else if (pending & CAUSEF_IP4)
0313 do_IRQ(K_INT_TIMER_0 + cpu);
0314
0315 #ifdef CONFIG_SMP
0316 else if (pending & CAUSEF_IP3)
0317 sb1250_mailbox_interrupt();
0318 #endif
0319
0320 else if (pending & CAUSEF_IP2)
0321 dispatch_ip2();
0322 else
0323 spurious_interrupt();
0324 }