#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
+#include <linux/bootmem.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/sn/sgi.h>
extern void pcibr_force_interrupt(pcibr_intr_t intr);
extern int sn_force_interrupt_flag;
-static pcibr_intr_list_t *pcibr_intr_list;
+struct sn_intr_list_t {
+ struct sn_intr_list_t *next;
+ pcibr_intr_t intr;
+};
+static struct sn_intr_list_t *sn_intr_list[NR_IRQS];
static unsigned int
}
static void
-sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
+sn_set_affinity_irq(unsigned int irq, unsigned long cpu)
{
-#if CONFIG_SMP
- int redir = 0;
- pcibr_intr_list_t p = pcibr_intr_list[irq];
- pcibr_intr_t intr;
- int cpu;
- extern void sn_shub_redirect_intr(pcibr_intr_t intr, unsigned long cpu);
- extern void sn_tio_redirect_intr(pcibr_intr_t intr, unsigned long cpu);
-
+#if CONFIG_SMP
+ int redir = 0;
+ struct sn_intr_list_t *p = sn_intr_list[irq];
+ pcibr_intr_t intr;
+ extern void sn_shub_redirect_intr(pcibr_intr_t intr, unsigned long cpu);
+ extern void sn_tio_redirect_intr(pcibr_intr_t intr, unsigned long cpu);
+
if (p == NULL)
return;
- intr = p->il_intr;
+ intr = p->intr;
if (intr == NULL)
return;
- cpu = first_cpu(mask);
sn_shub_redirect_intr(intr, cpu);
(void) set_irq_affinity_info(irq, cpu_physical_id(intr->bi_cpu), redir);
#endif /* CONFIG_SMP */
struct irq_desc *
-sn_irq_desc(unsigned int irq) {
+sn_irq_desc(unsigned int irq)
+{
irq = SN_IVEC_FROM_IRQ(irq);
}
u8
-sn_irq_to_vector(u8 irq) {
+sn_irq_to_vector(u8 irq)
+{
return(irq);
}
unsigned int
-sn_local_vector_to_irq(u8 vector) {
+sn_local_vector_to_irq(u8 vector)
+{
return (CPU_VECTOR_TO_IRQ(smp_processor_id(), vector));
}
int i;
irq_desc_t *base_desc = _irq_desc;
- for (i=IA64_FIRST_DEVICE_VECTOR; i<NR_IRQS; i++) {
+ for (i=0; i<NR_IRQS; i++) {
if (base_desc[i].handler == &no_irq_type) {
base_desc[i].handler = &irq_type_sn;
}
}
void
-register_pcibr_intr(int irq, pcibr_intr_t intr) {
- pcibr_intr_list_t p = kmalloc(sizeof(struct pcibr_intr_list_s), GFP_KERNEL);
- pcibr_intr_list_t list;
- int cpu = SN_CPU_FROM_IRQ(irq);
-
- if (pcibr_intr_list == NULL) {
- pcibr_intr_list = kmalloc(sizeof(pcibr_intr_list_t) * NR_IRQS, GFP_KERNEL);
- if (pcibr_intr_list == NULL)
- pcibr_intr_list = vmalloc(sizeof(pcibr_intr_list_t) * NR_IRQS);
- if (pcibr_intr_list == NULL) panic("Could not allocate memory for pcibr_intr_list\n");
- memset( (void *)pcibr_intr_list, 0, sizeof(pcibr_intr_list_t) * NR_IRQS);
- }
+register_pcibr_intr(int irq, pcibr_intr_t intr)
+{
+ struct sn_intr_list_t *p = kmalloc(sizeof(struct sn_intr_list_t), GFP_KERNEL);
+ struct sn_intr_list_t *list;
+ int cpu = intr->bi_cpu;
+
if (pdacpu(cpu)->sn_last_irq < irq) {
pdacpu(cpu)->sn_last_irq = irq;
}
- if (pdacpu(cpu)->sn_first_irq > irq) pdacpu(cpu)->sn_first_irq = irq;
- if (!p) panic("Could not allocate memory for pcibr_intr_list_t\n");
- if ((list = pcibr_intr_list[irq])) {
- while (list->il_next) list = list->il_next;
- list->il_next = p;
- p->il_next = NULL;
- p->il_intr = intr;
+ if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq) pdacpu(cpu)->sn_first_irq = irq;
+ if (!p) panic("Could not allocate memory for sn_intr_list_t\n");
+ if ((list = sn_intr_list[irq])) {
+ while (list->next) list = list->next;
+ list->next = p;
+ p->next = NULL;
+ p->intr = intr;
} else {
- pcibr_intr_list[irq] = p;
- p->il_next = NULL;
- p->il_intr = intr;
+ sn_intr_list[irq] = p;
+ p->next = NULL;
+ p->intr = intr;
}
}
void
-force_polled_int(void) {
+force_polled_int(void)
+{
int i;
- pcibr_intr_list_t p;
+ struct sn_intr_list_t *p;
for (i=0; i<NR_IRQS;i++) {
- p = pcibr_intr_list[i];
+ p = sn_intr_list[i];
while (p) {
- if (p->il_intr){
- pcibr_force_interrupt(p->il_intr);
+ if (p->intr){
+ pcibr_force_interrupt(p->intr);
}
- p = p->il_next;
+ p = p->next;
}
}
}
static void
-force_interrupt(int irq) {
- pcibr_intr_list_t p = pcibr_intr_list[irq];
+force_interrupt(int irq)
+{
+ struct sn_intr_list_t *p = sn_intr_list[irq];
while (p) {
- if (p->il_intr) {
- pcibr_force_interrupt(p->il_intr);
+ if (p->intr) {
+ pcibr_force_interrupt(p->intr);
}
- p = p->il_next;
+ p = p->next;
}
}
*/
static void
-sn_check_intr(int irq, pcibr_intr_t intr) {
+sn_check_intr(int irq, pcibr_intr_t intr)
+{
unsigned long regval;
int irr_reg_num;
int irr_bit;
}
void
-sn_lb_int_war_check(void) {
+sn_lb_int_war_check(void)
+{
int i;
if (pda->sn_first_irq == 0) return;
for (i=pda->sn_first_irq;
i <= pda->sn_last_irq; i++) {
- pcibr_intr_list_t p = pcibr_intr_list[i];
+ struct sn_intr_list_t *p = sn_intr_list[i];
if (p == NULL) {
continue;
}
while (p) {
- sn_check_intr(i, p->il_intr);
- p = p->il_next;
+ sn_check_intr(i, p->intr);
+ p = p->next;
}
}
}
-
-static inline int
-sn_get_next_bit(void) {
- int i;
- int bit;
-
- for (i = 3; i >= 0; i--) {
- if (pda->sn_soft_irr[i] != 0) {
- bit = (i * 64) + __ffs(pda->sn_soft_irr[i]);
- __change_bit(bit, (volatile void *)pda->sn_soft_irr);
- return(bit);
- }
- }
- return IA64_SPURIOUS_INT_VECTOR;
-}
-
-void
-sn_set_tpr(int vector) {
- if (vector > IA64_LAST_DEVICE_VECTOR || vector < IA64_FIRST_DEVICE_VECTOR) {
- ia64_setreg(_IA64_REG_CR_TPR, vector);
- } else {
- ia64_setreg(_IA64_REG_CR_TPR, IA64_LAST_DEVICE_VECTOR);
- }
-}
-
-static inline void
-sn_get_all_ivr(void) {
- int vector;
-
- vector = ia64_get_ivr();
- while (vector != IA64_SPURIOUS_INT_VECTOR) {
- __set_bit(vector, (volatile void *)pda->sn_soft_irr);
- ia64_eoi();
- if (vector > IA64_LAST_DEVICE_VECTOR) return;
- vector = ia64_get_ivr();
- }
-}
-
-int
-sn_get_ivr(void) {
- int vector;
-
- vector = sn_get_next_bit();
- if (vector == IA64_SPURIOUS_INT_VECTOR) {
- sn_get_all_ivr();
- vector = sn_get_next_bit();
- }
- return vector;
-}