|
@@ -120,3 +120,161 @@ 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);
|
|
|
+ spin_unlock(&dp264_irq_lock);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+clipper_disable_irq(struct irq_data *d)
|
|
|
+{
|
|
|
+ spin_lock(&dp264_irq_lock);
|
|
|
+ cached_irq_mask &= ~(1UL << (d->irq - 16));
|
|
|
+ tsunami_update_irq_hw(cached_irq_mask);
|
|
|
+ spin_unlock(&dp264_irq_lock);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
|
|
|
+{
|
|
|
+ int cpu;
|
|
|
+
|
|
|
+ for (cpu = 0; cpu < 4; cpu++) {
|
|
|
+ unsigned long aff = cpu_irq_affinity[cpu];
|
|
|
+ if (cpumask_test_cpu(cpu, &affinity))
|
|
|
+ aff |= 1UL << irq;
|
|
|
+ else
|
|
|
+ aff &= ~(1UL << irq);
|
|
|
+ cpu_irq_affinity[cpu] = aff;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static int
|
|
|
+dp264_set_affinity(struct irq_data *d, const struct cpumask *affinity,
|
|
|
+ bool force)
|
|
|
+{
|
|
|
+ spin_lock(&dp264_irq_lock);
|
|
|
+ cpu_set_irq_affinity(d->irq, *affinity);
|
|
|
+ tsunami_update_irq_hw(cached_irq_mask);
|
|
|
+ spin_unlock(&dp264_irq_lock);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int
|
|
|
+clipper_set_affinity(struct irq_data *d, const struct cpumask *affinity,
|
|
|
+ bool force)
|
|
|
+{
|
|
|
+ spin_lock(&dp264_irq_lock);
|
|
|
+ cpu_set_irq_affinity(d->irq - 16, *affinity);
|
|
|
+ tsunami_update_irq_hw(cached_irq_mask);
|
|
|
+ spin_unlock(&dp264_irq_lock);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static struct irq_chip dp264_irq_type = {
|
|
|
+ .name = "DP264",
|
|
|
+ .irq_unmask = dp264_enable_irq,
|
|
|
+ .irq_mask = dp264_disable_irq,
|
|
|
+ .irq_mask_ack = dp264_disable_irq,
|
|
|
+ .irq_set_affinity = dp264_set_affinity,
|
|
|
+};
|
|
|
+
|
|
|
+static struct irq_chip clipper_irq_type = {
|
|
|
+ .name = "CLIPPER",
|
|
|
+ .irq_unmask = clipper_enable_irq,
|
|
|
+ .irq_mask = clipper_disable_irq,
|
|
|
+ .irq_mask_ack = clipper_disable_irq,
|
|
|
+ .irq_set_affinity = clipper_set_affinity,
|
|
|
+};
|
|
|
+
|
|
|
+static void
|
|
|
+dp264_device_interrupt(unsigned long vector)
|
|
|
+{
|
|
|
+#if 1
|
|
|
+ printk("dp264_device_interrupt: NOT IMPLEMENTED YET!!\n");
|
|
|
+#else
|
|
|
+ unsigned long pld;
|
|
|
+ unsigned int i;
|
|
|
+
|
|
|
+ /* Read the interrupt summary register of TSUNAMI */
|
|
|
+ pld = TSUNAMI_cchip->dir0.csr;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Now for every possible bit set, work through them and call
|
|
|
+ * the appropriate interrupt handler.
|
|
|
+ */
|
|
|
+ while (pld) {
|
|
|
+ i = ffz(~pld);
|
|
|
+ pld &= pld - 1; /* clear least bit set */
|
|
|
+ if (i == 55)
|
|
|
+ isa_device_interrupt(vector);
|
|
|
+ else
|
|
|
+ handle_irq(16 + i);
|
|
|
+#if 0
|
|
|
+ TSUNAMI_cchip->dir0.csr = 1UL << i; mb();
|
|
|
+ tmp = TSUNAMI_cchip->dir0.csr;
|
|
|
+#endif
|
|
|
+ }
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+dp264_srm_device_interrupt(unsigned long vector)
|
|
|
+{
|
|
|
+ int irq;
|
|
|
+
|
|
|
+ irq = (vector - 0x800) >> 4;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The SRM console reports PCI interrupts with a vector calculated by:
|
|
|
+ *
|
|
|
+ * 0x900 + (0x10 * DRIR-bit)
|
|
|
+ *
|
|
|
+ * So bit 16 shows up as IRQ 32, etc.
|
|
|
+ *
|
|
|
+ * On DP264/BRICK/MONET, we adjust it down by 16 because at least
|
|
|
+ * that many of the low order bits of the DRIR are not used, and
|
|
|
+ * so we don't count them.
|
|
|
+ */
|
|
|
+ if (irq >= 32)
|
|
|
+ irq -= 16;
|
|
|
+
|
|
|
+ handle_irq(irq);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+clipper_srm_device_interrupt(unsigned long vector)
|
|
|
+{
|
|
|
+ int irq;
|
|
|
+
|
|
|
+ irq = (vector - 0x800) >> 4;
|
|
|
+
|
|
|
+/*
|
|
|
+ * The SRM console reports PCI interrupts with a vector calculated by:
|
|
|
+ *
|
|
|
+ * 0x900 + (0x10 * DRIR-bit)
|
|
|
+ *
|
|
|
+ * So bit 16 shows up as IRQ 32, etc.
|
|
|
+ *
|
|
|
+ * CLIPPER uses bits 8-47 for PCI interrupts, so we do not need
|
|
|
+ * to scale down the vector reported, we just use it.
|
|
|
+ *
|
|
|
+ * Eg IRQ 24 is DRIR bit 8, etc, etc
|
|
|
+ */
|
|
|
+ handle_irq(irq);
|
|
|
+}
|
|
|
+
|
|
|
+static void __init
|
|
|
+init_tsunami_irqs(struct irq_chip * ops, int imin, int imax)
|
|
|
+{
|
|
|
+ long i;
|
|
|
+ for (i = imin; i <= imax; ++i) {
|
|
|
+ irq_set_chip_and_handler(i, ops, handle_level_irq);
|
|
|
+ irq_set_status_flags(i, IRQ_LEVEL);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void __init
|
|
|
+dp264_init_irq(void)
|
|
|
+{
|
|
|
+ outb(0, DMA1_RESET_REG);
|