11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	include/asm-mips/i8259.h
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	i8259A interrupt definitions.
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Copyright (C) 2003  Maciej W. Rozycki
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Copyright (C) 2003  Ralf Baechle <ralf@linux-mips.org>
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	This program is free software; you can redistribute it and/or
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	modify it under the terms of the GNU General Public License
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	as published by the Free Software Foundation; either version
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	2 of the License, or (at your option) any later version.
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef _ASM_I8259_H
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _ASM_I8259_H
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/compiler.h>
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/spinlock.h>
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h>
212fa7937bd8922e1fe4aae6a45e7e787fa45d6043Atsushi Nemoto#include <irq.h>
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
232cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto/* i8259A PIC registers */
242cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto#define PIC_MASTER_CMD		0x20
252cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto#define PIC_MASTER_IMR		0x21
262cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto#define PIC_MASTER_ISR		PIC_MASTER_CMD
272cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto#define PIC_MASTER_POLL		PIC_MASTER_ISR
282cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto#define PIC_MASTER_OCW3		PIC_MASTER_ISR
292cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto#define PIC_SLAVE_CMD		0xa0
302cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto#define PIC_SLAVE_IMR		0xa1
312cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto
322cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto/* i8259A PIC related value */
332cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto#define PIC_CASCADE_IR		2
342cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto#define MASTER_ICW4_DEFAULT	0x01
352cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto#define SLAVE_ICW4_DEFAULT	0x01
362cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto#define PIC_ICW4_AEOI		2
372cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto
38896508705561bea24656680cdaf3b4095c4d7473Ralf Baechleextern raw_spinlock_t i8259A_lock;
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
40d80c1c0b2207ba326b2c06249dfebddf8ac863bdYoichi Yuasaextern int i8259A_irq_pending(unsigned int irq);
41d80c1c0b2207ba326b2c06249dfebddf8ac863bdYoichi Yuasaextern void make_8259A_irq(unsigned int irq);
422cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void init_i8259_irqs(void);
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Do the traditional i8259 interrupt polling thing.  This is for the few
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * cases where no better interrupt acknowledge method is available and we
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * absolutely must touch the i8259.
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int i8259_irq(void)
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int irq;
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
54896508705561bea24656680cdaf3b4095c4d7473Ralf Baechle	raw_spin_lock(&i8259A_lock);
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Perform an interrupt acknowledge cycle on controller 1. */
572cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto	outb(0x0C, PIC_MASTER_CMD);		/* prepare for poll */
582cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto	irq = inb(PIC_MASTER_CMD) & 7;
592cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto	if (irq == PIC_CASCADE_IR) {
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Interrupt is cascaded so perform interrupt
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * acknowledge on controller 2.
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
642cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto		outb(0x0C, PIC_SLAVE_CMD);		/* prepare for poll */
652cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto		irq = (inb(PIC_SLAVE_CMD) & 7) + 8;
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (unlikely(irq == 7)) {
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * This may be a spurious interrupt.
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 *
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Read the interrupt status register (ISR). If the most
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * significant bit is not set then there is no valid
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * interrupt.
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
762cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto		outb(0x0B, PIC_MASTER_ISR);		/* ISR register */
772cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto		if(~inb(PIC_MASTER_ISR) & 0x80)
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			irq = -1;
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
81896508705561bea24656680cdaf3b4095c4d7473Ralf Baechle	raw_spin_unlock(&i8259A_lock);
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
832cafe978462bc4016392aa330bf501a674679a86Atsushi Nemoto	return likely(irq >= 0) ? irq + I8259A_IRQ_BASE : irq;
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* _ASM_I8259_H */
87