Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1d7a6b97 authored by Stephen Rothwell's avatar Stephen Rothwell Committed by Paul Mackerras
Browse files

powerpc: more iseries irq work



Make get_IRQ return a pending irq number so it can be handled
in the powerpc geeneric code.

Signed-off-by: default avatarStephen Rothwell <sfr@canb.auug.org.au>
parent a50b56d2
Loading
Loading
Loading
Loading
+33 −20
Original line number Diff line number Diff line
@@ -82,31 +82,29 @@ struct pci_event {
	} data;
};

static DEFINE_SPINLOCK(pending_irqs_lock);
static int num_pending_irqs;
static int pending_irqs[NR_IRQS];

static void int_received(struct pci_event *event, struct pt_regs *regs)
{
	int irq;
#ifdef CONFIG_IRQSTACKS
	struct thread_info *curtp, *irqtp;
#endif

	switch (event->event.xSubtype) {
	case pe_slot_interrupt:
		irq = event->event.xCorrelationToken;
		/* Dispatch the interrupt handlers for this irq */
#ifdef CONFIG_IRQSTACKS
		/* Switch to the irq stack to handle this */
		curtp = current_thread_info();
		irqtp = hardirq_ctx[smp_processor_id()];
		if (curtp != irqtp) {
			irqtp->task = curtp->task;
			irqtp->flags = 0;
			call___do_IRQ(irq, regs, irqtp);
			irqtp->task = NULL;
			if (irqtp->flags)
				set_bits(irqtp->flags, &curtp->flags);
		} else
#endif
			__do_IRQ(irq, regs);
		if (irq < NR_IRQS) {
			spin_lock(&pending_irqs_lock);
			pending_irqs[irq]++;
			num_pending_irqs++;
			spin_unlock(&pending_irqs_lock);
		} else {
			printk(KERN_WARNING "int_received: bad irq number %d\n",
					irq);
			HvCallPci_eoi(event->data.slot.bus_number,
					event->data.slot.sub_bus_number,
					event->data.slot.dev_id);
		}
		break;
		/* Ignore error recovery events for now */
	case pe_bus_created:
@@ -342,6 +340,8 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus,
int iSeries_get_irq(struct pt_regs *regs)
{
	struct paca_struct *lpaca;
	/* -2 means ignore this interrupt */
	int irq = -2;

	lpaca = get_paca();
#ifdef CONFIG_SMP
@@ -353,6 +353,19 @@ int iSeries_get_irq(struct pt_regs *regs)
	if (hvlpevent_is_pending())
		process_hvlpevents(regs);

	/* -2 means ignore this interrupt */
	return -2;
	if (num_pending_irqs) {
		spin_lock(&pending_irqs_lock);
		for (irq = 0; irq < NR_IRQS; irq++) {
			if (pending_irqs[irq]) {
				pending_irqs[irq]--;
				num_pending_irqs--;
				break;
			}
		}
		spin_unlock(&pending_irqs_lock);
		if (irq >= NR_IRQS)
			irq = -2;
	}

	return irq;
}