aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/iosapic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/kernel/iosapic.c')
-rw-r--r--arch/ia64/kernel/iosapic.c60
1 files changed, 9 insertions, 51 deletions
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 7ded76658d2..22c38404f53 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -108,10 +108,6 @@
108#define DBG(fmt...) 108#define DBG(fmt...)
109#endif 109#endif
110 110
111#define NR_PREALLOCATE_RTE_ENTRIES \
112 (PAGE_SIZE / sizeof(struct iosapic_rte_info))
113#define RTE_PREALLOCATED (1)
114
115static DEFINE_SPINLOCK(iosapic_lock); 111static DEFINE_SPINLOCK(iosapic_lock);
116 112
117/* 113/*
@@ -136,7 +132,6 @@ struct iosapic_rte_info {
136 struct list_head rte_list; /* RTEs sharing the same vector */ 132 struct list_head rte_list; /* RTEs sharing the same vector */
137 char rte_index; /* IOSAPIC RTE index */ 133 char rte_index; /* IOSAPIC RTE index */
138 int refcnt; /* reference counter */ 134 int refcnt; /* reference counter */
139 unsigned int flags; /* flags */
140 struct iosapic *iosapic; 135 struct iosapic *iosapic;
141} ____cacheline_aligned; 136} ____cacheline_aligned;
142 137
@@ -155,9 +150,6 @@ static struct iosapic_intr_info {
155 150
156static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */ 151static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */
157 152
158static int iosapic_kmalloc_ok;
159static LIST_HEAD(free_rte_list);
160
161static inline void 153static inline void
162iosapic_write(struct iosapic *iosapic, unsigned int reg, u32 val) 154iosapic_write(struct iosapic *iosapic, unsigned int reg, u32 val)
163{ 155{
@@ -394,7 +386,7 @@ iosapic_startup_level_irq (unsigned int irq)
394} 386}
395 387
396static void 388static void
397iosapic_end_level_irq (unsigned int irq) 389iosapic_unmask_level_irq (unsigned int irq)
398{ 390{
399 ia64_vector vec = irq_to_vector(irq); 391 ia64_vector vec = irq_to_vector(irq);
400 struct iosapic_rte_info *rte; 392 struct iosapic_rte_info *rte;
@@ -404,7 +396,8 @@ iosapic_end_level_irq (unsigned int irq)
404 if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) { 396 if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
405 do_unmask_irq = 1; 397 do_unmask_irq = 1;
406 mask_irq(irq); 398 mask_irq(irq);
407 } 399 } else
400 unmask_irq(irq);
408 401
409 list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list) 402 list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list)
410 iosapic_eoi(rte->iosapic->addr, vec); 403 iosapic_eoi(rte->iosapic->addr, vec);
@@ -427,9 +420,8 @@ static struct irq_chip irq_type_iosapic_level = {
427 .enable = iosapic_enable_level_irq, 420 .enable = iosapic_enable_level_irq,
428 .disable = iosapic_disable_level_irq, 421 .disable = iosapic_disable_level_irq,
429 .ack = iosapic_ack_level_irq, 422 .ack = iosapic_ack_level_irq,
430 .end = iosapic_end_level_irq,
431 .mask = mask_irq, 423 .mask = mask_irq,
432 .unmask = unmask_irq, 424 .unmask = iosapic_unmask_level_irq,
433 .set_affinity = iosapic_set_affinity 425 .set_affinity = iosapic_set_affinity
434}; 426};
435 427
@@ -552,37 +544,6 @@ iosapic_reassign_vector (int irq)
552 } 544 }
553} 545}
554 546
555static struct iosapic_rte_info * __init_refok iosapic_alloc_rte (void)
556{
557 int i;
558 struct iosapic_rte_info *rte;
559 int preallocated = 0;
560
561 if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) {
562 rte = alloc_bootmem(sizeof(struct iosapic_rte_info) *
563 NR_PREALLOCATE_RTE_ENTRIES);
564 for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++)
565 list_add(&rte->rte_list, &free_rte_list);
566 }
567
568 if (!list_empty(&free_rte_list)) {
569 rte = list_entry(free_rte_list.next, struct iosapic_rte_info,
570 rte_list);
571 list_del(&rte->rte_list);
572 preallocated++;
573 } else {
574 rte = kmalloc(sizeof(struct iosapic_rte_info), GFP_ATOMIC);
575 if (!rte)
576 return NULL;
577 }
578
579 memset(rte, 0, sizeof(struct iosapic_rte_info));
580 if (preallocated)
581 rte->flags |= RTE_PREALLOCATED;
582
583 return rte;
584}
585
586static inline int irq_is_shared (int irq) 547static inline int irq_is_shared (int irq)
587{ 548{
588 return (iosapic_intr_info[irq].count > 1); 549 return (iosapic_intr_info[irq].count > 1);
@@ -615,7 +576,7 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
615 576
616 rte = find_rte(irq, gsi); 577 rte = find_rte(irq, gsi);
617 if (!rte) { 578 if (!rte) {
618 rte = iosapic_alloc_rte(); 579 rte = kzalloc(sizeof (*rte), GFP_ATOMIC);
619 if (!rte) { 580 if (!rte) {
620 printk(KERN_WARNING "%s: cannot allocate memory\n", 581 printk(KERN_WARNING "%s: cannot allocate memory\n",
621 __func__); 582 __func__);
@@ -658,6 +619,10 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
658 idesc->chip->name, irq_type->name); 619 idesc->chip->name, irq_type->name);
659 idesc->chip = irq_type; 620 idesc->chip = irq_type;
660 } 621 }
622 if (trigger == IOSAPIC_EDGE)
623 __set_irq_handler_unlocked(irq, handle_edge_irq);
624 else
625 __set_irq_handler_unlocked(irq, handle_level_irq);
661 return 0; 626 return 0;
662} 627}
663 628
@@ -1161,10 +1126,3 @@ map_iosapic_to_node(unsigned int gsi_base, int node)
1161 return; 1126 return;
1162} 1127}
1163#endif 1128#endif
1164
1165static int __init iosapic_enable_kmalloc (void)
1166{
1167 iosapic_kmalloc_ok = 1;
1168 return 0;
1169}
1170core_initcall (iosapic_enable_kmalloc);