[PARISC] Add IRQ affinities

This really only adds them for the machines I can check SMP on, which
is CPU interrupts and IOSAPIC (so not any of the GSC based machines).

With this patch, irqbalanced can be used to maintain irq balancing.
Unfortunately, irqbalanced is a bit x86 centric, so it doesn't do an
incredibly good job, but it does work.

Signed-off-by: James Bottomley <jejb@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index a39fbfe..19657ef 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -700,6 +700,28 @@
 	return 0;
 }
 
+#ifdef CONFIG_SMP
+static void iosapic_set_affinity_irq(unsigned int irq, cpumask_t dest)
+{
+	struct vector_info *vi = iosapic_get_vector(irq);
+	u32 d0, d1, dummy_d0;
+	unsigned long flags;
+
+	if (cpu_check_affinity(irq, &dest))
+		return;
+
+	vi->txn_addr = txn_affinity_addr(irq, first_cpu(dest));
+
+	spin_lock_irqsave(&iosapic_lock, flags);
+	/* d1 contains the destination CPU, so only want to set that
+	 * entry */
+	iosapic_rd_irt_entry(vi, &d0, &d1);
+	iosapic_set_irt_data(vi, &dummy_d0, &d1);
+	iosapic_wr_irt_entry(vi, d0, d1);
+	spin_unlock_irqrestore(&iosapic_lock, flags);
+}
+#endif
+
 static struct hw_interrupt_type iosapic_interrupt_type = {
 	.typename =	"IO-SAPIC-level",
 	.startup =	iosapic_startup_irq,
@@ -708,7 +730,9 @@
 	.disable =	iosapic_disable_irq,
 	.ack =		no_ack_irq,
 	.end =		iosapic_end_irq,
-//	.set_affinity =	iosapic_set_affinity_irq,
+#ifdef CONFIG_SMP
+	.set_affinity =	iosapic_set_affinity_irq,
+#endif
 };
 
 int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)