"i" (ASI_PHYS_USE_EC));
}
-#define __irq(bucket) ((unsigned long)(bucket))
-
#define irq_work_pa(__cpu) &(trap_block[(__cpu)].irq_worklist_pa)
static struct {
- unsigned long irq;
unsigned int dev_handle;
unsigned int dev_ino;
-} virt_to_real_irq_table[NR_IRQS];
+ unsigned int in_use;
+} virt_irq_table[NR_IRQS];
static DEFINE_SPINLOCK(virt_irq_alloc_lock);
-unsigned char virt_irq_alloc(unsigned long real_irq,
- unsigned int dev_handle,
+unsigned char virt_irq_alloc(unsigned int dev_handle,
unsigned int dev_ino)
{
unsigned long flags;
spin_lock_irqsave(&virt_irq_alloc_lock, flags);
for (ent = 1; ent < NR_IRQS; ent++) {
- if (!virt_to_real_irq_table[ent].irq)
+ if (!virt_irq_table[ent].in_use)
break;
}
if (ent >= NR_IRQS) {
printk(KERN_ERR "IRQ: Out of virtual IRQs.\n");
ent = 0;
} else {
- virt_to_real_irq_table[ent].irq = real_irq;
- virt_to_real_irq_table[ent].dev_handle = dev_handle;
- virt_to_real_irq_table[ent].dev_ino = dev_ino;
+ virt_irq_table[ent].dev_handle = dev_handle;
+ virt_irq_table[ent].dev_ino = dev_ino;
+ virt_irq_table[ent].in_use = 1;
}
spin_unlock_irqrestore(&virt_irq_alloc_lock, flags);
spin_lock_irqsave(&virt_irq_alloc_lock, flags);
- virt_to_real_irq_table[virt_irq].irq = 0;
+ virt_irq_table[virt_irq].in_use = 0;
spin_unlock_irqrestore(&virt_irq_alloc_lock, flags);
}
unsigned long imap;
void (*pre_handler)(unsigned int, void *, void *);
- void *pre_handler_arg1;
- void *pre_handler_arg2;
+ void *arg1;
+ void *arg2;
};
#ifdef CONFIG_SMP
}
}
-static void sun4u_irq_end(unsigned int virt_irq)
+static void sun4u_irq_eoi(unsigned int virt_irq)
{
struct irq_handler_data *data = get_irq_chip_data(virt_irq);
struct irq_desc *desc = irq_desc + virt_irq;
static void sun4v_irq_enable(unsigned int virt_irq)
{
- unsigned int ino = virt_to_real_irq_table[virt_irq].dev_ino;
+ unsigned int ino = virt_irq_table[virt_irq].dev_ino;
unsigned long cpuid = irq_choose_cpu(virt_irq);
int err;
static void sun4v_set_affinity(unsigned int virt_irq, cpumask_t mask)
{
- unsigned int ino = virt_to_real_irq_table[virt_irq].dev_ino;
+ unsigned int ino = virt_irq_table[virt_irq].dev_ino;
unsigned long cpuid = irq_choose_cpu(virt_irq);
int err;
static void sun4v_irq_disable(unsigned int virt_irq)
{
- unsigned int ino = virt_to_real_irq_table[virt_irq].dev_ino;
+ unsigned int ino = virt_irq_table[virt_irq].dev_ino;
int err;
err = sun4v_intr_setenabled(ino, HV_INTR_DISABLED);
"err(%d)\n", ino, err);
}
-static void sun4v_irq_end(unsigned int virt_irq)
+static void sun4v_irq_eoi(unsigned int virt_irq)
{
- unsigned int ino = virt_to_real_irq_table[virt_irq].dev_ino;
+ unsigned int ino = virt_irq_table[virt_irq].dev_ino;
struct irq_desc *desc = irq_desc + virt_irq;
int err;
cpuid = irq_choose_cpu(virt_irq);
- dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
- dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
+ dev_handle = virt_irq_table[virt_irq].dev_handle;
+ dev_ino = virt_irq_table[virt_irq].dev_ino;
err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid);
if (err != HV_EOK)
cpuid = irq_choose_cpu(virt_irq);
- dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
- dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
+ dev_handle = virt_irq_table[virt_irq].dev_handle;
+ dev_ino = virt_irq_table[virt_irq].dev_ino;
err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid);
if (err != HV_EOK)
unsigned long dev_handle, dev_ino;
int err;
- dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
- dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
+ dev_handle = virt_irq_table[virt_irq].dev_handle;
+ dev_ino = virt_irq_table[virt_irq].dev_ino;
err = sun4v_vintr_set_valid(dev_handle, dev_ino,
HV_INTR_DISABLED);
dev_handle, dev_ino, err);
}
-static void sun4v_virq_end(unsigned int virt_irq)
+static void sun4v_virq_eoi(unsigned int virt_irq)
{
struct irq_desc *desc = irq_desc + virt_irq;
unsigned long dev_handle, dev_ino;
if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
return;
- dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
- dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
+ dev_handle = virt_irq_table[virt_irq].dev_handle;
+ dev_ino = virt_irq_table[virt_irq].dev_ino;
err = sun4v_vintr_set_state(dev_handle, dev_ino,
HV_INTR_STATE_IDLE);
dev_handle, dev_ino, err);
}
-static void run_pre_handler(unsigned int virt_irq)
-{
- struct irq_handler_data *data = get_irq_chip_data(virt_irq);
- unsigned int ino;
-
- ino = virt_to_real_irq_table[virt_irq].dev_ino;
- if (likely(data->pre_handler)) {
- data->pre_handler(ino,
- data->pre_handler_arg1,
- data->pre_handler_arg2);
- }
-}
-
static struct irq_chip sun4u_irq = {
.typename = "sun4u",
.enable = sun4u_irq_enable,
.disable = sun4u_irq_disable,
- .end = sun4u_irq_end,
- .set_affinity = sun4u_set_affinity,
-};
-
-static struct irq_chip sun4u_irq_ack = {
- .typename = "sun4u+ack",
- .enable = sun4u_irq_enable,
- .disable = sun4u_irq_disable,
- .ack = run_pre_handler,
- .end = sun4u_irq_end,
+ .eoi = sun4u_irq_eoi,
.set_affinity = sun4u_set_affinity,
};
.typename = "sun4v",
.enable = sun4v_irq_enable,
.disable = sun4v_irq_disable,
- .end = sun4v_irq_end,
+ .eoi = sun4v_irq_eoi,
.set_affinity = sun4v_set_affinity,
};
.typename = "vsun4v",
.enable = sun4v_virq_enable,
.disable = sun4v_virq_disable,
- .end = sun4v_virq_end,
+ .eoi = sun4v_virq_eoi,
.set_affinity = sun4v_virt_set_affinity,
};
+static void fastcall pre_flow_handler(unsigned int virt_irq,
+ struct irq_desc *desc)
+{
+ struct irq_handler_data *data = get_irq_chip_data(virt_irq);
+ unsigned int ino = virt_irq_table[virt_irq].dev_ino;
+
+ data->pre_handler(ino, data->arg1, data->arg2);
+
+ handle_fasteoi_irq(virt_irq, desc);
+}
+
void irq_install_pre_handler(int virt_irq,
void (*func)(unsigned int, void *, void *),
void *arg1, void *arg2)
{
struct irq_handler_data *data = get_irq_chip_data(virt_irq);
- struct irq_chip *chip = get_irq_chip(virt_irq);
-
- if (WARN_ON(chip == &sun4v_irq || chip == &sun4v_virq)) {
- printk(KERN_ERR "IRQ: Trying to install pre-handler on "
- "sun4v irq %u\n", virt_irq);
- return;
- }
+ struct irq_desc *desc = irq_desc + virt_irq;
data->pre_handler = func;
- data->pre_handler_arg1 = arg1;
- data->pre_handler_arg2 = arg2;
-
- if (chip == &sun4u_irq_ack)
- return;
+ data->arg1 = arg1;
+ data->arg2 = arg2;
- set_irq_chip(virt_irq, &sun4u_irq_ack);
+ desc->handle_irq = pre_flow_handler;
}
unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
bucket = &ivector_table[ino];
virt_irq = bucket_get_virt_irq(__pa(bucket));
if (!virt_irq) {
- virt_irq = virt_irq_alloc(__irq(bucket), 0, ino);
+ virt_irq = virt_irq_alloc(0, ino);
bucket_set_virt_irq(__pa(bucket), virt_irq);
- set_irq_chip(virt_irq, &sun4u_irq);
+ set_irq_chip_and_handler_name(virt_irq,
+ &sun4u_irq,
+ handle_fasteoi_irq,
+ "IVEC");
}
data = get_irq_chip_data(virt_irq);
bucket = &ivector_table[sysino];
virt_irq = bucket_get_virt_irq(__pa(bucket));
if (!virt_irq) {
- virt_irq = virt_irq_alloc(__irq(bucket), 0, sysino);
+ virt_irq = virt_irq_alloc(0, sysino);
bucket_set_virt_irq(__pa(bucket), virt_irq);
- set_irq_chip(virt_irq, chip);
+ set_irq_chip_and_handler_name(virt_irq, chip,
+ handle_fasteoi_irq,
+ "IVEC");
}
data = get_irq_chip_data(virt_irq);
((unsigned long) bucket +
sizeof(struct ino_bucket)));
- virt_irq = virt_irq_alloc(__irq(bucket), devhandle, devino);
+ virt_irq = virt_irq_alloc(devhandle, devino);
bucket_set_virt_irq(__pa(bucket), virt_irq);
- set_irq_chip(virt_irq, &sun4v_virq);
+
+ set_irq_chip_and_handler_name(virt_irq, &sun4v_virq,
+ handle_fasteoi_irq,
+ "IVEC");
data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC);
if (unlikely(!data))
void ack_bad_irq(unsigned int virt_irq)
{
- unsigned int ino = virt_to_real_irq_table[virt_irq].dev_ino;
+ unsigned int ino = virt_irq_table[virt_irq].dev_ino;
if (!ino)
ino = 0xdeadbeef;
: "memory");
while (bucket_pa) {
+ struct irq_desc *desc;
unsigned long next_pa;
unsigned int virt_irq;
virt_irq = bucket_get_virt_irq(bucket_pa);
bucket_clear_chain_pa(bucket_pa);
- __do_IRQ(virt_irq);
+ desc = irq_desc + virt_irq;
+
+ desc->handle_irq(virt_irq, desc);
bucket_pa = next_pa;
}
static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask)
{
unsigned long size = PAGE_ALIGN(qmask + 1);
- void *p = __alloc_bootmem_low(size, size, 0);
+ void *p = __alloc_bootmem(size, size, 0);
if (!p) {
prom_printf("SUN4V: Error, cannot allocate mondo queue.\n");
prom_halt();
static void __init alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask)
{
unsigned long size = PAGE_ALIGN(qmask + 1);
- void *p = __alloc_bootmem_low(size, size, 0);
+ void *p = __alloc_bootmem(size, size, 0);
if (!p) {
prom_printf("SUN4V: Error, cannot allocate kbuf page.\n");
BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64));
- page = alloc_bootmem_low_pages(PAGE_SIZE);
+ page = alloc_bootmem_pages(PAGE_SIZE);
if (!page) {
prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n");
prom_halt();
kill_prom_timer();
size = sizeof(struct ino_bucket) * NUM_IVECS;
- ivector_table = alloc_bootmem_low(size);
+ ivector_table = alloc_bootmem(size);
if (!ivector_table) {
prom_printf("Fatal error, cannot allocate ivector_table\n");
prom_halt();