diff options
author | Jiri Slaby <jslaby@suse.cz> | 2012-03-08 15:01:18 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-03-08 15:26:30 -0500 |
commit | 6efb6b77ff6fd512e9ef45b29f1940cb924cd7a6 (patch) | |
tree | af1c250060eac5eed26608e8709ae7e4d3c4b287 /arch/ia64 | |
parent | 035cfe5ac55d399169b7f61f7a111d3d7075190c (diff) |
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>
Diffstat (limited to 'arch/ia64')
-rw-r--r-- | arch/ia64/hp/sim/hpsim_irq.c | 36 | ||||
-rw-r--r-- | arch/ia64/hp/sim/hpsim_setup.c | 6 | ||||
-rw-r--r-- | arch/ia64/hp/sim/simeth.c | 19 | ||||
-rw-r--r-- | arch/ia64/hp/sim/simserial.c | 3 | ||||
-rw-r--r-- | arch/ia64/include/asm/hpsim.h | 2 |
5 files changed, 35 insertions, 31 deletions
diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c index 4bd9a63260ee..0aa70ebda49d 100644 --- a/arch/ia64/hp/sim/hpsim_irq.c +++ b/arch/ia64/hp/sim/hpsim_irq.c | |||
@@ -10,6 +10,8 @@ | |||
10 | #include <linux/sched.h> | 10 | #include <linux/sched.h> |
11 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
12 | 12 | ||
13 | #include "hpsim_ssc.h" | ||
14 | |||
13 | static unsigned int | 15 | static unsigned int |
14 | hpsim_irq_startup(struct irq_data *data) | 16 | hpsim_irq_startup(struct irq_data *data) |
15 | { | 17 | { |
@@ -37,15 +39,37 @@ static struct irq_chip irq_type_hp_sim = { | |||
37 | .irq_set_affinity = hpsim_set_affinity_noop, | 39 | .irq_set_affinity = hpsim_set_affinity_noop, |
38 | }; | 40 | }; |
39 | 41 | ||
42 | static void hpsim_irq_set_chip(int irq) | ||
43 | { | ||
44 | struct irq_chip *chip = irq_get_chip(irq); | ||
45 | |||
46 | if (chip == &no_irq_chip) | ||
47 | irq_set_chip(irq, &irq_type_hp_sim); | ||
48 | } | ||
49 | |||
50 | static void hpsim_connect_irq(int intr, int irq) | ||
51 | { | ||
52 | ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT); | ||
53 | } | ||
54 | |||
55 | int hpsim_get_irq(int intr) | ||
56 | { | ||
57 | int irq = assign_irq_vector(AUTO_ASSIGN); | ||
58 | |||
59 | if (irq >= 0) { | ||
60 | hpsim_irq_set_chip(irq); | ||
61 | irq_set_handler(irq, handle_simple_irq); | ||
62 | hpsim_connect_irq(intr, irq); | ||
63 | } | ||
64 | |||
65 | return irq; | ||
66 | } | ||
67 | |||
40 | void __init | 68 | void __init |
41 | hpsim_irq_init (void) | 69 | hpsim_irq_init (void) |
42 | { | 70 | { |
43 | int i; | 71 | int i; |
44 | 72 | ||
45 | for_each_active_irq(i) { | 73 | for_each_active_irq(i) |
46 | struct irq_chip *chip = irq_get_chip(i); | 74 | hpsim_irq_set_chip(i); |
47 | |||
48 | if (chip == &no_irq_chip) | ||
49 | irq_set_chip(i, &irq_type_hp_sim); | ||
50 | } | ||
51 | } | 75 | } |
diff --git a/arch/ia64/hp/sim/hpsim_setup.c b/arch/ia64/hp/sim/hpsim_setup.c index f629e903ebc7..664a5402a695 100644 --- a/arch/ia64/hp/sim/hpsim_setup.c +++ b/arch/ia64/hp/sim/hpsim_setup.c | |||
@@ -26,12 +26,6 @@ | |||
26 | #include "hpsim_ssc.h" | 26 | #include "hpsim_ssc.h" |
27 | 27 | ||
28 | void | 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 | ia64_ctl_trace (long on) | 29 | ia64_ctl_trace (long on) |
36 | { | 30 | { |
37 | ia64_ssc(on, 0, 0, 0, SSC_CTL_TRACE); | 31 | 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 47afcc61f6e5..e343357f80b9 100644 --- a/arch/ia64/hp/sim/simeth.c +++ b/arch/ia64/hp/sim/simeth.c | |||
@@ -129,17 +129,6 @@ netdev_probe(char *name, unsigned char *ether) | |||
129 | 129 | ||
130 | 130 | ||
131 | static inline int | 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 | netdev_attach(int fd, int irq, unsigned int ipaddr) | 132 | netdev_attach(int fd, int irq, unsigned int ipaddr) |
144 | { | 133 | { |
145 | /* this puts the host interface in the right mode (start interrupting) */ | 134 | /* this puts the host interface in the right mode (start interrupting) */ |
@@ -226,15 +215,13 @@ simeth_probe1(void) | |||
226 | return err; | 215 | return err; |
227 | } | 216 | } |
228 | 217 | ||
229 | if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0) | ||
230 | panic("%s: out of interrupt vectors!\n", __func__); | ||
231 | dev->irq = rc; | ||
232 | |||
233 | /* | 218 | /* |
234 | * attach the interrupt in the simulator, this does enable interrupts | 219 | * attach the interrupt in the simulator, this does enable interrupts |
235 | * until a netdev_attach() is called | 220 | * until a netdev_attach() is called |
236 | */ | 221 | */ |
237 | netdev_connect(dev->irq); | 222 | if ((rc = hpsim_get_irq(NETWORK_INTR)) < 0) |
223 | panic("%s: out of interrupt vectors!\n", __func__); | ||
224 | dev->irq = rc; | ||
238 | 225 | ||
239 | printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr", | 226 | printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr", |
240 | dev->name, simeth_device, local->simfd); | 227 | dev->name, simeth_device, local->simfd); |
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index 35ae642b2a1a..3a079decde51 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c | |||
@@ -933,11 +933,10 @@ simrs_init (void) | |||
933 | if (state->type == PORT_UNKNOWN) continue; | 933 | if (state->type == PORT_UNKNOWN) continue; |
934 | 934 | ||
935 | if (!state->irq) { | 935 | if (!state->irq) { |
936 | if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0) | 936 | if ((rc = hpsim_get_irq(KEYBOARD_INTR)) < 0) |
937 | panic("%s: out of interrupt vectors!\n", | 937 | panic("%s: out of interrupt vectors!\n", |
938 | __func__); | 938 | __func__); |
939 | state->irq = rc; | 939 | state->irq = rc; |
940 | ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq); | ||
941 | } | 940 | } |
942 | 941 | ||
943 | printk(KERN_INFO "ttyS%d at 0x%04lx (irq = %d) is a %s\n", | 942 | 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 892ab198a9da..0fe50225daa4 100644 --- a/arch/ia64/include/asm/hpsim.h +++ b/arch/ia64/include/asm/hpsim.h | |||
@@ -10,7 +10,7 @@ int simcons_register(void); | |||
10 | struct tty_driver; | 10 | struct tty_driver; |
11 | extern struct tty_driver *hp_simserial_driver; | 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 | void ia64_ctl_trace(long on); | 14 | void ia64_ctl_trace(long on); |
15 | 15 | ||
16 | #endif | 16 | #endif |