bast-irq.c 3.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2
/* linux/arch/arm/mach-s3c2410/bast-irq.c
 *
3
 * Copyright (c) 2003,2005 Simtec Electronics
L
Linus Torvalds 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 *   Ben Dooks <ben@simtec.co.uk>
 *
 * http://www.simtec.co.uk/products/EB2410ITX/
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
*/
L
Linus Torvalds 已提交
22 23 24 25 26 27 28


#include <linux/init.h>
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/sysdev.h>

29 30
#include <asm/mach-types.h>

31
#include <mach/hardware.h>
L
Linus Torvalds 已提交
32 33 34 35
#include <asm/irq.h>
#include <asm/io.h>

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

37 38 39
#include <mach/regs-irq.h>
#include <mach/bast-map.h>
#include <mach/bast-irq.h>
40

41
#include <asm/plat-s3c24xx/irq.h>
L
Linus Torvalds 已提交
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

#if 0
#include <asm/debug-ll.h>
#endif

#define irqdbf(x...)
#define irqdbf2(x...)


/* handle PC104 ISA interrupts from the system CPLD */

/* table of ISA irq nos to the relevant mask... zero means
 * the irq is not implemented
*/
static unsigned char bast_pc104_irqmasks[] = {
	0,   /* 0 */
	0,   /* 1 */
	0,   /* 2 */
	1,   /* 3 */
	0,   /* 4 */
	2,   /* 5 */
	0,   /* 6 */
	4,   /* 7 */
	0,   /* 8 */
	0,   /* 9 */
	8,   /* 10 */
	0,   /* 11 */
	0,   /* 12 */
	0,   /* 13 */
	0,   /* 14 */
	0,   /* 15 */
};

static unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 };

static void
bast_pc104_mask(unsigned int irqno)
{
	unsigned long temp;

	temp = __raw_readb(BAST_VA_PC104_IRQMASK);
	temp &= ~bast_pc104_irqmasks[irqno];
	__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
}

static void
88
bast_pc104_maskack(unsigned int irqno)
L
Linus Torvalds 已提交
89
{
90
	struct irq_desc *desc = irq_desc + IRQ_ISA;
91 92 93

	bast_pc104_mask(irqno);
	desc->chip->ack(IRQ_ISA);
L
Linus Torvalds 已提交
94 95 96 97 98 99 100 101 102 103 104 105
}

static void
bast_pc104_unmask(unsigned int irqno)
{
	unsigned long temp;

	temp = __raw_readb(BAST_VA_PC104_IRQMASK);
	temp |= bast_pc104_irqmasks[irqno];
	__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
}

106
static struct irq_chip  bast_pc104_chip = {
L
Linus Torvalds 已提交
107 108
	.mask	     = bast_pc104_mask,
	.unmask	     = bast_pc104_unmask,
109
	.ack	     = bast_pc104_maskack
L
Linus Torvalds 已提交
110 111 112 113
};

static void
bast_irq_pc104_demux(unsigned int irq,
114
		     struct irq_desc *desc)
L
Linus Torvalds 已提交
115 116 117 118 119 120 121
{
	unsigned int stat;
	unsigned int irqno;
	int i;

	stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf;

122 123 124 125 126 127 128 129 130 131 132
	if (unlikely(stat == 0)) {
		/* ack if we get an irq with nothing (ie, startup) */

		desc = irq_desc + IRQ_ISA;
		desc->chip->ack(IRQ_ISA);
	} else {
		/* handle the IRQ */

		for (i = 0; stat != 0; i++, stat >>= 1) {
			if (stat & 1) {
				irqno = bast_pc104_irqs[i];
133
				desc = irq_desc + irqno;
134
				desc_handle_irq(irqno, desc);
135
			}
L
Linus Torvalds 已提交
136
		}
137 138
	}
}
L
Linus Torvalds 已提交
139

140 141 142 143 144 145 146 147 148 149 150 151 152
static __init int bast_irq_init(void)
{
	unsigned int i;

	if (machine_is_bast()) {
		printk(KERN_INFO "BAST PC104 IRQ routing, (c) 2005 Simtec Electronics\n");

		/* zap all the IRQs */

		__raw_writeb(0x0, BAST_VA_PC104_IRQMASK);

		set_irq_chained_handler(IRQ_ISA, bast_irq_pc104_demux);

153
		/* register our IRQs */
154 155 156 157 158

		for (i = 0; i < 4; i++) {
			unsigned int irqno = bast_pc104_irqs[i];

			set_irq_chip(irqno, &bast_pc104_chip);
159
			set_irq_handler(irqno, handle_level_irq);
160 161
			set_irq_flags(irqno, IRQF_VALID);
		}
L
Linus Torvalds 已提交
162
	}
163 164

	return 0;
L
Linus Torvalds 已提交
165
}
166 167

arch_initcall(bast_irq_init);