hpsim, initialize chip for assigned irqs
authorJiri Slaby <jslaby@suse.cz>
Thu, 8 Mar 2012 20:01:18 +0000 (21:01 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 8 Mar 2012 20:26:30 +0000 (12:26 -0800)
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>
arch/ia64/hp/sim/hpsim_irq.c
arch/ia64/hp/sim/hpsim_setup.c
arch/ia64/hp/sim/simeth.c
arch/ia64/hp/sim/simserial.c
arch/ia64/include/asm/hpsim.h

index 4bd9a63260eeda8c98c4f1cca66c4a9ccdf29a4c..0aa70ebda49dde6e178713c149e496fcc149d067 100644 (file)
@@ -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 @@ static struct irq_chip irq_type_hp_sim = {
        .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);
 }
index f629e903ebc787886ba786579e4852270e75d880..664a5402a6957439d733801a862c49cec7faa591 100644 (file)
 
 #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)
 {
index 47afcc61f6e54235353e4f5c55d634395e08aa49..e343357f80b93929fb1c7ae6b18bcb307b2cd24b 100644 (file)
@@ -128,17 +128,6 @@ netdev_probe(char *name, unsigned char *ether)
 }
 
 
-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)
 {
@@ -226,15 +215,13 @@ simeth_probe1(void)
                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);
index 35ae642b2a1ad4813948898c71168c546f2aada8..3a079decde517e0f93c669a6ed81447c7440db9b 100644 (file)
@@ -933,11 +933,10 @@ simrs_init (void)
                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",
index 892ab198a9da86d2a30d3332a3f29df2aaf73a5a..0fe50225daa457aef3a773c645f95d4819be866a 100644 (file)
@@ -10,7 +10,7 @@ int simcons_register(void);
 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