|
@@ -108,10 +108,6 @@
|
|
#define DBG(fmt...)
|
|
#define DBG(fmt...)
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-#define NR_PREALLOCATE_RTE_ENTRIES \
|
|
|
|
- (PAGE_SIZE / sizeof(struct iosapic_rte_info))
|
|
|
|
-#define RTE_PREALLOCATED (1)
|
|
|
|
-
|
|
|
|
static DEFINE_SPINLOCK(iosapic_lock);
|
|
static DEFINE_SPINLOCK(iosapic_lock);
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -136,7 +132,6 @@ struct iosapic_rte_info {
|
|
struct list_head rte_list; /* RTEs sharing the same vector */
|
|
struct list_head rte_list; /* RTEs sharing the same vector */
|
|
char rte_index; /* IOSAPIC RTE index */
|
|
char rte_index; /* IOSAPIC RTE index */
|
|
int refcnt; /* reference counter */
|
|
int refcnt; /* reference counter */
|
|
- unsigned int flags; /* flags */
|
|
|
|
struct iosapic *iosapic;
|
|
struct iosapic *iosapic;
|
|
} ____cacheline_aligned;
|
|
} ____cacheline_aligned;
|
|
|
|
|
|
@@ -155,9 +150,6 @@ static struct iosapic_intr_info {
|
|
|
|
|
|
static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */
|
|
static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */
|
|
|
|
|
|
-static int iosapic_kmalloc_ok;
|
|
|
|
-static LIST_HEAD(free_rte_list);
|
|
|
|
-
|
|
|
|
static inline void
|
|
static inline void
|
|
iosapic_write(struct iosapic *iosapic, unsigned int reg, u32 val)
|
|
iosapic_write(struct iosapic *iosapic, unsigned int reg, u32 val)
|
|
{
|
|
{
|
|
@@ -394,7 +386,7 @@ iosapic_startup_level_irq (unsigned int irq)
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
static void
|
|
-iosapic_end_level_irq (unsigned int irq)
|
|
|
|
|
|
+iosapic_unmask_level_irq (unsigned int irq)
|
|
{
|
|
{
|
|
ia64_vector vec = irq_to_vector(irq);
|
|
ia64_vector vec = irq_to_vector(irq);
|
|
struct iosapic_rte_info *rte;
|
|
struct iosapic_rte_info *rte;
|
|
@@ -404,7 +396,8 @@ iosapic_end_level_irq (unsigned int irq)
|
|
if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
|
|
if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
|
|
do_unmask_irq = 1;
|
|
do_unmask_irq = 1;
|
|
mask_irq(irq);
|
|
mask_irq(irq);
|
|
- }
|
|
|
|
|
|
+ } else
|
|
|
|
+ unmask_irq(irq);
|
|
|
|
|
|
list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list)
|
|
list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list)
|
|
iosapic_eoi(rte->iosapic->addr, vec);
|
|
iosapic_eoi(rte->iosapic->addr, vec);
|
|
@@ -427,9 +420,8 @@ static struct irq_chip irq_type_iosapic_level = {
|
|
.enable = iosapic_enable_level_irq,
|
|
.enable = iosapic_enable_level_irq,
|
|
.disable = iosapic_disable_level_irq,
|
|
.disable = iosapic_disable_level_irq,
|
|
.ack = iosapic_ack_level_irq,
|
|
.ack = iosapic_ack_level_irq,
|
|
- .end = iosapic_end_level_irq,
|
|
|
|
.mask = mask_irq,
|
|
.mask = mask_irq,
|
|
- .unmask = unmask_irq,
|
|
|
|
|
|
+ .unmask = iosapic_unmask_level_irq,
|
|
.set_affinity = iosapic_set_affinity
|
|
.set_affinity = iosapic_set_affinity
|
|
};
|
|
};
|
|
|
|
|
|
@@ -552,37 +544,6 @@ iosapic_reassign_vector (int irq)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static struct iosapic_rte_info * __init_refok iosapic_alloc_rte (void)
|
|
|
|
-{
|
|
|
|
- int i;
|
|
|
|
- struct iosapic_rte_info *rte;
|
|
|
|
- int preallocated = 0;
|
|
|
|
-
|
|
|
|
- if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) {
|
|
|
|
- rte = alloc_bootmem(sizeof(struct iosapic_rte_info) *
|
|
|
|
- NR_PREALLOCATE_RTE_ENTRIES);
|
|
|
|
- for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++)
|
|
|
|
- list_add(&rte->rte_list, &free_rte_list);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!list_empty(&free_rte_list)) {
|
|
|
|
- rte = list_entry(free_rte_list.next, struct iosapic_rte_info,
|
|
|
|
- rte_list);
|
|
|
|
- list_del(&rte->rte_list);
|
|
|
|
- preallocated++;
|
|
|
|
- } else {
|
|
|
|
- rte = kmalloc(sizeof(struct iosapic_rte_info), GFP_ATOMIC);
|
|
|
|
- if (!rte)
|
|
|
|
- return NULL;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- memset(rte, 0, sizeof(struct iosapic_rte_info));
|
|
|
|
- if (preallocated)
|
|
|
|
- rte->flags |= RTE_PREALLOCATED;
|
|
|
|
-
|
|
|
|
- return rte;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static inline int irq_is_shared (int irq)
|
|
static inline int irq_is_shared (int irq)
|
|
{
|
|
{
|
|
return (iosapic_intr_info[irq].count > 1);
|
|
return (iosapic_intr_info[irq].count > 1);
|
|
@@ -615,7 +576,7 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
|
|
|
|
|
|
rte = find_rte(irq, gsi);
|
|
rte = find_rte(irq, gsi);
|
|
if (!rte) {
|
|
if (!rte) {
|
|
- rte = iosapic_alloc_rte();
|
|
|
|
|
|
+ rte = kzalloc(sizeof (*rte), GFP_ATOMIC);
|
|
if (!rte) {
|
|
if (!rte) {
|
|
printk(KERN_WARNING "%s: cannot allocate memory\n",
|
|
printk(KERN_WARNING "%s: cannot allocate memory\n",
|
|
__func__);
|
|
__func__);
|
|
@@ -658,6 +619,10 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
|
|
idesc->chip->name, irq_type->name);
|
|
idesc->chip->name, irq_type->name);
|
|
idesc->chip = irq_type;
|
|
idesc->chip = irq_type;
|
|
}
|
|
}
|
|
|
|
+ if (trigger == IOSAPIC_EDGE)
|
|
|
|
+ __set_irq_handler_unlocked(irq, handle_edge_irq);
|
|
|
|
+ else
|
|
|
|
+ __set_irq_handler_unlocked(irq, handle_level_irq);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1161,10 +1126,3 @@ map_iosapic_to_node(unsigned int gsi_base, int node)
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
-
|
|
|
|
-static int __init iosapic_enable_kmalloc (void)
|
|
|
|
-{
|
|
|
|
- iosapic_kmalloc_ok = 1;
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-core_initcall (iosapic_enable_kmalloc);
|
|
|