44377f622e
The defines and typedefs (hw_interrupt_type, no_irq_type, irq_desc_t) have been kept around for migration reasons. After more than two years it's time to remove them finally. This patch cleans up one of the remaining users. When all such patches hit mainline we can remove the defines and typedefs finally. Impact: cleanup Convert the last remaining users to struct irq_chip and remove the define. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Richard Henderson <rth@twiddle.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
82 lines
1.6 KiB
C
82 lines
1.6 KiB
C
/*
|
|
* Handle interrupts from the SRM, assuming no additional weirdness.
|
|
*/
|
|
|
|
#include <linux/init.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/irq.h>
|
|
|
|
#include "proto.h"
|
|
#include "irq_impl.h"
|
|
|
|
|
|
/*
|
|
* Is the palcode SMP safe? In other words: can we call cserve_ena/dis
|
|
* at the same time in multiple CPUs? To be safe I added a spinlock
|
|
* but it can be removed trivially if the palcode is robust against smp.
|
|
*/
|
|
DEFINE_SPINLOCK(srm_irq_lock);
|
|
|
|
static inline void
|
|
srm_enable_irq(unsigned int irq)
|
|
{
|
|
spin_lock(&srm_irq_lock);
|
|
cserve_ena(irq - 16);
|
|
spin_unlock(&srm_irq_lock);
|
|
}
|
|
|
|
static void
|
|
srm_disable_irq(unsigned int irq)
|
|
{
|
|
spin_lock(&srm_irq_lock);
|
|
cserve_dis(irq - 16);
|
|
spin_unlock(&srm_irq_lock);
|
|
}
|
|
|
|
static unsigned int
|
|
srm_startup_irq(unsigned int irq)
|
|
{
|
|
srm_enable_irq(irq);
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
srm_end_irq(unsigned int irq)
|
|
{
|
|
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
|
|
srm_enable_irq(irq);
|
|
}
|
|
|
|
/* Handle interrupts from the SRM, assuming no additional weirdness. */
|
|
static struct irq_chip srm_irq_type = {
|
|
.typename = "SRM",
|
|
.startup = srm_startup_irq,
|
|
.shutdown = srm_disable_irq,
|
|
.enable = srm_enable_irq,
|
|
.disable = srm_disable_irq,
|
|
.ack = srm_disable_irq,
|
|
.end = srm_end_irq,
|
|
};
|
|
|
|
void __init
|
|
init_srm_irqs(long max, unsigned long ignore_mask)
|
|
{
|
|
long i;
|
|
|
|
if (NR_IRQS <= 16)
|
|
return;
|
|
for (i = 16; i < max; ++i) {
|
|
if (i < 64 && ((ignore_mask >> i) & 1))
|
|
continue;
|
|
irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
|
|
irq_desc[i].chip = &srm_irq_type;
|
|
}
|
|
}
|
|
|
|
void
|
|
srm_device_interrupt(unsigned long vector)
|
|
{
|
|
int irq = (vector - 0x800) >> 4;
|
|
handle_irq(irq);
|
|
}
|