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>
This commit is contained in:
Jiri Slaby 2012-03-08 21:01:18 +01:00 committed by Greg Kroah-Hartman
parent 035cfe5ac5
commit 6efb6b77ff
5 changed files with 35 additions and 31 deletions

View File

@ -10,6 +10,8 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/irq.h> #include <linux/irq.h>
#include "hpsim_ssc.h"
static unsigned int static unsigned int
hpsim_irq_startup(struct irq_data *data) 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, .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 void __init
hpsim_irq_init (void) hpsim_irq_init (void)
{ {
int i; int i;
for_each_active_irq(i) { for_each_active_irq(i)
struct irq_chip *chip = irq_get_chip(i); hpsim_irq_set_chip(i);
if (chip == &no_irq_chip)
irq_set_chip(i, &irq_type_hp_sim);
}
} }

View File

@ -25,12 +25,6 @@
#include "hpsim_ssc.h" #include "hpsim_ssc.h"
void
ia64_ssc_connect_irq (long intr, long irq)
{
ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT);
}
void void
ia64_ctl_trace (long on) ia64_ctl_trace (long on)
{ {

View 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 static inline int
netdev_attach(int fd, int irq, unsigned int ipaddr) netdev_attach(int fd, int irq, unsigned int ipaddr)
{ {
@ -226,15 +215,13 @@ simeth_probe1(void)
return err; 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 * attach the interrupt in the simulator, this does enable interrupts
* until a netdev_attach() is called * 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", printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr",
dev->name, simeth_device, local->simfd); dev->name, simeth_device, local->simfd);

View File

@ -933,11 +933,10 @@ simrs_init (void)
if (state->type == PORT_UNKNOWN) continue; if (state->type == PORT_UNKNOWN) continue;
if (!state->irq) { 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", panic("%s: out of interrupt vectors!\n",
__func__); __func__);
state->irq = rc; 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", printk(KERN_INFO "ttyS%d at 0x%04lx (irq = %d) is a %s\n",

View File

@ -10,7 +10,7 @@ int simcons_register(void);
struct tty_driver; struct tty_driver;
extern struct tty_driver *hp_simserial_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); void ia64_ctl_trace(long on);
#endif #endif