1 /* $NetBSD: vrgiu.c,v 1.40 2005/12/11 12:17:34 christos Exp $ */
3 * Copyright (c) 1999-2001
4 * Shin Takemura and PocketBSD Project. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by the PocketBSD project
17 * and its contributors.
18 * 4. Neither the name of the project nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: vrgiu.c,v 1.40 2005/12/11 12:17:34 christos Exp $");
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/device.h>
42 #include <sys/malloc.h>
43 #include <sys/queue.h>
44 #include <sys/reboot.h>
46 #include <mips/cpuregs.h>
47 #include <machine/bus.h>
48 #include <machine/config_hook.h>
49 #include <machine/debug.h>
51 #include <dev/hpc/hpciovar.h>
53 #include "opt_vr41xx.h"
54 #include <hpcmips/vr/vrcpudef.h>
55 #include <hpcmips/vr/vripif.h>
56 #include <hpcmips/vr/vripreg.h>
57 #include <hpcmips/vr/vrgiureg.h>
62 * constant and macro definitions
68 #ifndef VRGIUDEBUG_CONF
69 #define VRGIUDEBUG_CONF 0
70 #endif /* VRGIUDEBUG_CONF */
71 int vrgiu_debug
= VRGIUDEBUG_CONF
;
72 #define DPRINTF(flag, arg) if (vrgiu_debug & flag) printf arg;
73 #define DDUMP_IO(flag, sc) if (vrgiu_debug & flag) vrgiu_dump_io(sc);
74 #define DDUMP_IOSETTING(flag, sc) \
75 if (vrgiu_debug & flag) vrgiu_dump_iosetting(sc);
76 #define VPRINTF(flag, arg) \
77 if (bootverbose || vrgiu_debug & flag) printf arg;
78 #define VDUMP_IO(flag, sc) \
79 if (bootverbose || vrgiu_debug & flag) vrgiu_dump_io(sc);
80 #define VDUMP_IOSETTING(flag, sc) \
81 if (bootverbose || vrgiu_debug & flag) vrgiu_dump_iosetting(sc);
83 #define DPRINTF(flag, arg)
84 #define DDUMP_IO(flag, sc)
85 #define DDUMP_IOSETTING(flag, sc)
86 #define VPRINTF(flag, arg) if (bootverbose) printf arg;
87 #define VDUMP_IO(flag, sc) if (bootverbose) vrgiu_dump_io(sc);
88 #define VDUMP_IOSETTING(flag, sc) \
89 if (bootverbose) vrgiu_dump_iosetting(sc);
92 #ifdef VRGIU_INTR_NOLED
93 int vrgiu_intr_led
= 0;
94 #else /* VRGIU_INTR_NOLED */
95 int vrgiu_intr_led
= 1;
96 #endif /* VRGIU_INTR_NOLED */
98 #define MAX_GPIO_OUT 50 /* port 32:49 are output only port */
99 #define MAX_GPIO_INOUT 32 /* input/output port(0:31) */
101 #define LEGAL_INTR_PORT(x) ((x) >= 0 && (x) < MAX_GPIO_INOUT)
102 #define LEGAL_OUT_PORT(x) ((x) >= 0 && (x) < MAX_GPIO_OUT)
107 struct vrgiu_intr_entry
{
109 int (*ih_fun
)(void *);
111 TAILQ_ENTRY(vrgiu_intr_entry
) ih_link
;
115 struct device sc_dev
;
116 bus_space_tag_t sc_iot
;
117 bus_space_handle_t sc_ioh
;
119 vrip_chipset_tag_t sc_vc
;
121 u_int32_t sc_intr_mask
;
122 u_int32_t sc_intr_mode
[MAX_GPIO_INOUT
];
123 TAILQ_HEAD(, vrgiu_intr_entry
) sc_intr_head
[MAX_GPIO_INOUT
];
124 struct hpcio_chip sc_iochip
;
125 #ifndef SINGLE_VRIP_BASE
126 int sc_useupdn_reg
, sc_termupdn_reg
;
127 #endif /* SINGLE_VRIP_BASE */
130 #ifndef SINGLE_VRIP_BASE
131 #define GIUUSEUPDN_REG_W (sc->sc_useupdn_reg)
132 #define GIUTERMUPDN_REG_W (sc->sc_termupdn_reg)
133 #endif /* SINGLE_VRIP_BASE */
138 int vrgiu_match(struct device
*, struct cfdata
*, void*);
139 void vrgiu_attach(struct device
*, struct device
*, void*);
140 int vrgiu_intr(void*);
141 int vrgiu_print(void*, const char*);
142 void vrgiu_callback(struct device
*);
144 void vrgiu_dump_regs(struct vrgiu_softc
*);
145 void vrgiu_dump_io(struct vrgiu_softc
*);
146 void vrgiu_diff_io(void);
147 void vrgiu_dump_iosetting(struct vrgiu_softc
*);
148 void vrgiu_diff_iosetting(void);
149 u_int32_t
vrgiu_regread_4(struct vrgiu_softc
*, bus_addr_t
);
150 u_int16_t
vrgiu_regread(struct vrgiu_softc
*, bus_addr_t
);
151 void vrgiu_regwrite_4(struct vrgiu_softc
*, bus_addr_t
, u_int32_t
);
152 void vrgiu_regwrite(struct vrgiu_softc
*, bus_addr_t
, u_int16_t
);
154 static int vrgiu_port_read(hpcio_chip_t
, int);
155 static void vrgiu_port_write(hpcio_chip_t
, int, int);
156 static void *vrgiu_intr_establish(hpcio_chip_t
, int, int, int (*)(void *), void*);
157 static void vrgiu_intr_disestablish(hpcio_chip_t
, void*);
158 static void vrgiu_intr_clear(hpcio_chip_t
, void*);
159 static void vrgiu_register_iochip(hpcio_chip_t
, hpcio_chip_t
);
160 static void vrgiu_update(hpcio_chip_t
);
161 static void vrgiu_dump(hpcio_chip_t
);
162 static hpcio_chip_t
vrgiu_getchip(void*, int);
167 static struct hpcio_chip vrgiu_iochip
= {
168 .hc_portread
= vrgiu_port_read
,
169 .hc_portwrite
= vrgiu_port_write
,
170 .hc_intr_establish
= vrgiu_intr_establish
,
171 .hc_intr_disestablish
= vrgiu_intr_disestablish
,
172 .hc_intr_clear
= vrgiu_intr_clear
,
173 .hc_register_iochip
= vrgiu_register_iochip
,
174 .hc_update
= vrgiu_update
,
175 .hc_dump
= vrgiu_dump
,
178 CFATTACH_DECL(vrgiu
, sizeof(struct vrgiu_softc
),
179 vrgiu_match
, vrgiu_attach
, NULL
, NULL
);
181 struct vrgiu_softc
*this_giu
;
187 vrgiu_match(struct device
*parent
, struct cfdata
*cf
, void *aux
)
190 return (2); /* 1st attach group of vrip */
194 vrgiu_attach(struct device
*parent
, struct device
*self
, void *aux
)
196 struct vrip_attach_args
*va
= aux
;
197 struct vrgiu_softc
*sc
= (void*)self
;
198 struct hpcio_attach_args haa
;
201 #ifndef SINGLE_VRIP_BASE
202 if (va
->va_addr
== VR4102_GIU_ADDR
) {
203 sc
->sc_useupdn_reg
= VR4102_GIUUSEUPDN_REG_W
;
204 sc
->sc_termupdn_reg
= VR4102_GIUTERMUPDN_REG_W
;
206 if (va
->va_addr
== VR4122_GIU_ADDR
) {
207 sc
->sc_useupdn_reg
= VR4122_GIUUSEUPDN_REG_W
;
208 sc
->sc_termupdn_reg
= VR4122_GIUTERMUPDN_REG_W
;
210 panic("%s: unknown base address 0x%lx",
211 sc
->sc_dev
.dv_xname
, va
->va_addr
);
213 #endif /* SINGLE_VRIP_BASE */
216 sc
->sc_vc
= va
->va_vc
;
217 sc
->sc_iot
= va
->va_iot
;
218 bus_space_map(sc
->sc_iot
, va
->va_addr
, va
->va_size
,
219 0 /* no cache */, &sc
->sc_ioh
);
221 * Disable all interrupts.
223 sc
->sc_intr_mask
= 0;
225 #ifdef WINCE_DEFAULT_SETTING
226 #warning WINCE_DEFAULT_SETTING
228 VPRINTF(DEBUG_IO
, (" "
230 VPRINTF(DEBUG_IO
, (" "
231 "10987654321098765432109876543210\n"));
232 VPRINTF(DEBUG_IO
, ("WIN setting: "));
233 VDUMP_IOSETTING(DEBUG_IO
, sc
);
234 VPRINTF(DEBUG_IO
, ("\n"));
235 vrgiu_regwrite_4(sc
, GIUINTEN_REG
, sc
->sc_intr_mask
);
238 for (i
= 0; i
< MAX_GPIO_INOUT
; i
++)
239 TAILQ_INIT(&sc
->sc_intr_head
[i
]);
240 if (!(sc
->sc_ih
= vrip_intr_establish(va
->va_vc
, va
->va_unit
, 0,
241 IPL_BIO
, vrgiu_intr
, sc
))) {
242 printf("%s: can't establish interrupt\n", sc
->sc_dev
.dv_xname
);
246 * fill hpcio_chip structure
248 sc
->sc_iochip
= vrgiu_iochip
; /* structure copy */
249 sc
->sc_iochip
.hc_chipid
= VRIP_IOCHIP_VRGIU
;
250 sc
->sc_iochip
.hc_name
= sc
->sc_dev
.dv_xname
;
251 sc
->sc_iochip
.hc_sc
= sc
;
252 /* Register functions to upper interface */
253 vrip_register_gpio(va
->va_vc
, &sc
->sc_iochip
);
255 /* Display port status (Input/Output) for debugging */
256 VPRINTF(DEBUG_IO
, ("I/O setting: "));
257 VDUMP_IOSETTING(DEBUG_IO
, sc
);
258 VPRINTF(DEBUG_IO
, ("\n"));
259 VPRINTF(DEBUG_IO
, (" data:"));
260 VDUMP_IO(DEBUG_IO
, sc
);
265 haa
.haa_busname
= HPCIO_BUSNAME
;
267 haa
.haa_getchip
= vrgiu_getchip
;
268 haa
.haa_iot
= sc
->sc_iot
;
269 while (config_found(self
, &haa
, vrgiu_print
)) ;
273 #if 1 /* XXX Sometimes mounting root device failed. Why? XXX*/
274 config_defer(self
, vrgiu_callback
);
276 vrgiu_callback(self
);
281 vrgiu_callback(struct device
*self
)
283 struct vrgiu_softc
*sc
= (void*)self
;
284 struct hpcio_attach_args haa
;
286 haa
.haa_busname
= "vrisab";
288 haa
.haa_getchip
= vrgiu_getchip
;
289 haa
.haa_iot
= sc
->sc_iot
;
290 config_found(self
, &haa
, vrgiu_print
);
294 vrgiu_print(void *aux
, const char *pnp
)
302 vrgiu_dump_iosetting(struct vrgiu_softc
*sc
)
304 long iosel
, inten
, useupdn
, termupdn
, edge
, hold
, level
;
306 char syms
[] = "iiiiiiiilhLHeeEEoooooooooooooooo"
307 "DDDDDDDDDDDDDDDDUUUUUUUUUUUUUUUU";
309 iosel
= vrgiu_regread_4(sc
, GIUIOSEL_REG
);
310 inten
= vrgiu_regread_4(sc
, GIUINTEN_REG
);
311 edge
= vrgiu_regread_4(sc
, GIUINTTYP_REG
);
312 hold
= vrgiu_regread_4(sc
, GIUINTHTSEL_REG
);
313 level
= vrgiu_regread_4(sc
, GIUINTALSEL_REG
);
315 if (GIUUSEUPDN_REG_W
== GIU_NO_REG_W
)
318 useupdn
= vrgiu_regread(sc
, GIUUSEUPDN_REG_W
);
319 if (GIUTERMUPDN_REG_W
== GIU_NO_REG_W
)
322 termupdn
= vrgiu_regread(sc
, GIUTERMUPDN_REG_W
);
323 for (m
= 0x80000000; m
; m
>>=1)
325 ((useupdn
&m
) ? 32 : 0) +
326 ((iosel
&m
) ? 16 : 0) + ((termupdn
&m
) ? 16 : 0) +
327 ((inten
&m
) ? 8 : 0) +
330 ((level
&m
) ? 1 : 0)]);
334 vrgiu_diff_iosetting(void)
336 struct vrgiu_softc
*sc
= this_giu
;
337 static long oiosel
= 0, ointen
= 0, ouseupdn
= 0, otermupdn
= 0;
338 long iosel
, inten
, useupdn
, termupdn
;
341 iosel
= vrgiu_regread_4(sc
, GIUIOSEL_REG
);
342 inten
= vrgiu_regread_4(sc
, GIUINTEN_REG
);
343 if (GIUUSEUPDN_REG_W
== GIU_NO_REG_W
)
346 useupdn
= vrgiu_regread(sc
, GIUUSEUPDN_REG_W
);
347 if (GIUTERMUPDN_REG_W
== GIU_NO_REG_W
)
350 termupdn
= vrgiu_regread(sc
, GIUTERMUPDN_REG_W
);
351 if (oiosel
!= iosel
|| ointen
!= inten
||
352 ouseupdn
!= useupdn
|| otermupdn
!= termupdn
) {
353 for (m
= 0x80000000; m
; m
>>=1)
354 printf ("%c" , (useupdn
&m
) ?
355 ((termupdn
&m
) ? 'U' : 'D') :
356 ((iosel
&m
) ? 'o' : ((inten
&m
)?'I':'i')));
361 otermupdn
= termupdn
;
365 vrgiu_dump_io(struct vrgiu_softc
*sc
)
368 dbg_bit_display(vrgiu_regread_4(sc
, GIUPODAT_REG
));
369 dbg_bit_display(vrgiu_regread_4(sc
, GIUPIOD_REG
));
376 struct vrgiu_softc
*sc
= this_giu
;
377 static u_int32_t opreg
[2] = {0, 0};
380 preg
[0] = vrgiu_regread_4(sc
, GIUPIOD_REG
);
381 preg
[1] = vrgiu_regread_4(sc
, GIUPODAT_REG
);
383 if (opreg
[0] != preg
[0] || opreg
[1] != preg
[1]) {
384 printf("giu data: ");
385 dbg_bit_display(preg
[1]);
386 dbg_bit_display(preg
[0]);
394 vrgiu_dump_regs(struct vrgiu_softc
*sc
)
398 panic("%s(%d): VRGIU device not initialized",
401 printf(" IOSEL: %08x\n", vrgiu_regread_4(sc
, GIUIOSEL_REG
));
402 printf(" PIOD: %08x\n", vrgiu_regread_4(sc
, GIUPIOD_REG
));
403 printf(" PODAT: %08x\n", vrgiu_regread_4(sc
, GIUPODAT_REG
));
404 printf(" INTSTAT: %08x\n", vrgiu_regread_4(sc
, GIUINTSTAT_REG
));
405 printf(" INTEN: %08x\n", vrgiu_regread_4(sc
, GIUINTEN_REG
));
406 printf(" INTTYP: %08x\n", vrgiu_regread_4(sc
, GIUINTTYP_REG
));
407 printf(" INTALSEL: %08x\n", vrgiu_regread_4(sc
, GIUINTALSEL_REG
));
408 printf(" INTHTSEL: %08x\n", vrgiu_regread_4(sc
, GIUINTHTSEL_REG
));
411 * GIU regster access method.
414 vrgiu_regread_4(struct vrgiu_softc
*sc
, bus_addr_t offs
)
418 bus_space_read_region_2 (sc
->sc_iot
, sc
->sc_ioh
, offs
, reg
, 2);
420 return (reg
[0] | (reg
[1] << 16));
424 vrgiu_regread(struct vrgiu_softc
*sc
, bus_addr_t off
)
427 return (bus_space_read_2(sc
->sc_iot
, sc
->sc_ioh
, off
));
431 vrgiu_regwrite_4(struct vrgiu_softc
*sc
, bus_addr_t offs
, u_int32_t data
)
435 reg
[0] = data
& 0xffff;
436 reg
[1] = (data
>>16)&0xffff;
437 bus_space_write_region_2 (sc
->sc_iot
, sc
->sc_ioh
, offs
, reg
, 2);
441 vrgiu_regwrite(struct vrgiu_softc
*sc
, bus_addr_t off
, u_int16_t data
)
444 bus_space_write_2(sc
->sc_iot
, sc
->sc_ioh
, off
, data
);
451 vrgiu_port_read(hpcio_chip_t hc
, int port
)
453 struct vrgiu_softc
*sc
= hc
->hc_sc
;
456 if (!LEGAL_OUT_PORT(port
))
457 panic("vrgiu_port_read: illegal gpio port");
460 on
= (vrgiu_regread_4(sc
, GIUPIOD_REG
) & (1 << port
));
462 on
= (vrgiu_regread_4(sc
, GIUPODAT_REG
) & (1 << (port
- 32)));
468 vrgiu_port_write(hpcio_chip_t hc
, int port
, int onoff
)
470 struct vrgiu_softc
*sc
= hc
->hc_sc
;
474 if (!LEGAL_OUT_PORT(port
))
475 panic("vrgiu_port_write: illegal gpio port");
477 reg
[0] = vrgiu_regread_4(sc
, GIUPIOD_REG
);
478 reg
[1] = vrgiu_regread_4(sc
, GIUPODAT_REG
);
479 bank
= port
< 32 ? 0 : 1;
484 reg
[bank
] |= (1<<port
);
486 reg
[bank
] &= ~(1<<port
);
487 vrgiu_regwrite_4(sc
, GIUPIOD_REG
, reg
[0]);
488 vrgiu_regwrite_4(sc
, GIUPODAT_REG
, reg
[1]);
492 vrgiu_update(hpcio_chip_t hc
)
497 vrgiu_dump(hpcio_chip_t hc
)
502 vrgiu_getchip(void* scx
, int chipid
)
504 struct vrgiu_softc
*sc
= scx
;
506 return (&sc
->sc_iochip
);
513 vrgiu_intr_establish(
515 int port
, /* GPIO pin # */
516 int mode
, /* GIU trigger setting */
517 int (*ih_fun
)(void *),
520 struct vrgiu_softc
*sc
= hc
->hc_sc
;
523 struct vrgiu_intr_entry
*ih
;
525 if (!LEGAL_INTR_PORT(port
))
526 panic ("vrgiu_intr_establish: bogus interrupt line.");
527 if (sc
->sc_intr_mode
[port
] && mode
!= sc
->sc_intr_mode
[port
])
528 panic ("vrgiu_intr_establish: bogus interrupt type.");
530 sc
->sc_intr_mode
[port
] = mode
;
535 if (!(ih
= malloc(sizeof(struct vrgiu_intr_entry
), M_DEVBUF
, M_NOWAIT
)))
536 panic ("vrgiu_intr_establish: no memory.");
538 DPRINTF(DEBUG_INTR
, ("%s: port %d ", sc
->sc_dev
.dv_xname
, port
));
542 TAILQ_INSERT_TAIL(&sc
->sc_intr_head
[port
], ih
, ih_link
);
543 #ifdef WINCE_DEFAULT_SETTING
544 #warning WINCE_DEFAULT_SETTING
550 reg
= vrgiu_regread_4(sc
, GIUIOSEL_REG
);
552 vrgiu_regwrite_4(sc
, GIUIOSEL_REG
, reg
);
555 reg
= vrgiu_regread_4(sc
, GIUINTTYP_REG
);
556 DPRINTF(DEBUG_INTR
, ("[%s->",reg
& mask
? "edge" : "level"));
557 if (mode
& HPCIO_INTR_EDGE
) {
558 DPRINTF(DEBUG_INTR
, ("edge]"));
559 reg
|= mask
; /* edge */
561 DPRINTF(DEBUG_INTR
, ("level]"));
562 reg
&= ~mask
; /* level */
564 vrgiu_regwrite_4(sc
, GIUINTTYP_REG
, reg
);
566 /* interrupt level */
567 if (!(mode
& HPCIO_INTR_EDGE
)) {
568 reg
= vrgiu_regread_4(sc
, GIUINTALSEL_REG
);
569 DPRINTF(DEBUG_INTR
, ("[%s->",reg
& mask
? "high" : "low"));
570 if (mode
& HPCIO_INTR_HIGH
) {
571 DPRINTF(DEBUG_INTR
, ("high]"));
572 reg
|= mask
; /* high */
574 DPRINTF(DEBUG_INTR
, ("low]"));
575 reg
&= ~mask
; /* low */
577 vrgiu_regwrite_4(sc
, GIUINTALSEL_REG
, reg
);
579 /* hold or through */
580 reg
= vrgiu_regread_4(sc
, GIUINTHTSEL_REG
);
581 DPRINTF(DEBUG_INTR
, ("[%s->",reg
& mask
? "hold" : "through"));
582 if (mode
& HPCIO_INTR_HOLD
) {
583 DPRINTF(DEBUG_INTR
, ("hold]"));
584 reg
|= mask
; /* hold */
586 DPRINTF(DEBUG_INTR
, ("through]"));
587 reg
&= ~mask
; /* through */
589 vrgiu_regwrite_4(sc
, GIUINTHTSEL_REG
, reg
);
592 * clear interrupt status
594 reg
= vrgiu_regread_4(sc
, GIUINTSTAT_REG
);
596 vrgiu_regwrite_4(sc
, GIUINTSTAT_REG
, reg
);
600 #ifdef WINCE_DEFAULT_SETTING
601 #warning WINCE_DEFAULT_SETTING
603 sc
->sc_intr_mask
|= mask
;
604 vrgiu_regwrite_4(sc
, GIUINTEN_REG
, sc
->sc_intr_mask
);
605 /* Unmask GIU level 2 mask register */
606 vrip_intr_setmask2(sc
->sc_vc
, sc
->sc_ih
, (1<<port
), 1);
610 DPRINTF(DEBUG_INTR
, ("\n"));
616 vrgiu_intr_disestablish(hpcio_chip_t hc
, void *arg
)
618 struct vrgiu_intr_entry
*ihe
= arg
;
619 struct vrgiu_softc
*sc
= hc
->hc_sc
;
620 int port
= ihe
->ih_port
;
621 struct vrgiu_intr_entry
*ih
;
625 TAILQ_FOREACH(ih
, &sc
->sc_intr_head
[port
], ih_link
) {
627 TAILQ_REMOVE(&sc
->sc_intr_head
[port
], ih
, ih_link
);
629 if (TAILQ_EMPTY(&sc
->sc_intr_head
[port
])) {
630 /* Disable interrupt */
631 #ifdef WINCE_DEFAULT_SETTING
632 #warning WINCE_DEFAULT_SETTING
634 sc
->sc_intr_mask
&= ~(1<<port
);
635 vrgiu_regwrite_4(sc
, GIUINTEN_REG
, sc
->sc_intr_mask
);
642 panic("vrgiu_intr_disetablish: no such a handle.");
646 /* Clear interrupt */
648 vrgiu_intr_clear(hpcio_chip_t hc
, void *arg
)
650 struct vrgiu_softc
*sc
= hc
->hc_sc
;
651 struct vrgiu_intr_entry
*ihe
= arg
;
654 reg
= vrgiu_regread_4(sc
, GIUINTSTAT_REG
);
655 vrgiu_regwrite_4(sc
, GIUINTSTAT_REG
, reg
& ~(1 << ihe
->ih_port
));
659 vrgiu_register_iochip(hpcio_chip_t hc
, hpcio_chip_t iochip
)
661 struct vrgiu_softc
*sc
= hc
->hc_sc
;
663 vrip_register_gpio(sc
->sc_vc
, iochip
);
666 /* interrupt handler */
668 vrgiu_intr(void *arg
)
670 #ifdef DUMP_GIU_LEVEL2_INTR
671 #warning DUMP_GIU_LEVEL2_INTR
672 static u_int32_t oreg
;
674 struct vrgiu_softc
*sc
= arg
;
677 int ledvalue
= CONFIG_HOOK_LED_FLASH
;
679 /* Get Level 2 interrupt status */
680 vrip_intr_getstatus2 (sc
->sc_vc
, sc
->sc_ih
, ®
);
681 #ifdef DUMP_GIU_LEVEL2_INTR
682 #warning DUMP_GIU_LEVEL2_INTR
684 u_int32_t uedge
, dedge
, j
;
685 for (j
= 0x80000000; j
> 0; j
>>=1)
686 printf ("%c" , reg
&j
? '|' : '.');
687 uedge
= (reg
^ oreg
) & reg
;
688 dedge
= (reg
^ oreg
) & ~reg
;
689 if (uedge
|| dedge
) {
690 for (j
= 0; j
< 32; j
++) {
691 if (uedge
& (1 << j
))
693 else if (dedge
& (1 << j
))
701 /* Clear interrupt */
702 vrgiu_regwrite_4(sc
, GIUINTSTAT_REG
, vrgiu_regread_4(sc
, GIUINTSTAT_REG
));
704 /* Dispatch handler */
705 for (i
= 0; i
< MAX_GPIO_INOUT
; i
++) {
706 if (reg
& (1 << i
)) {
707 register struct vrgiu_intr_entry
*ih
;
708 TAILQ_FOREACH(ih
, &sc
->sc_intr_head
[i
], ih_link
) {
709 ih
->ih_fun(ih
->ih_arg
);
715 config_hook_call(CONFIG_HOOK_SET
, CONFIG_HOOK_LED
,