Tue Oct 4 15:38:31 2016 UTC ()
am335x's main interrupt source is 128.


(kiyohara)
diff -r1.9 -r1.10 src/sys/arch/arm/omap/omap2_icu.c

cvs diff -r1.9 -r1.10 src/sys/arch/arm/omap/Attic/omap2_icu.c (switch to unified diff)

--- src/sys/arch/arm/omap/Attic/omap2_icu.c 2012/08/20 12:38:28 1.9
+++ src/sys/arch/arm/omap/Attic/omap2_icu.c 2016/10/04 15:38:31 1.10
@@ -1,211 +1,219 @@ @@ -1,211 +1,219 @@
1/* $NetBSD: omap2_icu.c,v 1.9 2012/08/20 12:38:28 matt Exp $ */ 1/* $NetBSD: omap2_icu.c,v 1.10 2016/10/04 15:38:31 kiyohara Exp $ */
2/* 2/*
3 * Define the SDP2430 specific information and then include the generic OMAP 3 * Define the SDP2430 specific information and then include the generic OMAP
4 * interrupt header. 4 * interrupt header.
5 */ 5 */
6 6
7/* 7/*
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain this list of conditions 11 * 1. Redistributions of source code must retain this list of conditions
12 * and the following disclaimer. 12 * and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce this list of conditions 13 * 2. Redistributions in binary form must reproduce this list of conditions
14 * and the following disclaimer in the documentation and/or other materials 14 * and the following disclaimer in the documentation and/or other materials
15 * provided with the distribution. 15 * provided with the distribution.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 18 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY 19 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28#include "opt_omap.h" 28#include "opt_omap.h"
29 29
30#define _INTR_PRIVATE 30#define _INTR_PRIVATE
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: omap2_icu.c,v 1.9 2012/08/20 12:38:28 matt Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: omap2_icu.c,v 1.10 2016/10/04 15:38:31 kiyohara Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/evcnt.h> 36#include <sys/evcnt.h>
37#include <sys/device.h> 37#include <sys/device.h>
38 38
39#include <uvm/uvm_extern.h> 39#include <uvm/uvm_extern.h>
40 40
41#include <machine/intr.h> 41#include <machine/intr.h>
42#include <sys/bus.h> 42#include <sys/bus.h>
43 43
44#include <arm/cpu.h> 44#include <arm/cpu.h>
45#include <arm/armreg.h> 45#include <arm/armreg.h>
46#include <arm/cpufunc.h> 46#include <arm/cpufunc.h>
47#include <arm/atomic.h> 47#include <arm/atomic.h>
48 48
49#include <arm/omap/omap2_reg.h> 49#include <arm/omap/omap2_reg.h>
50#include <arm/omap/omap2_obiovar.h> 50#include <arm/omap/omap2_obiovar.h>
51 51
52 52
53#define INTC_READ(sc, g, o) \ 53#define INTC_READ(sc, g, o) \
54 bus_space_read_4((sc)->sc_memt, (sc)->sc_memh, (g) * 0x20 + (o)) 54 bus_space_read_4((sc)->sc_memt, (sc)->sc_memh, (g) * 0x20 + (o))
55#define INTC_WRITE(sc, g, o, v) \ 55#define INTC_WRITE(sc, g, o, v) \
56 bus_space_write_4((sc)->sc_memt, (sc)->sc_memh, (g) * 0x20 + (o), v) 56 bus_space_write_4((sc)->sc_memt, (sc)->sc_memh, (g) * 0x20 + (o), v)
57 57
58static int omap2icu_match(device_t, cfdata_t, void *); 58static int omap2icu_match(device_t, cfdata_t, void *);
59static void omap2icu_attach(device_t, device_t, void *); 59static void omap2icu_attach(device_t, device_t, void *);
60 60
61static void omap2icu_unblock_irqs(struct pic_softc *, size_t, uint32_t); 61static void omap2icu_unblock_irqs(struct pic_softc *, size_t, uint32_t);
62static void omap2icu_block_irqs(struct pic_softc *, size_t, uint32_t); 62static void omap2icu_block_irqs(struct pic_softc *, size_t, uint32_t);
63static void omap2icu_establish_irq(struct pic_softc *, struct intrsource *); 63static void omap2icu_establish_irq(struct pic_softc *, struct intrsource *);
64#if 0 64#if 0
65static void omap2icu_source_name(struct pic_softc *, int, char *, size_t); 65static void omap2icu_source_name(struct pic_softc *, int, char *, size_t);
66#endif 66#endif
67 67
68static const struct pic_ops omap2icu_picops = { 68static const struct pic_ops omap2icu_picops = {
69 .pic_unblock_irqs = omap2icu_unblock_irqs, 69 .pic_unblock_irqs = omap2icu_unblock_irqs,
70 .pic_block_irqs = omap2icu_block_irqs, 70 .pic_block_irqs = omap2icu_block_irqs,
71 .pic_establish_irq = omap2icu_establish_irq, 71 .pic_establish_irq = omap2icu_establish_irq,
72#if 0 72#if 0
73 .pic_source_name = omap2icu_source_name, 73 .pic_source_name = omap2icu_source_name,
74#endif 74#endif
75}; 75};
76 76
77#define PICTOSOFTC(pic) \ 77#define PICTOSOFTC(pic) \
78 ((void *)((uintptr_t)(pic) - offsetof(struct omap2icu_softc, sc_pic))) 78 ((void *)((uintptr_t)(pic) - offsetof(struct omap2icu_softc, sc_pic)))
79 79
80static struct omap2icu_softc { 80static struct omap2icu_softc {
81 device_t sc_dev; 81 device_t sc_dev;
82 bus_space_tag_t sc_memt; 82 bus_space_tag_t sc_memt;
83 bus_space_handle_t sc_memh; 83 bus_space_handle_t sc_memh;
84 struct pic_softc sc_pic; 84 struct pic_softc sc_pic;
 85#if defined(TI_AM335X)
 86 uint32_t sc_enabled_irqs[4];
 87#else
85 uint32_t sc_enabled_irqs[3]; 88 uint32_t sc_enabled_irqs[3];
 89#endif
86} omap2icu_softc = { 90} omap2icu_softc = {
87 .sc_pic = { 91 .sc_pic = {
88 .pic_ops = &omap2icu_picops, 92 .pic_ops = &omap2icu_picops,
 93#if defined(TI_AM335X)
 94 .pic_maxsources = 128,
 95#else
89 .pic_maxsources = 96, 96 .pic_maxsources = 96,
 97#endif
90 .pic_name = "omap2icu", 98 .pic_name = "omap2icu",
91 }, 99 },
92}; 100};
93 101
94static void 102static void
95omap2icu_unblock_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irq_mask) 103omap2icu_unblock_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irq_mask)
96{ 104{
97 struct omap2icu_softc * const sc = PICTOSOFTC(pic); 105 struct omap2icu_softc * const sc = PICTOSOFTC(pic);
98 const size_t group = irqbase / 32; 106 const size_t group = irqbase / 32;
99 KASSERT((irq_mask & sc->sc_enabled_irqs[group]) == 0); 107 KASSERT((irq_mask & sc->sc_enabled_irqs[group]) == 0);
100 sc->sc_enabled_irqs[group] |= irq_mask; 108 sc->sc_enabled_irqs[group] |= irq_mask;
101 INTC_WRITE(sc, group, INTC_MIR_CLEAR, irq_mask); 109 INTC_WRITE(sc, group, INTC_MIR_CLEAR, irq_mask);
102 110
103 /* Force INTC to recompute IRQ availability */ 111 /* Force INTC to recompute IRQ availability */
104 INTC_WRITE(sc, 0, INTC_CONTROL, INTC_CONTROL_NEWIRQAGR); 112 INTC_WRITE(sc, 0, INTC_CONTROL, INTC_CONTROL_NEWIRQAGR);
105} 113}
106 114
107static void 115static void
108omap2icu_block_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irq_mask) 116omap2icu_block_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irq_mask)
109{ 117{
110 struct omap2icu_softc * const sc = PICTOSOFTC(pic); 118 struct omap2icu_softc * const sc = PICTOSOFTC(pic);
111 const size_t group = irqbase / 32; 119 const size_t group = irqbase / 32;
112 120
113 INTC_WRITE(sc, group, INTC_MIR_SET, irq_mask); 121 INTC_WRITE(sc, group, INTC_MIR_SET, irq_mask);
114 sc->sc_enabled_irqs[group] &= ~irq_mask; 122 sc->sc_enabled_irqs[group] &= ~irq_mask;
115} 123}
116 124
117/* 125/*
118 * Called with interrupts disabled 126 * Called with interrupts disabled
119 */ 127 */
120static int 128static int
121find_pending_irqs(struct omap2icu_softc *sc, size_t group) 129find_pending_irqs(struct omap2icu_softc *sc, size_t group)
122{ 130{
123 uint32_t pending = INTC_READ(sc, group, INTC_PENDING_IRQ); 131 uint32_t pending = INTC_READ(sc, group, INTC_PENDING_IRQ);
124 132
125 KASSERT((sc->sc_enabled_irqs[group] & pending) == pending); 133 KASSERT((sc->sc_enabled_irqs[group] & pending) == pending);
126 134
127 if (pending == 0) 135 if (pending == 0)
128 return 0; 136 return 0;
129 137
130 return pic_mark_pending_sources(&sc->sc_pic, group * 32, pending); 138 return pic_mark_pending_sources(&sc->sc_pic, group * 32, pending);
131} 139}
132 140
133void 141void
134omap_irq_handler(void *frame) 142omap_irq_handler(void *frame)
135{ 143{
136 struct cpu_info * const ci = curcpu(); 144 struct cpu_info * const ci = curcpu();
137 struct omap2icu_softc * const sc = &omap2icu_softc; 145 struct omap2icu_softc * const sc = &omap2icu_softc;
138 const int oldipl = ci->ci_cpl; 146 const int oldipl = ci->ci_cpl;
139 const uint32_t oldipl_mask = __BIT(oldipl); 147 const uint32_t oldipl_mask = __BIT(oldipl);
140 int ipl_mask = 0; 148 int ipl_mask = 0;
141 149
142 ci->ci_data.cpu_nintr++; 150 ci->ci_data.cpu_nintr++;
143 151
144 if (sc->sc_enabled_irqs[0]) 152 if (sc->sc_enabled_irqs[0])
145 ipl_mask |= find_pending_irqs(sc, 0); 153 ipl_mask |= find_pending_irqs(sc, 0);
146 if (sc->sc_enabled_irqs[1]) 154 if (sc->sc_enabled_irqs[1])
147 ipl_mask |= find_pending_irqs(sc, 1); 155 ipl_mask |= find_pending_irqs(sc, 1);
148 if (sc->sc_enabled_irqs[2]) 156 if (sc->sc_enabled_irqs[2])
149 ipl_mask |= find_pending_irqs(sc, 2); 157 ipl_mask |= find_pending_irqs(sc, 2);
150 158
151 /* force INTC to recomputq IRQ */ 159 /* force INTC to recomputq IRQ */
152 INTC_WRITE(sc, 0, INTC_CONTROL, INTC_CONTROL_NEWIRQAGR); 160 INTC_WRITE(sc, 0, INTC_CONTROL, INTC_CONTROL_NEWIRQAGR);
153 161
154 /* 162 /*
155 * Record the pending_ipls and deliver them if we can. 163 * Record the pending_ipls and deliver them if we can.
156 */ 164 */
157 if ((ipl_mask & ~oldipl_mask) > oldipl_mask) 165 if ((ipl_mask & ~oldipl_mask) > oldipl_mask)
158 pic_do_pending_ints(I32_bit, oldipl, frame); 166 pic_do_pending_ints(I32_bit, oldipl, frame);
159} 167}
160 168
161void 169void
162omap2icu_establish_irq(struct pic_softc *pic, struct intrsource *is) 170omap2icu_establish_irq(struct pic_softc *pic, struct intrsource *is)
163{ 171{
164 KASSERT(is->is_irq < 96); 172 KASSERT(is->is_irq < omap2icu_softc.sc_pic.pic_maxsources);
165 KASSERT(is->is_type == IST_LEVEL); 173 KASSERT(is->is_type == IST_LEVEL);
166} 174}
167 175
168int 176int
169omap2icu_match(device_t parent, cfdata_t cf, void *aux) 177omap2icu_match(device_t parent, cfdata_t cf, void *aux)
170{ 178{
171 struct obio_attach_args * const oa = aux; 179 struct obio_attach_args * const oa = aux;
172 180
173#if defined(OMAP_2430) || defined(OMAP_2420) 181#if defined(OMAP_2430) || defined(OMAP_2420)
174 return oa->obio_addr == INTC_BASE; 182 return oa->obio_addr == INTC_BASE;
175#elif defined(OMAP3) 183#elif defined(OMAP3)
176 return oa->obio_addr == INTC_BASE_3530; 184 return oa->obio_addr == INTC_BASE_3530;
177#else 185#else
178#error unsupported OMAP variant 186#error unsupported OMAP variant
179#endif 187#endif
180} 188}
181 189
182void 190void
183omap2icu_attach(device_t parent, device_t self, void *aux) 191omap2icu_attach(device_t parent, device_t self, void *aux)
184{ 192{
185 struct obio_attach_args * const oa = aux; 193 struct obio_attach_args * const oa = aux;
186 struct omap2icu_softc * const sc = &omap2icu_softc; 194 struct omap2icu_softc * const sc = &omap2icu_softc;
187 int error; 195 int error;
188 196
189 aprint_normal("\n"); 197 aprint_normal("\n");
190 198
191 sc->sc_memt = oa->obio_iot; 199 sc->sc_memt = oa->obio_iot;
192 200
193 error = bus_space_map(sc->sc_memt, oa->obio_addr, 0x1000, 0, 201 error = bus_space_map(sc->sc_memt, oa->obio_addr, 0x1000, 0,
194 &sc->sc_memh); 202 &sc->sc_memh);
195 if (error) 203 if (error)
196 panic("failed to map interrupt registers: %d", error); 204 panic("failed to map interrupt registers: %d", error);
197 205
198 INTC_WRITE(sc, 0, INTC_MIR_SET, 0xffffffff); 206 INTC_WRITE(sc, 0, INTC_MIR_SET, 0xffffffff);
199 INTC_WRITE(sc, 1, INTC_MIR_SET, 0xffffffff); 207 INTC_WRITE(sc, 1, INTC_MIR_SET, 0xffffffff);
200 INTC_WRITE(sc, 2, INTC_MIR_SET, 0xffffffff); 208 INTC_WRITE(sc, 2, INTC_MIR_SET, 0xffffffff);
201 209
202 sc->sc_dev = self; 210 sc->sc_dev = self;
203 self->dv_private = sc; 211 self->dv_private = sc;
204 212
205 pic_add(&sc->sc_pic, 0); 213 pic_add(&sc->sc_pic, 0);
206} 214}
207 215
208CFATTACH_DECL_NEW(omap2icu, 216CFATTACH_DECL_NEW(omap2icu,
209 0, 217 0,
210 omap2icu_match, omap2icu_attach, 218 omap2icu_match, omap2icu_attach,
211 NULL, NULL); 219 NULL, NULL);