cy_isa.c revision 129879
1/*-
2 * cyclades cyclom-y serial driver
3 *	Andrew Herbert <andrew@werple.apana.org.au>, 17 August 1993
4 *
5 * Copyright (c) 1993 Andrew Herbert.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. The name Andrew Herbert may not be used to endorse or promote products
17 *    derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
22 * NO EVENT SHALL I BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/*
32 * Cyclades Y ISA serial interface driver
33 */
34
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD: head/sys/dev/cy/cy_isa.c 129879 2004-05-30 20:08:47Z phk $");
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/bus.h>
41#include <sys/kernel.h>
42#include <sys/module.h>
43
44#include <machine/bus.h>
45#include <sys/rman.h>
46#include <machine/resource.h>
47
48#include <isa/isavar.h>
49
50#include <dev/cy/cyreg.h>
51#include <dev/cy/cyvar.h>
52
53static int	cy_isa_attach(device_t dev);
54static int	cy_isa_probe(device_t dev);
55
56static device_method_t cy_isa_methods[] = {
57	/* Device interface. */
58	DEVMETHOD(device_probe,		cy_isa_probe),
59	DEVMETHOD(device_attach,	cy_isa_attach),
60
61	{ 0, 0 }
62};
63
64static driver_t cy_isa_driver = {
65	cy_driver_name,
66	cy_isa_methods,
67	0,
68};
69
70DRIVER_MODULE(cy, isa, cy_isa_driver, cy_devclass, 0, 0);
71
72static int
73cy_isa_probe(device_t dev)
74{
75	struct resource *mem_res;
76	cy_addr iobase;
77	int mem_rid;
78
79	if (isa_get_logicalid(dev) != 0)	/* skip PnP probes */
80		return (ENXIO);
81
82	mem_rid = 0;
83	mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &mem_rid,
84	    0ul, ~0ul, 0ul, RF_ACTIVE);
85	if (mem_res == NULL) {
86		device_printf(dev, "ioport resource allocation failed\n");
87		return (ENXIO);
88	}
89	iobase = rman_get_virtual(mem_res);
90
91	/* Cyclom-16Y hardware reset (Cyclom-8Ys don't care) */
92	cy_inb(iobase, CY16_RESET, 0);	/* XXX? */
93	DELAY(500);		/* wait for the board to get its act together */
94
95	/* this is needed to get the board out of reset */
96	cy_outb(iobase, CY_CLEAR_INTR, 0, 0);
97	DELAY(500);
98
99	bus_release_resource(dev, SYS_RES_MEMORY, mem_rid, mem_res);
100	return (cy_units(iobase, 0) == 0 ? ENXIO : 0);
101}
102
103static int
104cy_isa_attach(device_t dev)
105{
106	struct resource *irq_res, *mem_res;
107	void *irq_cookie, *vaddr, *vsc;
108	int irq_rid, mem_rid;
109
110	irq_res = NULL;
111	mem_res = NULL;
112
113	mem_rid = 0;
114	mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &mem_rid,
115	    0ul, ~0ul, 0ul, RF_ACTIVE);
116	if (mem_res == NULL) {
117		device_printf(dev, "memory resource allocation failed\n");
118		goto fail;
119	}
120	vaddr = rman_get_virtual(mem_res);
121
122	vsc = cyattach_common(vaddr, 0);
123	if (vsc == NULL) {
124		device_printf(dev, "no ports found!\n");
125		goto fail;
126	}
127
128	irq_rid = 0;
129	irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &irq_rid, 0ul, ~0ul, 0ul,
130	    RF_SHAREABLE | RF_ACTIVE);
131	if (irq_res == NULL) {
132		device_printf(dev, "interrupt resource allocation failed\n");
133		goto fail;
134	}
135	if (bus_setup_intr(dev, irq_res, INTR_TYPE_TTY | INTR_FAST, cyintr,
136	    vsc, &irq_cookie) != 0) {
137		device_printf(dev, "interrupt setup failed\n");
138		goto fail;
139	}
140
141	return (0);
142
143fail:
144	if (irq_res != NULL)
145		bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res);
146	if (mem_res != NULL)
147		bus_release_resource(dev, SYS_RES_MEMORY, mem_rid, mem_res);
148	return (ENXIO);
149}
150