Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jiri Slaby and committed by
Greg Kroah-Hartman
6efb6b77 035cfe5a

+35 -31
+30 -6
arch/ia64/hp/sim/hpsim_irq.c
··· 10 10 #include <linux/sched.h> 11 11 #include <linux/irq.h> 12 12 13 + #include "hpsim_ssc.h" 14 + 13 15 static unsigned int 14 16 hpsim_irq_startup(struct irq_data *data) 15 17 { ··· 39 37 .irq_set_affinity = hpsim_set_affinity_noop, 40 38 }; 41 39 40 + static void hpsim_irq_set_chip(int irq) 41 + { 42 + struct irq_chip *chip = irq_get_chip(irq); 43 + 44 + if (chip == &no_irq_chip) 45 + irq_set_chip(irq, &irq_type_hp_sim); 46 + } 47 + 48 + static void hpsim_connect_irq(int intr, int irq) 49 + { 50 + ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT); 51 + } 52 + 53 + int hpsim_get_irq(int intr) 54 + { 55 + int irq = assign_irq_vector(AUTO_ASSIGN); 56 + 57 + if (irq >= 0) { 58 + hpsim_irq_set_chip(irq); 59 + irq_set_handler(irq, handle_simple_irq); 60 + hpsim_connect_irq(intr, irq); 61 + } 62 + 63 + return irq; 64 + } 65 + 42 66 void __init 43 67 hpsim_irq_init (void) 44 68 { 45 69 int i; 46 70 47 - for_each_active_irq(i) { 48 - struct irq_chip *chip = irq_get_chip(i); 49 - 50 - if (chip == &no_irq_chip) 51 - irq_set_chip(i, &irq_type_hp_sim); 52 - } 71 + for_each_active_irq(i) 72 + hpsim_irq_set_chip(i); 53 73 }
-6
arch/ia64/hp/sim/hpsim_setup.c
··· 26 26 #include "hpsim_ssc.h" 27 27 28 28 void 29 - ia64_ssc_connect_irq (long intr, long irq) 30 - { 31 - ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT); 32 - } 33 - 34 - void 35 29 ia64_ctl_trace (long on) 36 30 { 37 31 ia64_ssc(on, 0, 0, 0, SSC_CTL_TRACE);
+3 -16
arch/ia64/hp/sim/simeth.c
··· 129 129 130 130 131 131 static inline int 132 - netdev_connect(int irq) 133 - { 134 - /* XXX Fix me 135 - * this does not support multiple cards 136 - * also no return value 137 - */ 138 - ia64_ssc_connect_irq(NETWORK_INTR, irq); 139 - return 0; 140 - } 141 - 142 - static inline int 143 132 netdev_attach(int fd, int irq, unsigned int ipaddr) 144 133 { 145 134 /* this puts the host interface in the right mode (start interrupting) */ ··· 215 226 return err; 216 227 } 217 228 218 - if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0) 219 - panic("%s: out of interrupt vectors!\n", __func__); 220 - dev->irq = rc; 221 - 222 229 /* 223 230 * attach the interrupt in the simulator, this does enable interrupts 224 231 * until a netdev_attach() is called 225 232 */ 226 - netdev_connect(dev->irq); 233 + if ((rc = hpsim_get_irq(NETWORK_INTR)) < 0) 234 + panic("%s: out of interrupt vectors!\n", __func__); 235 + dev->irq = rc; 227 236 228 237 printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr", 229 238 dev->name, simeth_device, local->simfd);
+1 -2
arch/ia64/hp/sim/simserial.c
··· 933 933 if (state->type == PORT_UNKNOWN) continue; 934 934 935 935 if (!state->irq) { 936 - if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0) 936 + if ((rc = hpsim_get_irq(KEYBOARD_INTR)) < 0) 937 937 panic("%s: out of interrupt vectors!\n", 938 938 __func__); 939 939 state->irq = rc; 940 - ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq); 941 940 } 942 941 943 942 printk(KERN_INFO "ttyS%d at 0x%04lx (irq = %d) is a %s\n",
+1 -1
arch/ia64/include/asm/hpsim.h
··· 10 10 struct tty_driver; 11 11 extern struct tty_driver *hp_simserial_driver; 12 12 13 - void ia64_ssc_connect_irq(long intr, long irq); 13 + extern int hpsim_get_irq(int intr); 14 14 void ia64_ctl_trace(long on); 15 15 16 16 #endif