1 /* $NetBSD: vrecu.c,v 1.8 2009/09/14 12:49:33 tsutsui Exp $ */
4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Naoto Shimazaki of YOKOGAWA Electric Corporation.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: vrecu.c,v 1.8 2009/09/14 12:49:33 tsutsui Exp $");
35 #include <sys/param.h>
36 #include <sys/device.h>
37 #include <sys/malloc.h>
38 #include <sys/queue.h>
39 #include <sys/systm.h>
41 #include <machine/bus.h>
42 #include <machine/intr.h>
44 #include <hpcmips/vr/vrcpudef.h>
45 #include <hpcmips/vr/vripif.h>
46 #include <hpcmips/vr/vr4181ecureg.h>
48 #include <dev/isa/isareg.h>
49 #include <dev/isa/isavar.h>
50 #include <dev/pcmcia/pcmciareg.h>
51 #include <dev/pcmcia/pcmciavar.h>
52 #include <dev/pcmcia/pcmciachip.h>
54 #include <dev/ic/i82365reg.h>
55 #include <dev/ic/i82365var.h>
56 #include <dev/isa/i82365_isavar.h>
58 static int pcic_vrip_match(struct device
*, struct cfdata
*, void *);
59 static void pcic_vrip_attach(struct device
*, struct device
*, void *);
60 static void *pcic_vrip_chip_intr_establish(pcmcia_chipset_handle_t
,
61 struct pcmcia_function
*, int,
62 int (*)(void *), void *);
63 static void pcic_vrip_chip_intr_disestablish(pcmcia_chipset_handle_t
, void *);
64 static int pcic_vrip_intr(void *);
66 struct pcic_vrip_softc
{
67 struct pcic_softc sc_pcic
; /* real pcic softc */
68 uint16_t sc_intr_mask
;
69 uint16_t sc_intr_valid
;
71 int (*ih_fun
)(void *);
73 } sc_intrhand
[ECU_MAX_INTR
];
76 CFATTACH_DECL(pcic_vrip
, sizeof(struct pcic_vrip_softc
),
77 pcic_vrip_match
, pcic_vrip_attach
, NULL
, NULL
);
79 static struct pcmcia_chip_functions pcic_vrip_functions
= {
80 .mem_alloc
= pcic_chip_mem_alloc
,
81 .mem_free
= pcic_chip_mem_free
,
82 .mem_map
= pcic_chip_mem_map
,
83 .mem_unmap
= pcic_chip_mem_unmap
,
85 .io_alloc
= pcic_chip_io_alloc
,
86 .io_free
= pcic_chip_io_free
,
87 .io_map
= pcic_chip_io_map
,
88 .io_unmap
= pcic_chip_io_unmap
,
90 .intr_establish
= pcic_vrip_chip_intr_establish
,
91 .intr_disestablish
= pcic_vrip_chip_intr_disestablish
,
93 .socket_enable
= pcic_chip_socket_enable
,
94 .socket_disable
= pcic_chip_socket_disable
,
95 .socket_settype
= pcic_chip_socket_settype
,
100 pcic_vrip_match(struct device
*parent
, struct cfdata
*match
, void *aux
)
106 pcic_vrip_attach(struct device
*parent
, struct device
*self
, void *aux
)
108 struct pcic_vrip_softc
*vsc
= device_private(self
);
109 struct pcic_softc
*sc
= &vsc
->sc_pcic
;
110 struct vrip_attach_args
*va
= aux
;
111 bus_space_handle_t ioh
;
112 bus_space_handle_t memh
;
115 vsc
->sc_intr_valid
= PCIC_INTR_IRQ_VALIDMASK
;
116 vsc
->sc_intr_mask
= 0xffff;
117 for (i
= 0; i
< ECU_MAX_INTR
; i
++)
118 vsc
->sc_intrhand
[i
].ih_fun
= NULL
;
120 if ((sc
->ih
= vrip_intr_establish(va
->va_vc
, va
->va_unit
, 0,
121 IPL_NET
, pcic_vrip_intr
, vsc
))
123 printf(": can't establish interrupt");
127 if (bus_space_map(va
->va_iot
, va
->va_addr
, ECU_SIZE
, 0, &ioh
)) {
128 printf(": can't map pcic register space\n");
133 bus_space_write_2(va
->va_iot
, ioh
, ECU_CFG_REG_1_W
, 0x0001);
135 /* mask all interrupt */
136 bus_space_write_2(va
->va_iot
, ioh
, ECU_INTMSK_REG_W
,
141 if (bus_space_map(va
->va_iot
, VR_ISA_MEM_BASE
, 0x4000, 0, &memh
))
142 panic("pcic_pci_attach: can't map mem space");
144 sc
->membase
= VR_ISA_MEM_BASE
;
145 sc
->subregionmask
= (1 << (0x4000 / PCIC_MEM_PAGESIZE
)) - 1;
147 sc
->iobase
= VR_ISA_PORT_BASE
+ 0x400;
150 if (bus_space_map(va
->va_iot
, VR_ISA_MEM_BASE
, 0x70000, 0, &memh
))
151 panic("pcic_pci_attach: can't map mem space");
153 sc
->membase
= VR_ISA_MEM_BASE
;
154 sc
->subregionmask
= (1 << (0x70000 / PCIC_MEM_PAGESIZE
)) - 1;
156 sc
->iobase
= VR_ISA_PORT_BASE
;
157 sc
->iosize
= 0x10000;
160 sc
->pct
= &pcic_vrip_functions
;
162 sc
->iot
= va
->va_iot
;
164 sc
->memt
= va
->va_iot
;
172 pcic_attach_sockets(sc
);
173 pcic_attach_sockets_finish(sc
);
177 pcic_vrip_chip_intr_establish(pcmcia_chipset_handle_t pch
,
178 struct pcmcia_function
*pf
,
180 int (*ih_fun
)(void *),
183 struct pcic_handle
*h
;
184 struct pcic_softc
*sc
;
185 struct pcic_vrip_softc
*vsc
;
193 * XXXXXXXXXXXXXXXXXXXXXXXXXXXX
194 * XXXXXXXXXXXXXXXXXXXXXXXXXXXX
195 * XXXXXXXXXXXXXXXXXXXXXXXXXXXX
199 * XXXXXXXXXXXXXXXXXXXXXXXXXXXX
200 * XXXXXXXXXXXXXXXXXXXXXXXXXXXX
201 * XXXXXXXXXXXXXXXXXXXXXXXXXXXX
205 h
= (struct pcic_handle
*) pch
;
206 vsc
= device_private(h
->ph_parent
);
210 ih
= &vsc
->sc_intrhand
[irq
];
211 if (ih
->ih_fun
) /* cannot share ecu interrupt */
217 if (h
->flags
& PCIC_FLAG_ENABLED
) {
218 r
= pcic_read(h
, PCIC_INTR
);
219 r
&= ~PCIC_INTR_IRQ_MASK
;
220 pcic_write(h
, PCIC_INTR
, r
| irq
);
223 vsc
->sc_intr_mask
&= ~(1 << irq
);
224 bus_space_write_2(sc
->iot
, sc
->ioh
, ECU_INTMSK_REG_W
,
231 pcic_vrip_chip_intr_disestablish(pcmcia_chipset_handle_t pch
, void *arg
)
233 struct pcic_handle
*h
;
234 struct pcic_softc
*sc
;
235 struct pcic_vrip_softc
*vsc
;
236 struct intrhand
*ih
= arg
;
241 h
= (struct pcic_handle
*) pch
;
242 vsc
= device_private(h
->ph_parent
);
245 if (ih
!= &vsc
->sc_intrhand
[h
->ih_irq
])
246 panic("pcic_vrip_chip_intr_disestablish: bad handler");
250 vsc
->sc_intr_mask
|= 1 << h
->ih_irq
;
251 bus_space_write_2(sc
->iot
, sc
->ioh
, ECU_INTMSK_REG_W
,
255 if (h
->flags
& PCIC_FLAG_ENABLED
) {
256 r
= pcic_read(h
, PCIC_INTR
);
257 r
&= ~(PCIC_INTR_IRQ_MASK
| PCIC_INTR_ENABLE
);
258 pcic_write(h
, PCIC_INTR
, r
);
271 pcic_vrip_intr(void *arg
)
273 struct pcic_vrip_softc
*vsc
= arg
;
274 struct pcic_softc
*sc
= &vsc
->sc_pcic
;
278 r
= bus_space_read_2(sc
->iot
, sc
->ioh
, ECU_INTSTAT_REG_W
)
279 & ~vsc
->sc_intr_mask
;
281 for (i
= 0; i
< ECU_MAX_INTR
; i
++) {
282 struct intrhand
*ih
= &vsc
->sc_intrhand
[i
];
283 if (ih
->ih_fun
&& (r
& (1 << i
)))
284 ih
->ih_fun(ih
->ih_arg
);