forked from Minki/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>
This commit is contained in:
parent
035cfe5ac5
commit
6efb6b77ff
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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",
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user