| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * arch/sh/boards/saturn/irq.c | 
|  | 3 | * | 
|  | 4 | * Copyright (C) 2002 Paul Mundt | 
|  | 5 | * | 
|  | 6 | * Released under the terms of the GNU GPL v2.0. | 
|  | 7 | */ | 
|  | 8 | #include <linux/kernel.h> | 
|  | 9 | #include <linux/init.h> | 
|  | 10 | #include <linux/interrupt.h> | 
|  | 11 | #include <asm/irq.h> | 
|  | 12 | #include <asm/io.h> | 
|  | 13 |  | 
|  | 14 | /* | 
|  | 15 | * Interrupts map out as follows: | 
|  | 16 | * | 
|  | 17 | *  Vector	Name		Mask | 
|  | 18 | * | 
|  | 19 | * 	64	VBLANKIN	0x0001 | 
|  | 20 | * 	65	VBLANKOUT	0x0002 | 
|  | 21 | *	66	HBLANKIN	0x0004 | 
|  | 22 | *	67	TIMER0		0x0008 | 
|  | 23 | *	68	TIMER1		0x0010 | 
|  | 24 | *	69	DSPEND		0x0020 | 
|  | 25 | *	70	SOUNDREQUEST	0x0040 | 
|  | 26 | *	71	SYSTEMMANAGER	0x0080 | 
|  | 27 | *	72	PAD		0x0100 | 
|  | 28 | *	73	LEVEL2DMAEND	0x0200 | 
|  | 29 | *	74	LEVEL1DMAEND	0x0400 | 
|  | 30 | *	75	LEVEL0DMAEND	0x0800 | 
|  | 31 | *	76	DMAILLEGAL	0x1000 | 
|  | 32 | *	77	SRITEDRAWEND	0x2000 | 
|  | 33 | *	78	ABUS		0x8000 | 
|  | 34 | * | 
|  | 35 | */ | 
|  | 36 | #define SATURN_IRQ_MIN		64	/* VBLANKIN */ | 
|  | 37 | #define SATURN_IRQ_MAX		78	/* ABUS */ | 
|  | 38 |  | 
|  | 39 | #define SATURN_IRQ_MASK		0xbfff | 
|  | 40 |  | 
|  | 41 | static inline u32 saturn_irq_mask(unsigned int irq_nr) | 
|  | 42 | { | 
|  | 43 | u32 mask; | 
|  | 44 |  | 
|  | 45 | mask = (1 << (irq_nr - SATURN_IRQ_MIN)); | 
|  | 46 | mask <<= (irq_nr == SATURN_IRQ_MAX); | 
|  | 47 | mask &= SATURN_IRQ_MASK; | 
|  | 48 |  | 
|  | 49 | return mask; | 
|  | 50 | } | 
|  | 51 |  | 
|  | 52 | static inline void mask_saturn_irq(unsigned int irq_nr) | 
|  | 53 | { | 
|  | 54 | u32 mask; | 
|  | 55 |  | 
|  | 56 | mask = ctrl_inl(SATURN_IMR); | 
|  | 57 | mask |= saturn_irq_mask(irq_nr); | 
|  | 58 | ctrl_outl(mask, SATURN_IMR); | 
|  | 59 | } | 
|  | 60 |  | 
|  | 61 | static inline void unmask_saturn_irq(unsigned int irq_nr) | 
|  | 62 | { | 
|  | 63 | u32 mask; | 
|  | 64 |  | 
|  | 65 | mask = ctrl_inl(SATURN_IMR); | 
|  | 66 | mask &= ~saturn_irq_mask(irq_nr); | 
|  | 67 | ctrl_outl(mask, SATURN_IMR); | 
|  | 68 | } | 
|  | 69 |  | 
|  | 70 | static void disable_saturn_irq(unsigned int irq_nr) | 
|  | 71 | { | 
|  | 72 | mask_saturn_irq(irq_nr); | 
|  | 73 | } | 
|  | 74 |  | 
|  | 75 | static void enable_saturn_irq(unsigned int irq_nr) | 
|  | 76 | { | 
|  | 77 | unmask_saturn_irq(irq_nr); | 
|  | 78 | } | 
|  | 79 |  | 
|  | 80 | static void mask_and_ack_saturn_irq(unsigned int irq_nr) | 
|  | 81 | { | 
|  | 82 | mask_saturn_irq(irq_nr); | 
|  | 83 | } | 
|  | 84 |  | 
|  | 85 | static void end_saturn_irq(unsigned int irq_nr) | 
|  | 86 | { | 
|  | 87 | if (!(irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | 
|  | 88 | unmask_saturn_irq(irq_nr); | 
|  | 89 | } | 
|  | 90 |  | 
|  | 91 | static unsigned int startup_saturn_irq(unsigned int irq_nr) | 
|  | 92 | { | 
|  | 93 | unmask_saturn_irq(irq_nr); | 
|  | 94 |  | 
|  | 95 | return 0; | 
|  | 96 | } | 
|  | 97 |  | 
|  | 98 | static void shutdown_saturn_irq(unsigned int irq_nr) | 
|  | 99 | { | 
|  | 100 | mask_saturn_irq(irq_nr); | 
|  | 101 | } | 
|  | 102 |  | 
|  | 103 | static struct hw_interrupt_type saturn_int = { | 
|  | 104 | .typename	= "Saturn", | 
|  | 105 | .enable		= enable_saturn_irq, | 
|  | 106 | .disable	= disable_saturn_irq, | 
|  | 107 | .ack		= mask_and_ack_saturn_irq, | 
|  | 108 | .end		= end_saturn_irq, | 
|  | 109 | .startup	= startup_saturn_irq, | 
|  | 110 | .shutdown	= shutdown_saturn_irq, | 
|  | 111 | }; | 
|  | 112 |  | 
|  | 113 | int saturn_irq_demux(int irq_nr) | 
|  | 114 | { | 
|  | 115 | /* FIXME */ | 
|  | 116 | return irq_nr; | 
|  | 117 | } | 
|  | 118 |  |