/* * linux/arch/alpha/kernel/sys_dp264.c * * Copyright (C) 1995 David A Rusling * Copyright (C) 1996, 1999 Jay A Estabrook * Copyright (C) 1998, 1999 Richard Henderson * * Modified by Christopher C. Chimelis, 2001 to * add support for the addition of Shark to the * Tsunami family. * * Code supporting the DP264 (EV6+TSUNAMI). */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "proto.h" #include "irq_impl.h" #include "pci_impl.h" #include "machvec_impl.h" /* Note mask bit is true for ENABLED irqs. */ static unsigned long cached_irq_mask; /* dp264 boards handle at max four CPUs */ static unsigned long cpu_irq_affinity[4] = { 0UL, 0UL, 0UL, 0UL }; DEFINE_SPINLOCK(dp264_irq_lock); static void tsunami_update_irq_hw(unsigned long mask) { register tsunami_cchip *cchip = TSUNAMI_cchip; unsigned long isa_enable = 1UL << 55; register int bcpu = boot_cpuid; #ifdef CONFIG_SMP volatile unsigned long *dim0, *dim1, *dim2, *dim3; unsigned long mask0, mask1, mask2, mask3, dummy; mask &= ~isa_enable; mask0 = mask & cpu_irq_affinity[0]; mask1 = mask & cpu_irq_affinity[1]; mask2 = mask & cpu_irq_affinity[2]; mask3 = mask & cpu_irq_affinity[3]; if (bcpu == 0) mask0 |= isa_enable; else if (bcpu == 1) mask1 |= isa_enable; else if (bcpu == 2) mask2 |= isa_enable; else mask3 |= isa_enable; dim0 = &cchip->dim0.csr; dim1 = &cchip->dim1.csr; dim2 = &cchip->dim2.csr; dim3 = &cchip->dim3.csr; if (!cpu_possible(0)) dim0 = &dummy; if (!cpu_possible(1)) dim1 = &dummy; if (!cpu_possible(2)) dim2 = &dummy; if (!cpu_possible(3)) dim3 = &dummy; *dim0 = mask0; *dim1 = mask1; *dim2 = mask2; *dim3 = mask3; mb(); *dim0; *dim1; *dim2; *dim3; #else volatile unsigned long *dimB; if (bcpu == 0) dimB = &cchip->dim0.csr; else if (bcpu == 1) dimB = &cchip->dim1.csr; else if (bcpu == 2) dimB = &cchip->dim2.csr; else dimB = &cchip->dim3.csr; *dimB = mask | isa_enable; mb(); *dimB; #endif } static void dp264_enable_irq(struct irq_data *d) { spin_lock(&dp264_irq_lock); cached_irq_mask |= 1UL << d->irq; tsunami_update_irq_hw(cached_irq_mask); spin_unlock(&dp264_irq_lock); } static void dp264_disable_irq(struct irq_data *d) { spin_lock(&dp264_irq_lock); cached_irq_mask &= ~(1UL << d->irq); tsunami_update_irq_hw(cached_irq_mask); spin_unlock(&dp264_irq_lock); } static void clipper_enable_irq(struct irq_data *d) { spin_lock(&dp264_irq_lock); cached_irq_mask |= 1UL << (d->irq - 16); tsunami_update_irq_hw(cached_irq_mask);