bast-irq.c 3.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2
/* linux/arch/arm/mach-s3c2410/bast-irq.c
 *
3
 * Copyright 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


#include <linux/init.h>
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/sysdev.h>
28
#include <linux/io.h>
L
Linus Torvalds 已提交
29

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

32
#include <mach/hardware.h>
L
Linus Torvalds 已提交
33 34 35
#include <asm/irq.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 <plat/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

#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
78
bast_pc104_mask(struct irq_data *data)
L
Linus Torvalds 已提交
79 80 81 82
{
	unsigned long temp;

	temp = __raw_readb(BAST_VA_PC104_IRQMASK);
83
	temp &= ~bast_pc104_irqmasks[data->irq];
L
Linus Torvalds 已提交
84 85 86 87
	__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
}

static void
88
bast_pc104_maskack(struct irq_data *data)
L
Linus Torvalds 已提交
89
{
90
	struct irq_desc *desc = irq_desc + IRQ_ISA;
91

92 93
	bast_pc104_mask(data);
	desc->irq_data.chip->irq_ack(&desc->irq_data);
L
Linus Torvalds 已提交
94 95 96
}

static void
97
bast_pc104_unmask(struct irq_data *data)
L
Linus Torvalds 已提交
98 99 100 101
{
	unsigned long temp;

	temp = __raw_readb(BAST_VA_PC104_IRQMASK);
102
	temp |= bast_pc104_irqmasks[data->irq];
L
Linus Torvalds 已提交
103 104 105
	__raw_writeb(temp, BAST_VA_PC104_IRQMASK);
}

106
static struct irq_chip  bast_pc104_chip = {
107 108 109
	.irq_mask	= bast_pc104_mask,
	.irq_unmask	= bast_pc104_unmask,
	.irq_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
	if (unlikely(stat == 0)) {
		/* ack if we get an irq with nothing (ie, startup) */

		desc = irq_desc + IRQ_ISA;
126
		desc->irq_data.chip->irq_ack(&desc->irq_data);
127 128 129 130 131 132
	} else {
		/* handle the IRQ */

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

139 140 141 142 143
static __init int bast_irq_init(void)
{
	unsigned int i;

	if (machine_is_bast()) {
144
		printk(KERN_INFO "BAST PC104 IRQ routing, Copyright 2005 Simtec Electronics\n");
145 146 147 148 149 150 151

		/* zap all the IRQs */

		__raw_writeb(0x0, BAST_VA_PC104_IRQMASK);

		set_irq_chained_handler(IRQ_ISA, bast_irq_pc104_demux);

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

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

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

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

arch_initcall(bast_irq_init);