Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | /*
* Platform dependent support for SGI SN1
*
* Copyright (C) 2000 Silicon Graphics
* Copyright (C) 2000 Jack Steiner (steiner@sgi.com)
* Copyright (C) 2000 Alan Mayer (ajm@sgi.com)
* Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com)
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <asm/current.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/sn/sgi.h>
#include <asm/sn/iograph.h>
#include <asm/sn/invent.h>
#include <linux/devfs_fs_kernel.h>
#include <asm/sn/hcl.h>
#include <asm/sn/types.h>
#include <asm/sn/pci/bridge.h>
#include <asm/sn/pci/pciio.h>
#include <asm/sn/pci/pciio_private.h>
#include <asm/sn/sn_cpuid.h>
#include <asm/sn/sn1/bedrock.h>
#include <asm/sn/intr.h>
#include <asm/sn/addrs.h>
#include <asm/sn/sn1/addrs.h>
#include <asm/sn/iobus.h>
#include <asm/sn/sn1/arch.h>
#include <asm/sn/synergy.h>
#define IRQ_BIT_OFFSET 64
int bit_pos_to_irq(int bit)
{
if (bit > 118)
bit = 118;
return (bit + IRQ_BIT_OFFSET);
}
static inline int irq_to_bit_pos(int irq)
{
int bit = irq - IRQ_BIT_OFFSET;
if (bit > 63)
bit -= 64;
return bit;
}
static unsigned int
sn1_startup_irq(unsigned int irq)
{
return(0);
}
static void
sn1_shutdown_irq(unsigned int irq)
{
}
static void
sn1_disable_irq(unsigned int irq)
{
}
static void
sn1_enable_irq(unsigned int irq)
{
}
static void
sn1_ack_irq(unsigned int irq)
{
}
static void
sn1_end_irq(unsigned int irq)
{
int bit;
bit = irq_to_bit_pos(irq);
LOCAL_HUB_CLR_INTR(bit);
}
static void
sn1_set_affinity_irq(unsigned int irq, unsigned long mask)
{
}
struct hw_interrupt_type irq_type_sn1 = {
"sn1_irq",
sn1_startup_irq,
sn1_shutdown_irq,
sn1_enable_irq,
sn1_disable_irq,
sn1_ack_irq,
sn1_end_irq,
sn1_set_affinity_irq
};
void
sn1_irq_init (void)
{
int i;
for (i = 0; i <= NR_IRQS; ++i) {
if (idesc_from_vector(i)->handler == &no_irq_type) {
idesc_from_vector(i)->handler = &irq_type_sn1;
}
}
}
#if !defined(CONFIG_IA64_SGI_SN1)
void
sn1_pci_fixup(int arg)
{
}
#endif
#ifdef CONFIG_PERCPU_IRQ
extern irq_desc_t irq_descX[NR_IRQS];
irq_desc_t *irq_desc_ptr[NR_CPUS] = { irq_descX };
/*
* Each slave AP allocates its own irq table.
*/
int __init cpu_irq_init(void)
{
irq_desc_ptr[smp_processor_id()] = (irq_desc_t *)kmalloc(sizeof(irq_descX), GFP_KERNEL);
if (irq_desc_ptr[smp_processor_id()] == 0)
return(-1);
memcpy(irq_desc_ptr[smp_processor_id()], irq_desc_ptr[0],
sizeof(irq_descX));
return(0);
}
/*
* This can also allocate the irq tables for the other cpus, specifically
* on their nodes.
*/
int __init master_irq_init(void)
{
return(0);
}
/*
* The input is an ivt level.
*/
irq_desc_t *idesc_from_vector(unsigned int ivnum)
{
return(irq_desc_ptr[smp_processor_id()] + ivnum);
}
/*
* The input is a "soft" level, that we encoded in.
*/
irq_desc_t *idesc_from_irq(unsigned int irq)
{
return(irq_desc_ptr[irq >> 8] + (irq & 0xff));
}
unsigned int ivector_from_irq(unsigned int irq)
{
return(irq & 0xff);
}
/*
* This should return the Linux irq # for the i/p vector on the
* i/p cpu. We currently do not track this.
*/
unsigned int irq_from_cpuvector(int cpunum, unsigned int vector)
{
return (vector);
}
#endif /* CONFIG_PERCPU_IRQ */
|