Commit 3132fdcb authored by Linus Torvalds's avatar Linus Torvalds

Interrupt handlers should return whether the interrupt

was for them or not, so that the irq subsystem can properly
handle screaming shared interrupts.

So change the irq handlers to return a "irqretval_t", which
is either IRQ_HANDLED or IRQ_NONE.
parent 805aba53
......@@ -325,15 +325,16 @@ void init_8259A(int auto_eoi)
* =PC9800NOTE= In NEC PC-9800, we use irq8 instead of irq13!
*/
static void math_error_irq(int cpl, void *dev_id, struct pt_regs *regs)
static irqreturn_t math_error_irq(int cpl, void *dev_id, struct pt_regs *regs)
{
extern void math_error(void *);
#ifndef CONFIG_X86_PC9800
outb(0,0xF0);
#endif
if (ignore_fpu_irq || !boot_cpu_data.hard_math)
return;
return IRQ_NONE;
math_error((void *)regs->eip);
return IRQ_HANDLED;
}
/*
......
......@@ -74,7 +74,8 @@ static void register_irq_proc (unsigned int irq);
* Special irq handlers.
*/
void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs)
{ return IRQ_NONE; }
/*
* Generic no controller code
......@@ -205,18 +206,30 @@ inline void synchronize_irq(unsigned int irq)
int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
{
int status = 1; /* Force the "do bottom halves" bit */
int retval = 0;
if (!(action->flags & SA_INTERRUPT))
local_irq_enable();
do {
status |= action->flags;
action->handler(irq, action->dev_id, regs);
retval |= action->handler(irq, action->dev_id, regs).val;
action = action->next;
} while (action);
if (status & SA_SAMPLE_RANDOM)
add_interrupt_randomness(irq);
local_irq_disable();
if (retval != 1) {
static int count = 100;
while (count) {
count--;
printk(retval
? "irq event %d: bogus retval mask %x\n"
: "irq %d: nobody cared!n",
irq,
retval);
}
}
return status;
}
......@@ -447,7 +460,7 @@ asmlinkage unsigned int do_IRQ(struct pt_regs regs)
*/
int request_irq(unsigned int irq,
void (*handler)(int, void *, struct pt_regs *),
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long irqflags,
const char * devname,
void *dev_id)
......
......@@ -267,7 +267,7 @@ static inline void detect_lost_tick(void)
* Time Stamp Counter value at the time of the timer interrupt, so that
* we later on can estimate the time of day more exactly.
*/
void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
/*
* Here we are in the timer irq handler. We just have irqs locally
......@@ -284,7 +284,7 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
do_timer_interrupt(irq, NULL, regs);
write_sequnlock(&xtime_lock);
return IRQ_HANDLED;
}
/* not static: needed by APM */
......
......@@ -695,7 +695,8 @@ static int irqbits;
| (1 << SIGUSR1) | (1 << SIGUSR2) | (1 << SIGIO) | (1 << SIGURG) \
| (1 << SIGUNUSED) )
static void irq_handler(int intno, void *dev_id, struct pt_regs * regs) {
static irqreturn_t irq_handler(int intno, void *dev_id, struct pt_regs * regs)
{
int irq_bit;
unsigned long flags;
......@@ -709,6 +710,7 @@ static void irq_handler(int intno, void *dev_id, struct pt_regs * regs) {
/* else user will poll for IRQs */
out:
spin_unlock_irqrestore(&irqbits_lock, flags);
return IRQ_NONE;
}
static inline void free_vm86_irq(int irqnumber)
......@@ -742,7 +744,10 @@ static inline int get_and_reset_irq(int irqnumber)
bit = irqbits & (1 << irqnumber);
irqbits &= ~bit;
spin_unlock_irqrestore(&irqbits_lock, flags);
return bit;
if (!bit)
return 0;
enable_irq(irqnumber);
return 1;
}
......
......@@ -560,8 +560,9 @@ static struct irq_info *pirq_get_info(struct pci_dev *dev)
return NULL;
}
static void pcibios_test_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
static irqreturn_t pcibios_test_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
return IRQ_NONE;
}
static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
......
......@@ -234,10 +234,12 @@ acpi_os_table_override (struct acpi_table_header *existing_table,
return AE_OK;
}
static void
static irqreturn_t
acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
{
(*acpi_irq_handler)(acpi_irq_context);
/* FIXME!! We really should check that the irq was really ours! */
return IRQ_HANDLED;
}
acpi_status
......
......@@ -217,7 +217,7 @@ static int use_virtual_dma;
static spinlock_t floppy_lock = SPIN_LOCK_UNLOCKED;
static unsigned short virtual_dma_port=0x3f0;
void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs);
irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs);
static int set_dor(int fdc, char mask, char data);
static void register_devfs_entries (int drive) __init;
......@@ -1743,7 +1743,7 @@ static void print_result(char *message, int inr)
}
/* interrupt handler. Note that this can be called externally on the Sparc */
void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs)
irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
void (*handler)(void) = do_floppy;
int do_print;
......@@ -1764,7 +1764,7 @@ void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs)
printk("floppy interrupt on bizarre fdc %d\n",fdc);
printk("handler=%p\n", handler);
is_alive("bizarre fdc");
return;
return IRQ_NONE;
}
FDCS->reset = 0;
......@@ -1797,6 +1797,9 @@ void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs)
} else
FDCS->reset = 1;
is_alive("normal interrupt end");
/* FIXME! Was it really for us? */
return IRQ_HANDLED;
}
static void recalibrate_floppy(void)
......
......@@ -837,7 +837,7 @@ extern int DRM(control)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(irq_install)( drm_device_t *dev, int irq );
extern int DRM(irq_uninstall)( drm_device_t *dev );
extern void DRM(dma_service)( int irq, void *device,
extern irqreturn_t DRM(dma_service)( int irq, void *device,
struct pt_regs *regs );
extern void DRM(driver_irq_preinstall)( drm_device_t *dev );
extern void DRM(driver_irq_postinstall)( drm_device_t *dev );
......
......@@ -54,7 +54,7 @@
* tied to dma at all, this is just a hangover from dri prehistory.
*/
void DRM(dma_service)( DRM_IRQ_ARGS )
irqreturn_t DRM(dma_service)( DRM_IRQ_ARGS )
{
drm_device_t *dev = (drm_device_t *) arg;
drm_radeon_private_t *dev_priv =
......@@ -67,7 +67,7 @@ void DRM(dma_service)( DRM_IRQ_ARGS )
stat = RADEON_READ(RADEON_GEN_INT_STATUS)
& (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT);
if (!stat)
return;
return IRQ_NONE;
/* SW interrupt */
if (stat & RADEON_SW_INT_TEST) {
......@@ -83,6 +83,7 @@ void DRM(dma_service)( DRM_IRQ_ARGS )
/* Acknowledge interrupts we handle */
RADEON_WRITE(RADEON_GEN_INT_STATUS, stat);
return IRQ_HANDLED;
}
static __inline__ void radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv)
......
......@@ -1112,7 +1112,7 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
* on the hwgroup and the process begins again.
*/
void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
irqreturn_t ide_intr (int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long flags;
ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id;
......@@ -1126,7 +1126,7 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
if (!ide_ack_intr(hwif)) {
spin_unlock_irqrestore(&ide_lock, flags);
return;
return IRQ_NONE;
}
if ((handler = hwgroup->handler) == NULL ||
......@@ -1165,7 +1165,7 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
#endif /* CONFIG_BLK_DEV_IDEPCI */
}
spin_unlock_irqrestore(&ide_lock, flags);
return;
return IRQ_HANDLED;
}
drive = hwgroup->drive;
if (!drive) {
......@@ -1176,7 +1176,7 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
* [Note - this can occur if the drive is hot unplugged]
*/
spin_unlock_irqrestore(&ide_lock, flags);
return;
return IRQ_HANDLED;
}
if (!drive_is_ready(drive)) {
/*
......@@ -1187,7 +1187,7 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
* enough advance overhead that the latter isn't a problem.
*/
spin_unlock_irqrestore(&ide_lock, flags);
return;
return IRQ_HANDLED;
}
if (!hwgroup->busy) {
hwgroup->busy = 1; /* paranoia */
......@@ -1222,6 +1222,7 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
}
}
spin_unlock_irqrestore(&ide_lock, flags);
return IRQ_HANDLED;
}
EXPORT_SYMBOL(ide_intr);
......
......@@ -74,7 +74,7 @@ static unsigned char i8042_unxlate_table[128] = {
19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
};
static void i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs);
/*
* The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to
......@@ -332,7 +332,7 @@ static char i8042_mux_phys[4][32];
* to the upper layers.
*/
static void i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long flags;
unsigned char str, data;
......@@ -415,6 +415,8 @@ static void i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
serio_interrupt(&i8042_kbd_port, data, dfl, regs);
}
/* FIXME - was it really ours? */
return IRQ_HANDLED;
}
/*
......
......@@ -190,7 +190,7 @@ static unsigned char e100_init(struct e100_private *);
static int e100_set_mac(struct net_device *, void *);
struct net_device_stats *e100_get_stats(struct net_device *);
static void e100intr(int, void *, struct pt_regs *);
static irqreturn_t e100intr(int, void *, struct pt_regs *);
static void e100_print_brd_conf(struct e100_private *);
static void e100_set_multi(struct net_device *);
void e100_set_speed_duplex(struct e100_private *);
......@@ -1837,7 +1837,7 @@ e100_manage_adaptive_ifs(struct e100_private *bdp)
* the RX & TX queues & starts the RU if it has stopped due
* to no resources.
*/
void
irqreturn_t
e100intr(int irq, void *dev_inst, struct pt_regs *regs)
{
struct net_device *dev;
......@@ -1850,7 +1850,7 @@ e100intr(int irq, void *dev_inst, struct pt_regs *regs)
intr_status = readw(&bdp->scb->scb_status);
/* If not my interrupt, just return */
if (!(intr_status & SCB_STATUS_ACK_MASK) || (intr_status == 0xffff)) {
return;
return IRQ_NONE;
}
/* disable and ack intr */
......@@ -1859,7 +1859,7 @@ e100intr(int irq, void *dev_inst, struct pt_regs *regs)
/* the device is closed, don't continue or else bad things may happen. */
if (!netif_running(dev)) {
e100_set_intr_mask(bdp);
return;
return IRQ_NONE;
}
/* SWI intr (triggered by watchdog) is signal to allocate new skb buffers */
......@@ -1877,6 +1877,7 @@ e100intr(int irq, void *dev_inst, struct pt_regs *regs)
e100_tx_srv(bdp);
e100_set_intr_mask(bdp);
return IRQ_HANDLED;
}
/**
......
......@@ -117,7 +117,7 @@ static int pcnet_open(struct net_device *dev);
static int pcnet_close(struct net_device *dev);
static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static int do_ioctl_light(struct net_device *dev, struct ifreq *rq, int cmd);
static void ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs);
static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs);
static void ei_watchdog(u_long arg);
static void pcnet_reset_8390(struct net_device *dev);
static int set_config(struct net_device *dev, struct ifmap *map);
......@@ -1121,11 +1121,13 @@ static int set_config(struct net_device *dev, struct ifmap *map)
/*====================================================================*/
static void ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs)
static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs)
{
pcnet_dev_t *info = dev_id;
info->stale = 0;
ei_interrupt(irq, dev_id, regs);
/* FIXME! Was it really ours? */
return IRQ_HANDLED;
}
static void ei_watchdog(u_long arg)
......
......@@ -262,9 +262,11 @@ static int clear_epp_timeout(struct parport *pb)
* of these are in parport_pc.h.
*/
static void parport_pc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static irqreturn_t parport_pc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
parport_generic_irq(irq, (struct parport *) dev_id, regs);
/* FIXME! Was it really ours? */
return IRQ_HANDLED;
}
void parport_pc_write_data(struct parport *p, unsigned char d)
......
......@@ -599,7 +599,7 @@ int find_mem_region(u_long *base, u_long num, u_long align,
#ifdef CONFIG_PCMCIA_PROBE
static void fake_irq(int i, void *d, struct pt_regs *r) { }
static irqreturn_t fake_irq(int i, void *d, struct pt_regs *r) { return IRQ_NONE; }
static inline int check_irq(int irq)
{
if (request_irq(irq, fake_irq, 0, "bogus", NULL) != 0)
......
......@@ -429,7 +429,7 @@ static void yenta_bh(void *data)
socket->handler(socket->info, events);
}
static void yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned int events;
pci_socket_t *socket = (pci_socket_t *) dev_id;
......@@ -440,7 +440,9 @@ static void yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
socket->events |= events;
spin_unlock(&socket->event_lock);
schedule_work(&socket->tq_task);
return IRQ_HANDLED;
}
return IRQ_NONE;
}
static void yenta_interrupt_wrapper(unsigned long data)
......
......@@ -420,8 +420,9 @@ struct pnp_dev * pnp_check_irq_conflicts(struct pnp_dev * dev, int idx, int mode
return NULL;
}
static void pnp_test_handler(int irq, void *dev_id, struct pt_regs *regs)
static irqreturn_t pnp_test_handler(int irq, void *dev_id, struct pt_regs *regs)
{
return IRQ_NONE;
}
int pnp_check_irq(struct pnp_dev * dev, int idx)
......
......@@ -3863,7 +3863,7 @@ ahc_linux_run_device_queue(struct ahc_softc *ahc, struct ahc_linux_device *dev)
/*
* SCSI controller interrupt handler.
*/
void
irqreturn_t
ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
{
struct ahc_softc *ahc;
......@@ -3883,6 +3883,8 @@ ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
ahc_schedule_completeq(ahc, acmd);
}
ahc_unlock(ahc, &flags);
/* FIXME! Was it really ours? */
return IRQ_HANDLED;
}
void
......
......@@ -1224,7 +1224,7 @@ void ahc_platform_set_tags(struct ahc_softc *ahc,
int ahc_platform_abort_scbs(struct ahc_softc *ahc, int target,
char channel, int lun, u_int tag,
role_t role, uint32_t status);
void ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
irqreturn_t ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
void ahc_platform_flushwork(struct ahc_softc *ahc);
int ahc_softc_comp(struct ahc_softc *, struct ahc_softc *);
void ahc_done(struct ahc_softc*, struct scb*);
......
......@@ -1736,11 +1736,12 @@ qla1280_biosparam(struct scsi_device *sdev, struct block_device *bdev,
* qla1280_intr_handler
* Handles the H/W interrupt
**************************************************************************/
void
irqreturn_t
qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
{
struct scsi_qla_host *ha;
struct device_reg *reg;
int handled = 0;
u16 data;
ENTER_INTR ("qla1280_intr_handler");
......@@ -1757,6 +1758,7 @@ qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
/* Check for pending interrupts. */
if (data & RISC_INT) {
qla1280_isr(ha, &ha->done_q_first, &ha->done_q_last);
handled = 1;
} else {
/* spurious interrupts can happen legally */
dprintk(1, "scsi(%ld): Spurious interrupt - ignoring\n",
......@@ -1772,6 +1774,7 @@ qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
WRT_REG_WORD(&reg->ictrl, (ISP_EN_INT | ISP_EN_RISC));
LEAVE_INTR("qla1280_intr_handler");
return IRQ_RETVAL(handled);
}
/**************************************************************************
......
......@@ -1316,7 +1316,7 @@ int qla1280_reset(Scsi_Cmnd *, unsigned int);
int qla1280_biosparam(struct scsi_device *, struct block_device *,
sector_t, int[]);
static int qla1280_slave_configure(Scsi_Device *);
void qla1280_intr_handler(int, void *, struct pt_regs *);
irqreturn_t qla1280_intr_handler(int, void *, struct pt_regs *);
void qla1280_setup(char *s, int *dummy);
/*
......
......@@ -984,7 +984,7 @@ serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs)
* This means we need to loop through all ports. checking that they
* don't have an interrupt pending.
*/
static void serial8250_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static irqreturn_t serial8250_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct irq_info *i = dev_id;
struct list_head *l, *end = NULL;
......@@ -1024,6 +1024,8 @@ static void serial8250_interrupt(int irq, void *dev_id, struct pt_regs *regs)
spin_unlock(&i->lock);
DEBUG_INTR("end.\n");
/* FIXME! Was it really ours? */
return IRQ_HANDLED;
}
/*
......
......@@ -1436,17 +1436,18 @@ EXPORT_SYMBOL (usb_hcd_giveback_urb);
* to handle interrupts. The PCI glue layer does so automatically; only
* bus glue for non-PCI system busses will need to use this.
*/
void usb_hcd_irq (int irq, void *__hcd, struct pt_regs * r)
irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs * r)
{
struct usb_hcd *hcd = __hcd;
int start = hcd->state;
if (unlikely (hcd->state == USB_STATE_HALT)) /* irq sharing? */
return;
return IRQ_NONE;
hcd->driver->irq (hcd, r);
if (hcd->state != start && hcd->state == USB_STATE_HALT)
usb_hc_died (hcd);
return IRQ_HANDLED;
}
EXPORT_SYMBOL (usb_hcd_irq);
......
......@@ -239,7 +239,7 @@ void hcd_buffer_free (struct usb_bus *bus, size_t size,
/* generic bus glue, needed for host controllers that don't use PCI */
extern struct usb_operations usb_hcd_operations;
extern void usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r);
extern irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r);
extern void usb_hc_died (struct usb_hcd *hcd);
/* -------------------------------------------------------------------------- */
......
#ifndef _ASM_ARCH_HOOKS_H
#define _ASM_ARCH_HOOKS_H
#include <linux/interrupt.h>
/*
* linux/include/asm/arch_hooks.h
*
......@@ -12,7 +14,7 @@
extern void init_ISA_irqs(void);
extern void apic_intr_init(void);
extern void smp_intr_init(void);
extern void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
extern irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
/* these are the defined hooks */
extern void intr_init_hook(void);
......
......@@ -51,7 +51,7 @@ static char *virtual_dma_addr;
static int virtual_dma_mode;
static int doing_pdma;
static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
{
register unsigned char st;
......@@ -63,10 +63,8 @@ static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
static int bytes=0;
static int dma_wait=0;
#endif
if(!doing_pdma) {
floppy_interrupt(irq, dev_id, regs);
return;
}
if (!doing_pdma)
return floppy_interrupt(irq, dev_id, regs);
#ifdef TRACE_FLPY_INT
if(!calls)
......@@ -130,7 +128,7 @@ static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
calls++;
#endif
if(st == 0x20)
return;
return IRQ_HANDLED;
if(!(st & 0x20)) {
virtual_dma_residue += virtual_dma_count;
virtual_dma_count=0;
......@@ -143,12 +141,13 @@ static void floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
#endif
doing_pdma = 0;
floppy_interrupt(irq, dev_id, regs);
return;
return IRQ_HANDLED;
}
#ifdef TRACE_FLPY_INT
if(!virtual_dma_count)
dma_wait++;
#endif
return IRQ_HANDLED;
}
static void fd_disable_dma(void)
......
......@@ -1568,7 +1568,7 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
extern int ide_spin_wait_hwgroup(ide_drive_t *);
extern void ide_timer_expiry(unsigned long);
extern void ide_intr(int irq, void *dev_id, struct pt_regs *regs);
extern irqreturn_t ide_intr(int irq, void *dev_id, struct pt_regs *regs);
extern void do_ide_request(request_queue_t *);
extern void ide_init_subdrivers(void);
......
......@@ -11,8 +11,30 @@
#include <asm/ptrace.h>
#include <asm/system.h>
/*
* For 2.4.x compatibility, 2.4.x can use
*
* typedef void irqreturn_t;
* #define IRQ_NONE
* #define IRQ_HANDLED
* #define IRQ_RETVAL(x)
*
* To mix old-style and new-style irq handler returns.
*
* IRQ_NONE means we didn't handle it.
* IRQ_HANDLED means that we did have a valid interrupt and handled it.
* IRQ_RETVAL(x) selects on the two depending on x being non-zero (for handled)
*/
typedef struct irqreturn {
unsigned int val;
} irqreturn_t;
#define IRQ_NONE ((struct irqreturn) { 0 })
#define IRQ_HANDLED ((struct irqreturn) { 1 })
#define IRQ_RETVAL(x) ((struct irqreturn) { (x) != 0 })
struct irqaction {
void (*handler)(int, void *, struct pt_regs *);
irqreturn_t (*handler)(int, void *, struct pt_regs *);
unsigned long flags;
unsigned long mask;
const char *name;
......@@ -20,8 +42,9 @@ struct irqaction {
struct irqaction *next;
};
extern irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs);
extern int request_irq(unsigned int,
void (*handler)(int, void *, struct pt_regs *),
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long, const char *, void *);
extern void free_irq(unsigned int, void *);
......
......@@ -72,7 +72,6 @@ extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
extern int setup_irq(unsigned int , struct irqaction * );
extern hw_irq_controller no_irq_type; /* needed in every arch ? */
extern void no_action(int cpl, void *dev_id, struct pt_regs *regs);
#endif
......
......@@ -102,7 +102,7 @@ struct _snd_mpu401 {
*/
void snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs);
irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs);
int snd_mpu401_uart_new(snd_card_t * card,
int device,
......
......@@ -90,7 +90,7 @@ static void snd_mpu401_uart_clear_rx(mpu401_t *mpu)
#endif
}
static void _snd_mpu401_uart_interrupt(mpu401_t *mpu)
static irqreturn_t _snd_mpu401_uart_interrupt(mpu401_t *mpu)
{
if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
if (! test_and_set_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode)) {
......@@ -108,6 +108,9 @@ static void _snd_mpu401_uart_interrupt(mpu401_t *mpu)
snd_mpu401_uart_output_write(mpu);
spin_unlock(&mpu->output_lock);
}
/* FIXME! This should really check whether the irq was for us */
return IRQ_HANDLED;
}
/**
......@@ -118,13 +121,13 @@ static void _snd_mpu401_uart_interrupt(mpu401_t *mpu)
*
* Processes the interrupt for MPU401-UART i/o.
*/
void snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs)
irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
mpu401_t *mpu = snd_magic_cast(mpu401_t, dev_id, return);
if (mpu == NULL)
return;
_snd_mpu401_uart_interrupt(mpu);
return IRQ_NONE;
return _snd_mpu401_uart_interrupt(mpu);
}
/*
......
......@@ -716,7 +716,7 @@ static inline void snd_intel8x0_update(intel8x0_t *chip, ichdev_t *ichdev)
iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
}
static void snd_intel8x0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
intel8x0_t *chip = snd_magic_cast(intel8x0_t, dev_id, return);
ichdev_t *ichdev;
......@@ -727,7 +727,7 @@ static void snd_intel8x0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
status = igetdword(chip, chip->int_sta_reg);
if ((status & chip->int_sta_mask) == 0) {
spin_unlock(&chip->reg_lock);
return;
return IRQ_NONE;
}
/* ack first */
iputdword(chip, chip->int_sta_reg, status & ~chip->int_sta_mask);
......@@ -738,6 +738,7 @@ static void snd_intel8x0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (status & ichdev->int_sta_mask)
snd_intel8x0_update(chip, ichdev);
}
return IRQ_HANDLED;
}
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment