1*cbab9cadSchs /* $NetBSD: vr4181ip.c,v 1.4 2012/10/27 17:17:55 chs Exp $ */
2f8bc0014Sigy
3f8bc0014Sigy /*-
4f8bc0014Sigy * Copyright (c) 1999, 2002
5f8bc0014Sigy * Shin Takemura and PocketBSD Project. All rights reserved.
6f8bc0014Sigy *
7f8bc0014Sigy * Redistribution and use in source and binary forms, with or without
8f8bc0014Sigy * modification, are permitted provided that the following conditions
9f8bc0014Sigy * are met:
10f8bc0014Sigy * 1. Redistributions of source code must retain the above copyright
11f8bc0014Sigy * notice, this list of conditions and the following disclaimer.
12f8bc0014Sigy * 2. Redistributions in binary form must reproduce the above copyright
13f8bc0014Sigy * notice, this list of conditions and the following disclaimer in the
14f8bc0014Sigy * documentation and/or other materials provided with the distribution.
15f8bc0014Sigy * 3. Neither the name of the project nor the names of its contributors
16f8bc0014Sigy * may be used to endorse or promote products derived from this software
17f8bc0014Sigy * without specific prior written permission.
18f8bc0014Sigy *
19f8bc0014Sigy * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20f8bc0014Sigy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21f8bc0014Sigy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22f8bc0014Sigy * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23f8bc0014Sigy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24f8bc0014Sigy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25f8bc0014Sigy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26f8bc0014Sigy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27f8bc0014Sigy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28f8bc0014Sigy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29f8bc0014Sigy * SUCH DAMAGE.
30f8bc0014Sigy *
31f8bc0014Sigy */
32f8bc0014Sigy
330c82163cSlukem #include <sys/cdefs.h>
34*cbab9cadSchs __KERNEL_RCSID(0, "$NetBSD: vr4181ip.c,v 1.4 2012/10/27 17:17:55 chs Exp $");
350c82163cSlukem
36f8bc0014Sigy #include "opt_vr41xx.h"
37f8bc0014Sigy
38f8bc0014Sigy #include <sys/param.h>
39f8bc0014Sigy #include <sys/device.h>
40f8bc0014Sigy #include <sys/systm.h>
41f8bc0014Sigy
42f8bc0014Sigy #include <machine/bus.h>
43f8bc0014Sigy
44f8bc0014Sigy #include <hpcmips/vr/vrcpudef.h>
45f8bc0014Sigy #include <hpcmips/vr/vripunit.h>
46f8bc0014Sigy #include <hpcmips/vr/vripreg.h>
47f8bc0014Sigy #include <hpcmips/vr/vripvar.h>
48f8bc0014Sigy #include <hpcmips/vr/vr4181ipvar.h>
49f8bc0014Sigy #include <hpcmips/vr/icureg.h>
50f8bc0014Sigy #include <hpcmips/vr/cmureg.h>
51f8bc0014Sigy
52*cbab9cadSchs static void vr4181ipattach(device_t, device_t, void *);
53f8bc0014Sigy
54*cbab9cadSchs CFATTACH_DECL_NEW(vr4181ip, sizeof(struct vrip_softc),
55f8bc0014Sigy vripmatch, vr4181ipattach, NULL, NULL);
56f8bc0014Sigy
57f8bc0014Sigy static const struct vrip_unit vr4181ip_units[] = {
58f8bc0014Sigy [VRIP_UNIT_RTC] = { "rtc",
59f8bc0014Sigy { VRIP_INTR_RTCL1, }, },
60f8bc0014Sigy [VRIP_UNIT_SIU] = { "siu",
61f8bc0014Sigy { VRIP_INTR_SIU, }, },
62f8bc0014Sigy [VRIP_UNIT_GIU] = { "giu",
63f8bc0014Sigy { VRIP_INTR_GIU, }, },
64f8bc0014Sigy [VRIP_UNIT_ECU] = { "ecu",
65f8bc0014Sigy { VRIP_INTR_ECU, }, },
66f8bc0014Sigy [VRIP_UNIT_AIU] = { "aiu",
67f8bc0014Sigy { VRIP_INTR_DCU81, }, },
68f8bc0014Sigy #if 0
69f8bc0014Sigy [VRIP_UNIT_PMU] = { "pmu",
70f8bc0014Sigy { VRIP_INTR_POWER, VRIP_INTR_BAT, }, },
71f8bc0014Sigy [VRIP_UNIT_PIU] = { "piu",
72f8bc0014Sigy { VRIP_INTR_PIU, },
73f8bc0014Sigy CMUMASK_PIU,
74f8bc0014Sigy ICUPIUINT_REG_W, MPIUINT_REG_W },
75f8bc0014Sigy [VRIP_UNIT_KIU] = { "kiu",
76f8bc0014Sigy { VRIP_INTR_KIU, },
77f8bc0014Sigy CMUMASK_KIU,
78f8bc0014Sigy KIUINT_REG_W, MKIUINT_REG_W },
79f8bc0014Sigy [VRIP_UNIT_LED] = { "led",
80f8bc0014Sigy { VRIP_INTR_LED, }, },
81f8bc0014Sigy [VRIP_UNIT_AIU] = { "aiu",
82f8bc0014Sigy { VRIP_INTR_AIU, },
83f8bc0014Sigy CMUMASK_AIU,
84f8bc0014Sigy AIUINT_REG_W, MAIUINT_REG_W },
85f8bc0014Sigy [VRIP_UNIT_FIR] = { "fir",
86f8bc0014Sigy { VRIP_INTR_FIR, },
87f8bc0014Sigy CMUMASK_FIR,
88f8bc0014Sigy FIRINT_REG_W, MFIRINT_REG_W },
89f8bc0014Sigy [VRIP_UNIT_DSIU]= { "dsiu",
90f8bc0014Sigy { VRIP_INTR_DSIU, },
91f8bc0014Sigy CMUMASK_DSIU,
92f8bc0014Sigy DSIUINT_REG_W, MDSIUINT_REG_W },
93f8bc0014Sigy [VRIP_UNIT_PCIU]= { "pciu",
94f8bc0014Sigy { VRIP_INTR_PCI, },
95f8bc0014Sigy CMUMASK_PCIU,
96f8bc0014Sigy PCIINT_REG_W, MPCIINT_REG_W },
97f8bc0014Sigy [VRIP_UNIT_SCU] = { "scu",
98f8bc0014Sigy { VRIP_INTR_SCU, },
99f8bc0014Sigy 0,
100f8bc0014Sigy SCUINT_REG_W, MSCUINT_REG_W },
101f8bc0014Sigy [VRIP_UNIT_CSI] = { "csi",
102f8bc0014Sigy { VRIP_INTR_CSI, },
103f8bc0014Sigy CMUMASK_CSI,
104f8bc0014Sigy CSIINT_REG_W, MCSIINT_REG_W },
105f8bc0014Sigy [VRIP_UNIT_BCU] = { "bcu",
106f8bc0014Sigy { VRIP_INTR_BCU, },
107f8bc0014Sigy 0,
108f8bc0014Sigy BCUINT_REG_W, MBCUINT_REG_W },
109f8bc0014Sigy #endif
110f8bc0014Sigy };
111f8bc0014Sigy
112f8bc0014Sigy #define MAXCOMINTR 2
113f8bc0014Sigy
114f8bc0014Sigy struct vr4181ip_intrhand {
115f8bc0014Sigy int (*ih_fun)(void *);
116f8bc0014Sigy void *ih_arg;
117f8bc0014Sigy };
118f8bc0014Sigy
119f8bc0014Sigy static struct vr4181ip_intrhand intrhands[MAXCOMINTR];
120f8bc0014Sigy static int registered = 0;
121f8bc0014Sigy
122f8bc0014Sigy
123f8bc0014Sigy static void
vr4181ipattach(device_t parent,device_t self,void * aux)124*cbab9cadSchs vr4181ipattach(device_t parent, device_t self, void *aux)
125f8bc0014Sigy {
126*cbab9cadSchs struct vrip_softc *sc = device_private(self);
127f8bc0014Sigy
128f8bc0014Sigy printf("\n");
129f8bc0014Sigy
130f8bc0014Sigy sc->sc_units = vr4181ip_units;
131f8bc0014Sigy sc->sc_nunits = sizeof(vr4181ip_units)/sizeof(struct vrip_unit);
132f8bc0014Sigy sc->sc_icu_addr = VR4181_ICU_ADDR;
133f8bc0014Sigy sc->sc_sysint2 = VR4181_SYSINT2_REG_W;
134f8bc0014Sigy sc->sc_msysint2 = VR4181_MSYSINT2_REG_W;
135f8bc0014Sigy
136f8bc0014Sigy vripattach_common(parent, self, aux);
137f8bc0014Sigy }
138f8bc0014Sigy
139f8bc0014Sigy static int
vr4181ip_comintr(void * arg)140f8bc0014Sigy vr4181ip_comintr(void *arg)
141f8bc0014Sigy {
142f8bc0014Sigy struct vr4181ip_intrhand *ih = arg;
143f8bc0014Sigy int i;
144f8bc0014Sigy
145f8bc0014Sigy for (i = 0; i < MAXCOMINTR; i++) {
146f8bc0014Sigy if (ih[i].ih_fun)
147f8bc0014Sigy ih[i].ih_fun(ih[i].ih_arg);
148f8bc0014Sigy }
149f8bc0014Sigy return 1;
150f8bc0014Sigy }
151f8bc0014Sigy
152f8bc0014Sigy void
vr4181ip_comintr_establish(vrip_chipset_tag_t vc,int unit,int line,int level,int (* ih_fun)(void *),void * ih_arg)153f8bc0014Sigy vr4181ip_comintr_establish(vrip_chipset_tag_t vc, int unit, int line,
154f8bc0014Sigy int level, int (*ih_fun)(void *), void *ih_arg)
155f8bc0014Sigy {
156f8bc0014Sigy int i;
157f8bc0014Sigy
158f8bc0014Sigy if (!registered) {
159f8bc0014Sigy if (!vrip_intr_establish(vc, unit, 0, IPL_TTY,
160f8bc0014Sigy vr4181ip_comintr, intrhands)) {
161f8bc0014Sigy panic("vr4181ip_comintr_establish: "
162f8bc0014Sigy "can't map interrupt line.");
163f8bc0014Sigy }
164f8bc0014Sigy registered = 1;
165f8bc0014Sigy }
166f8bc0014Sigy
167f8bc0014Sigy for (i = 0; i < MAXCOMINTR; i++) {
168f8bc0014Sigy if (intrhands[i].ih_fun == NULL) {
169f8bc0014Sigy intrhands[i].ih_fun = ih_fun;
170f8bc0014Sigy intrhands[i].ih_arg = ih_arg;
171f8bc0014Sigy break;
172f8bc0014Sigy }
173f8bc0014Sigy }
174f8bc0014Sigy if (i >= MAXCOMINTR)
175f8bc0014Sigy panic("too many vr4181 SIU");
176f8bc0014Sigy }
177