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