hpsim, initialize chip for assigned irqs

Currently, when assign_irq_vector is called and the irq connected in
the simulator, the irq is not ready. request_irq will return ENOSYS
immediately. It is because the irq chip is unset.

Hence set the chip properly to irq_type_hp_sim. And make sure this is
done from both users of simulated interrupts.

Also we have to set handler here, otherwise we end up in
handle_bad_int resulting in spam in logs and no irqs handled. We use
handle_simple_irq as these are SW interrupts that need no ACK or
anything.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c
index 4bd9a632..0aa70eb 100644
--- a/arch/ia64/hp/sim/hpsim_irq.c
+++ b/arch/ia64/hp/sim/hpsim_irq.c
@@ -10,6 +10,8 @@
 #include <linux/sched.h>
 #include <linux/irq.h>
 
+#include "hpsim_ssc.h"
+
 static unsigned int
 hpsim_irq_startup(struct irq_data *data)
 {
@@ -37,15 +39,37 @@
 	.irq_set_affinity =	hpsim_set_affinity_noop,
 };
 
+static void hpsim_irq_set_chip(int irq)
+{
+	struct irq_chip *chip = irq_get_chip(irq);
+
+	if (chip == &no_irq_chip)
+		irq_set_chip(irq, &irq_type_hp_sim);
+}
+
+static void hpsim_connect_irq(int intr, int irq)
+{
+	ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT);
+}
+
+int hpsim_get_irq(int intr)
+{
+	int irq = assign_irq_vector(AUTO_ASSIGN);
+
+	if (irq >= 0) {
+		hpsim_irq_set_chip(irq);
+		irq_set_handler(irq, handle_simple_irq);
+		hpsim_connect_irq(intr, irq);
+	}
+
+	return irq;
+}
+
 void __init
 hpsim_irq_init (void)
 {
 	int i;
 
-	for_each_active_irq(i) {
-		struct irq_chip *chip = irq_get_chip(i);
-
-		if (chip == &no_irq_chip)
-			irq_set_chip(i, &irq_type_hp_sim);
-	}
+	for_each_active_irq(i)
+		hpsim_irq_set_chip(i);
 }
diff --git a/arch/ia64/hp/sim/hpsim_setup.c b/arch/ia64/hp/sim/hpsim_setup.c
index f629e90..664a540 100644
--- a/arch/ia64/hp/sim/hpsim_setup.c
+++ b/arch/ia64/hp/sim/hpsim_setup.c
@@ -26,12 +26,6 @@
 #include "hpsim_ssc.h"
 
 void
-ia64_ssc_connect_irq (long intr, long irq)
-{
-	ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT);
-}
-
-void
 ia64_ctl_trace (long on)
 {
 	ia64_ssc(on, 0, 0, 0, SSC_CTL_TRACE);
diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c
index 47afcc6..e343357 100644
--- a/arch/ia64/hp/sim/simeth.c
+++ b/arch/ia64/hp/sim/simeth.c
@@ -129,17 +129,6 @@
 
 
 static inline int
-netdev_connect(int irq)
-{
-	/* XXX Fix me
-	 * this does not support multiple cards
-	 * also no return value
-	 */
-	ia64_ssc_connect_irq(NETWORK_INTR, irq);
-	return 0;
-}
-
-static inline int
 netdev_attach(int fd, int irq, unsigned int ipaddr)
 {
 	/* this puts the host interface in the right mode (start interrupting) */
@@ -226,15 +215,13 @@
 		return err;
 	}
 
-	if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0)
-		panic("%s: out of interrupt vectors!\n", __func__);
-	dev->irq = rc;
-
 	/*
 	 * attach the interrupt in the simulator, this does enable interrupts
 	 * until a netdev_attach() is called
 	 */
-	netdev_connect(dev->irq);
+	if ((rc = hpsim_get_irq(NETWORK_INTR)) < 0)
+		panic("%s: out of interrupt vectors!\n", __func__);
+	dev->irq = rc;
 
 	printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr",
 	       dev->name, simeth_device, local->simfd);
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index 35ae642..3a079de 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -933,11 +933,10 @@
 		if (state->type == PORT_UNKNOWN) continue;
 
 		if (!state->irq) {
-			if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0)
+			if ((rc = hpsim_get_irq(KEYBOARD_INTR)) < 0)
 				panic("%s: out of interrupt vectors!\n",
 				      __func__);
 			state->irq = rc;
-			ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq);
 		}
 
 		printk(KERN_INFO "ttyS%d at 0x%04lx (irq = %d) is a %s\n",
diff --git a/arch/ia64/include/asm/hpsim.h b/arch/ia64/include/asm/hpsim.h
index 892ab19..0fe5022 100644
--- a/arch/ia64/include/asm/hpsim.h
+++ b/arch/ia64/include/asm/hpsim.h
@@ -10,7 +10,7 @@
 struct tty_driver;
 extern struct tty_driver *hp_simserial_driver;
 
-void ia64_ssc_connect_irq(long intr, long irq);
+extern int hpsim_get_irq(int intr);
 void ia64_ctl_trace(long on);
 
 #endif