irq.c 2.5 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3 4 5 6
/*
 *  linux/arch/arm/mach-shark/irq.c
 *
 * by Alexander Schulz
 *
 * derived from linux/arch/ppc/kernel/i8259.c and:
7
 * arch/arm/mach-ebsa110/include/mach/irq.h
Linus Torvalds's avatar
Linus Torvalds committed
8 9 10 11 12 13
 * Copyright (C) 1996-1998 Russell King
 */

#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
14
#include <linux/io.h>
Linus Torvalds's avatar
Linus Torvalds committed
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62

#include <asm/irq.h>
#include <asm/mach/irq.h>

/*
 * 8259A PIC functions to handle ISA devices:
 */

/*
 * This contains the irq mask for both 8259A irq controllers,
 * Let through the cascade-interrupt no. 2 (ff-(1<<2)==fb)
 */
static unsigned char cached_irq_mask[2] = { 0xfb, 0xff };

/*
 * These have to be protected by the irq controller spinlock
 * before being called.
 */
static void shark_disable_8259A_irq(unsigned int irq)
{
	unsigned int mask;
	if (irq<8) {
	  mask = 1 << irq;
	  cached_irq_mask[0] |= mask;
	  outb(cached_irq_mask[1],0xA1);
	} else {
	  mask = 1 << (irq-8);
	  cached_irq_mask[1] |= mask;
	  outb(cached_irq_mask[0],0x21);
	}
}

static void shark_enable_8259A_irq(unsigned int irq)
{
	unsigned int mask;
	if (irq<8) {
	  mask = ~(1 << irq);
	  cached_irq_mask[0] &= mask;
	  outb(cached_irq_mask[0],0x21);
	} else {
	  mask = ~(1 << (irq-8));
	  cached_irq_mask[1] &= mask;
	  outb(cached_irq_mask[1],0xA1);
	}
}

static void shark_ack_8259A_irq(unsigned int irq){}

63
static irqreturn_t bogus_int(int irq, void *dev_id)
Linus Torvalds's avatar
Linus Torvalds committed
64 65 66 67 68 69 70
{
	printk("Got interrupt %i!\n",irq);
	return IRQ_NONE;
}

static struct irqaction cascade;

71 72
static struct irq_chip fb_chip = {
	.name	= "XT-PIC",
Linus Torvalds's avatar
Linus Torvalds committed
73 74 75 76 77 78 79 80 81 82 83
	.ack	= shark_ack_8259A_irq,
	.mask	= shark_disable_8259A_irq,
	.unmask = shark_enable_8259A_irq,
};

void __init shark_init_irq(void)
{
	int irq;

	for (irq = 0; irq < NR_IRQS; irq++) {
		set_irq_chip(irq, &fb_chip);
84
		set_irq_handler(irq, handle_edge_irq);
Linus Torvalds's avatar
Linus Torvalds committed
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
	}

	/* init master interrupt controller */
	outb(0x11, 0x20); /* Start init sequence, edge triggered (level: 0x19)*/
	outb(0x00, 0x21); /* Vector base */
	outb(0x04, 0x21); /* Cascade (slave) on IRQ2 */
	outb(0x03, 0x21); /* Select 8086 mode , auto eoi*/
	outb(0x0A, 0x20);
	/* init slave interrupt controller */
	outb(0x11, 0xA0); /* Start init sequence, edge triggered */
	outb(0x08, 0xA1); /* Vector base */
	outb(0x02, 0xA1); /* Cascade (slave) on IRQ2 */
	outb(0x03, 0xA1); /* Select 8086 mode, auto eoi */
	outb(0x0A, 0xA0);
	outb(cached_irq_mask[1],0xA1);
	outb(cached_irq_mask[0],0x21);
	//request_region(0x20,0x2,"pic1");
	//request_region(0xA0,0x2,"pic2");

	cascade.handler = bogus_int;
	cascade.name = "cascade";
	setup_irq(2,&cascade);
}