2 * linux/arch/sh/kernel/irq_maskreg.c
4 * Copyright (C) 2001 A&D Co., Ltd. <http://www.aandd.co.jp>
6 * This file may be copied or modified under the terms of the GNU
7 * General Public License. See linux/COPYING for more information.
9 * Interrupt handling for Simple external interrupt mask register
11 * This is for the machine which have single 16 bit register
12 * for masking external IRQ individually.
13 * Each bit of the register is for masking each interrupt.
16 #include <linux/config.h>
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/irq.h>
21 #include <asm/system.h>
23 #include <asm/machvec.h>
25 /* address of external interrupt mask register
26 * address must be set prior to use these (maybe in init_XXX_irq())
27 * XXX : is it better to use .config than specifying it in code? */
28 unsigned short *irq_mask_register
= 0;
30 /* forward declaration */
31 static unsigned int startup_maskreg_irq(unsigned int irq
);
32 static void shutdown_maskreg_irq(unsigned int irq
);
33 static void enable_maskreg_irq(unsigned int irq
);
34 static void disable_maskreg_irq(unsigned int irq
);
35 static void mask_and_ack_maskreg(unsigned int);
36 static void end_maskreg_irq(unsigned int irq
);
38 /* hw_interrupt_type */
39 static struct hw_interrupt_type maskreg_irq_type
= {
49 /* actual implementatin */
50 static unsigned int startup_maskreg_irq(unsigned int irq
)
52 enable_maskreg_irq(irq
);
53 return 0; /* never anything pending */
56 static void shutdown_maskreg_irq(unsigned int irq
)
58 disable_maskreg_irq(irq
);
61 static void disable_maskreg_irq(unsigned int irq
)
63 if (irq_mask_register
) {
65 unsigned short val
, mask
= 0x01 << irq
;
68 local_irq_save(flags
);
69 val
= ctrl_inw((unsigned long)irq_mask_register
);
71 ctrl_outw(val
, (unsigned long)irq_mask_register
);
72 local_irq_restore(flags
);
76 static void enable_maskreg_irq(unsigned int irq
)
78 if (irq_mask_register
) {
80 unsigned short val
, mask
= ~(0x01 << irq
);
82 /* Clear "irq"th bit */
83 local_irq_save(flags
);
84 val
= ctrl_inw((unsigned long)irq_mask_register
);
86 ctrl_outw(val
, (unsigned long)irq_mask_register
);
87 local_irq_restore(flags
);
91 static void mask_and_ack_maskreg(unsigned int irq
)
93 disable_maskreg_irq(irq
);
96 static void end_maskreg_irq(unsigned int irq
)
98 if (!(irq_desc
[irq
].status
& (IRQ_DISABLED
|IRQ_INPROGRESS
)))
99 enable_maskreg_irq(irq
);
102 void make_maskreg_irq(unsigned int irq
)
104 disable_irq_nosync(irq
);
105 irq_desc
[irq
].handler
= &maskreg_irq_type
;
106 disable_maskreg_irq(irq
);