]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - arch/sh/kernel/cpu/irq/ipr.c
Remove obsolete #include <linux/config.h>
[mirror_ubuntu-jammy-kernel.git] / arch / sh / kernel / cpu / irq / ipr.c
CommitLineData
bf3a00f8
PM
1/*
2 * arch/sh/kernel/cpu/irq/ipr.c
1da177e4
LT
3 *
4 * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi
5 * Copyright (C) 2000 Kazumoto Kojima
6 * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
7 *
8 * Interrupt handling for IPR-based IRQ.
9 *
10 * Supported system:
11 * On-chip supporting modules (TMU, RTC, etc.).
12 * On-chip supporting modules for SH7709/SH7709A/SH7729/SH7300.
13 * Hitachi SolutionEngine external I/O:
14 * MS7709SE01, MS7709ASE01, and MS7750SE01
15 *
16 */
17
1da177e4
LT
18#include <linux/init.h>
19#include <linux/irq.h>
20#include <linux/module.h>
21
22#include <asm/system.h>
23#include <asm/io.h>
24#include <asm/machvec.h>
25
26struct ipr_data {
27 unsigned int addr; /* Address of Interrupt Priority Register */
28 int shift; /* Shifts of the 16-bit data */
29 int priority; /* The priority */
30};
31static struct ipr_data ipr_data[NR_IRQS];
32
33static void enable_ipr_irq(unsigned int irq);
34static void disable_ipr_irq(unsigned int irq);
35
36/* shutdown is same as "disable" */
37#define shutdown_ipr_irq disable_ipr_irq
38
39static void mask_and_ack_ipr(unsigned int);
40static void end_ipr_irq(unsigned int irq);
41
42static unsigned int startup_ipr_irq(unsigned int irq)
43{
44 enable_ipr_irq(irq);
45 return 0; /* never anything pending */
46}
47
48static struct hw_interrupt_type ipr_irq_type = {
08d0fd07
TG
49 .typename = "IPR-IRQ",
50 .startup = startup_ipr_irq,
51 .shutdown = shutdown_ipr_irq,
52 .enable = enable_ipr_irq,
53 .disable = disable_ipr_irq,
54 .ack = mask_and_ack_ipr,
55 .end = end_ipr_irq
1da177e4
LT
56};
57
58static void disable_ipr_irq(unsigned int irq)
59{
60 unsigned long val, flags;
61 unsigned int addr = ipr_data[irq].addr;
62 unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift);
63
64 /* Set the priority in IPR to 0 */
65 local_irq_save(flags);
66 val = ctrl_inw(addr);
67 val &= mask;
68 ctrl_outw(val, addr);
69 local_irq_restore(flags);
70}
71
72static void enable_ipr_irq(unsigned int irq)
73{
74 unsigned long val, flags;
75 unsigned int addr = ipr_data[irq].addr;
76 int priority = ipr_data[irq].priority;
77 unsigned short value = (priority << ipr_data[irq].shift);
78
79 /* Set priority in IPR back to original value */
80 local_irq_save(flags);
81 val = ctrl_inw(addr);
82 val |= value;
83 ctrl_outw(val, addr);
84 local_irq_restore(flags);
85}
86
87static void mask_and_ack_ipr(unsigned int irq)
88{
89 disable_ipr_irq(irq);
90
91#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
92 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
93 /* This is needed when we use edge triggered setting */
94 /* XXX: Is it really needed? */
95 if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) {
96 /* Clear external interrupt request */
97 int a = ctrl_inb(INTC_IRR0);
98 a &= ~(1 << (irq - IRQ0_IRQ));
99 ctrl_outb(a, INTC_IRR0);
100 }
101#endif
102}
103
104static void end_ipr_irq(unsigned int irq)
105{
106 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
107 enable_ipr_irq(irq);
108}
109
8d27e081 110void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority)
1da177e4
LT
111{
112 disable_irq_nosync(irq);
113 ipr_data[irq].addr = addr;
114 ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */
115 ipr_data[irq].priority = priority;
116
d1bef4ed 117 irq_desc[irq].chip = &ipr_irq_type;
1da177e4
LT
118 disable_ipr_irq(irq);
119}
120
1da177e4
LT
121void __init init_IRQ(void)
122{
bf3a00f8 123#ifndef CONFIG_CPU_SUBTYPE_SH7780
8d27e081
PM
124 make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY);
125 make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY);
1da177e4 126#if defined(CONFIG_SH_RTC)
8d27e081 127 make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY);
1da177e4
LT
128#endif
129
130#ifdef SCI_ERI_IRQ
8d27e081
PM
131 make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
132 make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
133 make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
1da177e4
LT
134#endif
135
136#ifdef SCIF1_ERI_IRQ
8d27e081
PM
137 make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
138 make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
139 make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
140 make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
1da177e4
LT
141#endif
142
143#if defined(CONFIG_CPU_SUBTYPE_SH7300)
8d27e081
PM
144 make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY);
145 make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
146 make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
147 make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
1da177e4
LT
148#endif
149
150#ifdef SCIF_ERI_IRQ
8d27e081
PM
151 make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
152 make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
153 make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
154 make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
1da177e4
LT
155#endif
156
157#ifdef IRDA_ERI_IRQ
8d27e081
PM
158 make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
159 make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
160 make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
161 make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
1da177e4
LT
162#endif
163
164#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
165 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
166 /*
167 * Initialize the Interrupt Controller (INTC)
168 * registers to their power on values
169 */
170
171 /*
172 * Enable external irq (INTC IRQ mode).
173 * You should set corresponding bits of PFC to "00"
174 * to enable these interrupts.
175 */
8d27e081
PM
176 make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY);
177 make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY);
178 make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY);
179 make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY);
180 make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY);
181 make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY);
bf3a00f8
PM
182#endif
183#endif
1da177e4 184
bf3a00f8
PM
185#ifdef CONFIG_CPU_HAS_PINT_IRQ
186 init_IRQ_pint();
187#endif
1da177e4 188
bf3a00f8 189#ifdef CONFIG_CPU_HAS_INTC2_IRQ
1da177e4
LT
190 init_IRQ_intc2();
191#endif
1da177e4 192 /* Perform the machine specific initialisation */
bf3a00f8 193 if (sh_mv.mv_init_irq != NULL)
1da177e4 194 sh_mv.mv_init_irq();
1da177e4 195}
bf3a00f8
PM
196
197#if !defined(CONFIG_CPU_HAS_PINT_IRQ)
1da177e4
LT
198int ipr_irq_demux(int irq)
199{
1da177e4
LT
200 return irq;
201}
202#endif
203
204EXPORT_SYMBOL(make_ipr_irq);