]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/sparc/kernel/sun4m_irq.c
sparc32,sun4m: irq, smp files cleanup
[karo-tx-linux.git] / arch / sparc / kernel / sun4m_irq.c
index 7f3b97ff62c17394604d8134cafa5b5211e24256..3c6657a4caec79b95b5c8a3d33b56e422c443479 100644 (file)
@@ -1,5 +1,5 @@
-/*  sun4m_irq.c
- *  arch/sparc/kernel/sun4m_irq.c:
+/*
+ * sun4m irq support
  *
  *  djhr: Hacked out of irq.c into a CPU dependent version.
  *
@@ -9,36 +9,92 @@
  *  Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk)
  */
 
-#include <linux/errno.h>
-#include <linux/linkage.h>
-#include <linux/kernel_stat.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-#include <asm/system.h>
-#include <asm/psr.h>
-#include <asm/vaddrs.h>
 #include <asm/timer.h>
-#include <asm/openprom.h>
-#include <asm/oplib.h>
 #include <asm/traps.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
-#include <asm/smp.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <asm/cacheflush.h>
 
 #include "irq.h"
+#include "kernel.h"
+
+/* Sample sun4m IRQ layout:
+ *
+ * 0x22 - Power
+ * 0x24 - ESP SCSI
+ * 0x26 - Lance ethernet
+ * 0x2b - Floppy
+ * 0x2c - Zilog uart
+ * 0x32 - SBUS level 0
+ * 0x33 - Parallel port, SBUS level 1
+ * 0x35 - SBUS level 2
+ * 0x37 - SBUS level 3
+ * 0x39 - Audio, Graphics card, SBUS level 4
+ * 0x3b - SBUS level 5
+ * 0x3d - SBUS level 6
+ *
+ * Each interrupt source has a mask bit in the interrupt registers.
+ * When the mask bit is set, this blocks interrupt deliver.  So you
+ * clear the bit to enable the interrupt.
+ *
+ * Interrupts numbered less than 0x10 are software triggered interrupts
+ * and unused by Linux.
+ *
+ * Interrupt level assignment on sun4m:
+ *
+ *     level           source
+ * ------------------------------------------------------------
+ *       1             softint-1
+ *       2             softint-2, VME/SBUS level 1
+ *       3             softint-3, VME/SBUS level 2
+ *       4             softint-4, onboard SCSI
+ *       5             softint-5, VME/SBUS level 3
+ *       6             softint-6, onboard ETHERNET
+ *       7             softint-7, VME/SBUS level 4
+ *       8             softint-8, onboard VIDEO
+ *       9             softint-9, VME/SBUS level 5, Module Interrupt
+ *      10             softint-10, system counter/timer
+ *      11             softint-11, VME/SBUS level 6, Floppy
+ *      12             softint-12, Keyboard/Mouse, Serial
+ *      13             softint-13, VME/SBUS level 7, ISDN Audio
+ *      14             softint-14, per-processor counter/timer
+ *      15             softint-15, Asynchronous Errors (broadcast)
+ *
+ * Each interrupt source is masked distinctly in the sun4m interrupt
+ * registers.  The PIL level alone is therefore ambiguous, since multiple
+ * interrupt sources map to a single PIL.
+ *
+ * This ambiguity is resolved in the 'intr' property for device nodes
+ * in the OF device tree.  Each 'intr' property entry is composed of
+ * two 32-bit words.  The first word is the IRQ priority value, which
+ * is what we're intersted in.  The second word is the IRQ vector, which
+ * is unused.
+ *
+ * The low 4 bits of the IRQ priority indicate the PIL, and the upper
+ * 4 bits indicate onboard vs. SBUS leveled vs. VME leveled.  0x20
+ * means onboard, 0x30 means SBUS leveled, and 0x40 means VME leveled.
+ *
+ * For example, an 'intr' IRQ priority value of 0x24 is onboard SCSI
+ * whereas a value of 0x33 is SBUS level 2.  Here are some sample
+ * 'intr' property IRQ priority values from ss4, ss5, ss10, ss20, and
+ * Tadpole S3 GX systems.
+ *
+ * esp:                0x24    onboard ESP SCSI
+ * le:         0x26    onboard Lance ETHERNET
+ * p9100:      0x32    SBUS level 1 P9100 video
+ * bpp:                0x33    SBUS level 2 BPP parallel port device
+ * DBRI:       0x39    SBUS level 5 DBRI ISDN audio
+ * SUNW,leo:   0x39    SBUS level 5 LEO video
+ * pcmcia:     0x3b    SBUS level 6 PCMCIA controller
+ * uctrl:      0x3b    SBUS level 6 UCTRL device
+ * modem:      0x3d    SBUS level 7 MODEM
+ * zs:         0x2c    onboard keyboard/mouse/serial
+ * floppy:     0x2b    onboard Floppy
+ * power:      0x22    onboard power device (XXX unknown mask bit XXX)
+ */
+
 
 struct sun4m_irq_percpu {
        u32             pending;
@@ -61,9 +117,9 @@ struct sun4m_irq_global __iomem *sun4m_irq_global;
 /* Dave Redman (djhr@tadpole.co.uk)
  * The sun4m interrupt registers.
  */
-#define SUN4M_INT_ENABLE       0x80000000
-#define SUN4M_INT_E14          0x00000080
-#define SUN4M_INT_E10          0x00080000
+#define SUN4M_INT_ENABLE       0x80000000
+#define SUN4M_INT_E14          0x00000080
+#define SUN4M_INT_E10          0x00080000
 
 #define SUN4M_HARD_INT(x)      (0x000000001 << (x))
 #define SUN4M_SOFT_INT(x)      (0x000010000 << (x))
@@ -99,59 +155,6 @@ struct sun4m_irq_global __iomem *sun4m_irq_global;
 #define        OBP_INT_LEVEL_SBUS      0x30
 #define        OBP_INT_LEVEL_VME       0x40
 
-/* Interrupt level assignment on sun4m:
- *
- *     level           source
- * ------------------------------------------------------------
- *        1            softint-1
- *       2             softint-2, VME/SBUS level 1
- *       3             softint-3, VME/SBUS level 2
- *       4             softint-4, onboard SCSI
- *       5             softint-5, VME/SBUS level 3
- *       6             softint-6, onboard ETHERNET
- *       7             softint-7, VME/SBUS level 4
- *       8             softint-8, onboard VIDEO
- *       9             softint-9, VME/SBUS level 5, Module Interrupt
- *      10             softint-10, system counter/timer
- *      11             softint-11, VME/SBUS level 6, Floppy
- *      12             softint-12, Keyboard/Mouse, Serial
- *      13             softint-13, VME/SBUS level 7, ISDN Audio
- *      14             softint-14, per-processor counter/timer
- *      15             softint-15, Asynchronous Errors (broadcast)
- *
- * Each interrupt source is masked distinctly in the sun4m interrupt
- * registers.  The PIL level alone is therefore ambiguous, since multiple
- * interrupt sources map to a single PIL.
- *
- * This ambiguity is resolved in the 'intr' property for device nodes
- * in the OF device tree.  Each 'intr' property entry is composed of
- * two 32-bit words.  The first word is the IRQ priority value, which
- * is what we're intersted in.  The second word is the IRQ vector, which
- * is unused.
- *
- * The low 4 bits of the IRQ priority indicate the PIL, and the upper
- * 4 bits indicate onboard vs. SBUS leveled vs. VME leveled.  0x20
- * means onboard, 0x30 means SBUS leveled, and 0x40 means VME leveled.
- *
- * For example, an 'intr' IRQ priority value of 0x24 is onboard SCSI
- * whereas a value of 0x33 is SBUS level 2.  Here are some sample
- * 'intr' property IRQ priority values from ss4, ss5, ss10, ss20, and
- * Tadpole S3 GX systems.
- *
- * esp:        0x24    onboard ESP SCSI
- * le:         0x26    onboard Lance ETHERNET
- * p9100:      0x32    SBUS level 1 P9100 video
- * bpp:        0x33    SBUS level 2 BPP parallel port device
- * DBRI:       0x39    SBUS level 5 DBRI ISDN audio
- * SUNW,leo:   0x39    SBUS level 5 LEO video
- * pcmcia:     0x3b    SBUS level 6 PCMCIA controller
- * uctrl:      0x3b    SBUS level 6 UCTRL device
- * modem:      0x3d    SBUS level 7 MODEM
- * zs:         0x2c    onboard keyboard/mouse/serial
- * floppy:     0x2b    onboard Floppy
- * power:      0x22    onboard power device (XXX unknown mask bit XXX)
- */
-
 static unsigned long irq_mask[0x50] = {
        /* SMP */
        0,  SUN4M_SOFT_INT(1),
@@ -193,7 +196,7 @@ static unsigned long irq_mask[0x50] = {
 static unsigned long sun4m_get_irqmask(unsigned int irq)
 {
        unsigned long mask;
-    
+
        if (irq < 0x50)
                mask = irq_mask[irq];
        else
@@ -217,7 +220,7 @@ static void sun4m_disable_irq(unsigned int irq_nr)
                sbus_writel(mask, &sun4m_irq_global->mask_set);
        else
                sbus_writel(mask, &sun4m_irq_percpu[cpu]->set);
-       local_irq_restore(flags);    
+       local_irq_restore(flags);
 }
 
 static void sun4m_enable_irq(unsigned int irq_nr)
@@ -226,17 +229,17 @@ static void sun4m_enable_irq(unsigned int irq_nr)
        int cpu = smp_processor_id();
 
        /* Dreadful floppy hack. When we use 0x2b instead of
-         * 0x0b the system blows (it starts to whistle!).
-         * So we continue to use 0x0b. Fixme ASAP. --P3
-         */
-        if (irq_nr != 0x0b) {
+        * 0x0b the system blows (it starts to whistle!).
+        * So we continue to use 0x0b. Fixme ASAP. --P3
+        */
+       if (irq_nr != 0x0b) {
                mask = sun4m_get_irqmask(irq_nr);
                local_irq_save(flags);
                if (irq_nr > 15)
                        sbus_writel(mask, &sun4m_irq_global->mask_clear);
                else
                        sbus_writel(mask, &sun4m_irq_percpu[cpu]->clear);
-               local_irq_restore(flags);    
+               local_irq_restore(flags);
        } else {
                local_irq_save(flags);
                sbus_writel(SUN4M_INT_FLOPPY, &sun4m_irq_global->mask_clear);
@@ -260,7 +263,7 @@ static unsigned long cpu_pil_to_imask[16] = {
 /*12*/ SUN4M_INT_SERIAL  | SUN4M_INT_KBDMS,
 /*13*/ SUN4M_INT_SBUS(6) | SUN4M_INT_VME(6) | SUN4M_INT_AUDIO,
 /*14*/ SUN4M_INT_E14,
-/*15*/ SUN4M_INT_ERROR
+/*15*/ SUN4M_INT_ERROR,
 };
 
 /* We assume the caller has disabled local interrupts when these are called,
@@ -280,12 +283,14 @@ static void sun4m_enable_pil_irq(unsigned int pil)
 static void sun4m_send_ipi(int cpu, int level)
 {
        unsigned long mask = sun4m_get_irqmask(level);
+
        sbus_writel(mask, &sun4m_irq_percpu[cpu]->set);
 }
 
 static void sun4m_clear_ipi(int cpu, int level)
 {
        unsigned long mask = sun4m_get_irqmask(level);
+
        sbus_writel(mask, &sun4m_irq_percpu[cpu]->clear);
 }
 
@@ -314,7 +319,7 @@ struct sun4m_timer_global {
 
 static struct sun4m_timer_global __iomem *timers_global;
 
-#define TIMER_IRQ      (OBP_INT_LEVEL_ONBOARD | 10)
+#define TIMER_IRQ      (OBP_INT_LEVEL_ONBOARD | 10)
 
 unsigned int lvl14_resolution = (((1000000/HZ) + 1) << 10);
 
@@ -407,7 +412,6 @@ static void __init sun4m_init_timers(irq_handler_t counter_fn)
 #ifdef CONFIG_SMP
        {
                unsigned long flags;
-               extern unsigned long lvl14_save[4];
                struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)];
 
                /* For SMP we use the level 14 ticker, however the bootup code