patch-2.3.49 linux/arch/alpha/kernel/sys_dp264.c
Next file: linux/arch/alpha/kernel/sys_eb64p.c
Previous file: linux/arch/alpha/kernel/sys_cabriolet.c
Back to the patch index
Back to the overall index
- Lines: 199
- Date:
Mon Feb 28 14:54:30 2000
- Orig file:
v2.3.48/linux/arch/alpha/kernel/sys_dp264.c
- Orig date:
Sat Feb 26 22:31:38 2000
diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_dp264.c linux/arch/alpha/kernel/sys_dp264.c
@@ -35,6 +35,10 @@
/* 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];
+
+spinlock_t dp264_irq_lock = SPIN_LOCK_UNLOCKED;
static void
tsunami_update_irq_hw(unsigned long mask, unsigned long isa_enable)
@@ -50,9 +54,14 @@
mask0 = mask1 = mask2 = mask3 = mask;
maskB = mask | isa_enable;
if (bcpu == 0) mask0 = maskB;
- if (bcpu == 1) mask1 = maskB;
- if (bcpu == 2) mask2 = maskB;
- if (bcpu == 3) mask3 = maskB;
+ else if (bcpu == 1) mask1 = maskB;
+ else if (bcpu == 2) mask2 = maskB;
+ else if (bcpu == 3) mask3 = maskB;
+
+ mask0 &= cpu_irq_affinity[0];
+ mask1 &= cpu_irq_affinity[1];
+ mask2 &= cpu_irq_affinity[2];
+ mask3 &= cpu_irq_affinity[3];
dim0 = &cchip->dim0.csr;
dim1 = &cchip->dim1.csr;
@@ -73,10 +82,12 @@
*dim2;
*dim3;
#else
- volatile unsigned long *dimB = &cchip->dim1.csr;
+ volatile unsigned long *dimB;
if (bcpu == 0) dimB = &cchip->dim0.csr;
- if (bcpu == 2) dimB = &cchip->dim2.csr;
- if (bcpu == 3) dimB = &cchip->dim3.csr;
+ else if (bcpu == 1) dimB = &cchip->dim1.csr;
+ else if (bcpu == 2) dimB = &cchip->dim2.csr;
+ else if (bcpu == 3) dimB = &cchip->dim3.csr;
+
*dimB = mask | isa_enable;
mb();
*dimB;
@@ -95,18 +106,22 @@
tsunami_update_irq_hw(mask, 1UL << 55);
}
-static inline void
+static void
dp264_enable_irq(unsigned int irq)
{
+ spin_lock(&dp264_irq_lock);
cached_irq_mask |= 1UL << irq;
dp264_update_irq_hw(cached_irq_mask);
+ spin_unlock(&dp264_irq_lock);
}
static void
dp264_disable_irq(unsigned int irq)
{
+ spin_lock(&dp264_irq_lock);
cached_irq_mask &= ~(1UL << irq);
dp264_update_irq_hw(cached_irq_mask);
+ spin_unlock(&dp264_irq_lock);
}
static unsigned int
@@ -116,18 +131,29 @@
return 0; /* never anything pending */
}
-static inline void
+static void
+dp264_end_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ dp264_enable_irq(irq);
+}
+
+static void
clipper_enable_irq(unsigned int irq)
{
+ spin_lock(&dp264_irq_lock);
cached_irq_mask |= 1UL << irq;
clipper_update_irq_hw(cached_irq_mask);
+ spin_unlock(&dp264_irq_lock);
}
static void
clipper_disable_irq(unsigned int irq)
{
+ spin_lock(&dp264_irq_lock);
cached_irq_mask &= ~(1UL << irq);
clipper_update_irq_hw(cached_irq_mask);
+ spin_unlock(&dp264_irq_lock);
}
static unsigned int
@@ -137,6 +163,47 @@
return 0; /* never anything pending */
}
+static void
+clipper_end_irq(unsigned int irq)
+{
+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ clipper_enable_irq(irq);
+}
+
+static void
+cpu_set_irq_affinity(unsigned int irq, unsigned long affinity)
+{
+ int cpu;
+
+ for (cpu = 0; cpu < 4; cpu++) {
+ unsigned long aff = cpu_irq_affinity[cpu];
+ if (affinity & (1UL << cpu))
+ aff |= 1UL << irq;
+ else
+ aff &= ~(1UL << irq);
+ cpu_irq_affinity[cpu] = aff;
+ }
+
+}
+
+static void
+dp264_set_affinity(unsigned int irq, unsigned long affinity)
+{
+ spin_lock(&dp264_irq_lock);
+ cpu_set_irq_affinity(irq, affinity);
+ dp264_update_irq_hw(cached_irq_mask);
+ spin_unlock(&dp264_irq_lock);
+}
+
+static void
+clipper_set_affinity(unsigned int irq, unsigned long affinity)
+{
+ spin_lock(&dp264_irq_lock);
+ cpu_set_irq_affinity(irq, affinity);
+ clipper_update_irq_hw(cached_irq_mask);
+ spin_unlock(&dp264_irq_lock);
+}
+
static struct hw_interrupt_type dp264_irq_type = {
typename: "DP264",
startup: dp264_startup_irq,
@@ -144,7 +211,8 @@
enable: dp264_enable_irq,
disable: dp264_disable_irq,
ack: dp264_disable_irq,
- end: dp264_enable_irq,
+ end: dp264_end_irq,
+ set_affinity: dp264_set_affinity,
};
static struct hw_interrupt_type clipper_irq_type = {
@@ -154,7 +222,8 @@
enable: clipper_enable_irq,
disable: clipper_disable_irq,
ack: clipper_disable_irq,
- end: clipper_enable_irq,
+ end: clipper_end_irq,
+ set_affinity: clipper_set_affinity,
};
static void
@@ -249,6 +318,8 @@
static void __init
dp264_init_irq(void)
{
+ int cpu;
+
outb(0, DMA1_RESET_REG);
outb(0, DMA2_RESET_REG);
outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
@@ -257,10 +328,12 @@
if (alpha_using_srm)
alpha_mv.device_interrupt = dp264_srm_device_interrupt;
+ /* this is single threaded by design so no need of any smp lock */
+ for (cpu = 0; cpu < 4; cpu++)
+ cpu_irq_affinity[cpu] = ~0UL;
dp264_update_irq_hw(0UL);
init_i8259a_irqs();
- init_rtc_irq();
init_tsunami_irqs(&dp264_irq_type);
}
@@ -278,7 +351,6 @@
clipper_update_irq_hw(0UL);
init_i8259a_irqs();
- init_rtc_irq();
init_tsunami_irqs(&clipper_irq_type);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)