diff options
Diffstat (limited to 'arch/sh/boards/mach-systemh/irq.c')
-rw-r--r-- | arch/sh/boards/mach-systemh/irq.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/arch/sh/boards/mach-systemh/irq.c b/arch/sh/boards/mach-systemh/irq.c new file mode 100644 index 000000000000..601c9c8cdbec --- /dev/null +++ b/arch/sh/boards/mach-systemh/irq.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/boards/renesas/systemh/irq.c | ||
3 | * | ||
4 | * Copyright (C) 2000 Kazumoto Kojima | ||
5 | * | ||
6 | * Hitachi SystemH Support. | ||
7 | * | ||
8 | * Modified for 7751 SystemH by | ||
9 | * Jonathan Short. | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | |||
16 | #include <asm/io.h> | ||
17 | #include <asm/systemh7751.h> | ||
18 | #include <asm/smc37c93x.h> | ||
19 | |||
20 | /* address of external interrupt mask register | ||
21 | * address must be set prior to use these (maybe in init_XXX_irq()) | ||
22 | * XXX : is it better to use .config than specifying it in code? */ | ||
23 | static unsigned long *systemh_irq_mask_register = (unsigned long *)0xB3F10004; | ||
24 | static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000; | ||
25 | |||
26 | /* forward declaration */ | ||
27 | static unsigned int startup_systemh_irq(unsigned int irq); | ||
28 | static void shutdown_systemh_irq(unsigned int irq); | ||
29 | static void enable_systemh_irq(unsigned int irq); | ||
30 | static void disable_systemh_irq(unsigned int irq); | ||
31 | static void mask_and_ack_systemh(unsigned int); | ||
32 | static void end_systemh_irq(unsigned int irq); | ||
33 | |||
34 | /* hw_interrupt_type */ | ||
35 | static struct hw_interrupt_type systemh_irq_type = { | ||
36 | .typename = " SystemH Register", | ||
37 | .startup = startup_systemh_irq, | ||
38 | .shutdown = shutdown_systemh_irq, | ||
39 | .enable = enable_systemh_irq, | ||
40 | .disable = disable_systemh_irq, | ||
41 | .ack = mask_and_ack_systemh, | ||
42 | .end = end_systemh_irq | ||
43 | }; | ||
44 | |||
45 | static unsigned int startup_systemh_irq(unsigned int irq) | ||
46 | { | ||
47 | enable_systemh_irq(irq); | ||
48 | return 0; /* never anything pending */ | ||
49 | } | ||
50 | |||
51 | static void shutdown_systemh_irq(unsigned int irq) | ||
52 | { | ||
53 | disable_systemh_irq(irq); | ||
54 | } | ||
55 | |||
56 | static void disable_systemh_irq(unsigned int irq) | ||
57 | { | ||
58 | if (systemh_irq_mask_register) { | ||
59 | unsigned long val, mask = 0x01 << 1; | ||
60 | |||
61 | /* Clear the "irq"th bit in the mask and set it in the request */ | ||
62 | val = ctrl_inl((unsigned long)systemh_irq_mask_register); | ||
63 | val &= ~mask; | ||
64 | ctrl_outl(val, (unsigned long)systemh_irq_mask_register); | ||
65 | |||
66 | val = ctrl_inl((unsigned long)systemh_irq_request_register); | ||
67 | val |= mask; | ||
68 | ctrl_outl(val, (unsigned long)systemh_irq_request_register); | ||
69 | } | ||
70 | } | ||
71 | |||
72 | static void enable_systemh_irq(unsigned int irq) | ||
73 | { | ||
74 | if (systemh_irq_mask_register) { | ||
75 | unsigned long val, mask = 0x01 << 1; | ||
76 | |||
77 | /* Set "irq"th bit in the mask register */ | ||
78 | val = ctrl_inl((unsigned long)systemh_irq_mask_register); | ||
79 | val |= mask; | ||
80 | ctrl_outl(val, (unsigned long)systemh_irq_mask_register); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | static void mask_and_ack_systemh(unsigned int irq) | ||
85 | { | ||
86 | disable_systemh_irq(irq); | ||
87 | } | ||
88 | |||
89 | static void end_systemh_irq(unsigned int irq) | ||
90 | { | ||
91 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
92 | enable_systemh_irq(irq); | ||
93 | } | ||
94 | |||
95 | void make_systemh_irq(unsigned int irq) | ||
96 | { | ||
97 | disable_irq_nosync(irq); | ||
98 | irq_desc[irq].chip = &systemh_irq_type; | ||
99 | disable_systemh_irq(irq); | ||
100 | } | ||
101 | |||