obio.c revision 202035
1204076Spjd/*	$NetBSD: obio.c,v 1.11 2003/07/15 00:25:05 lukem Exp $	*/
2204076Spjd
3204076Spjd/*-
4204076Spjd * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
5204076Spjd * All rights reserved.
6204076Spjd *
7204076Spjd * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8204076Spjd *
9204076Spjd * Redistribution and use in source and binary forms, with or without
10204076Spjd * modification, are permitted provided that the following conditions
11204076Spjd * are met:
12204076Spjd * 1. Redistributions of source code must retain the above copyright
13204076Spjd *    notice, this list of conditions and the following disclaimer.
14204076Spjd * 2. Redistributions in binary form must reproduce the above copyright
15204076Spjd *    notice, this list of conditions and the following disclaimer in the
16204076Spjd *    documentation and/or other materials provided with the distribution.
17204076Spjd * 3. All advertising materials mentioning features or use of this software
18204076Spjd *    must display the following acknowledgement:
19204076Spjd *	This product includes software developed for the NetBSD Project by
20204076Spjd *	Wasabi Systems, Inc.
21204076Spjd * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22204076Spjd *    or promote products derived from this software without specific prior
23204076Spjd *    written permission.
24204076Spjd *
25204076Spjd * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26204076Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27204076Spjd * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28204076Spjd * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29204076Spjd * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30204076Spjd * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31204076Spjd * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32204076Spjd * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33204076Spjd * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34204076Spjd * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35204076Spjd * POSSIBILITY OF SUCH DAMAGE.
36204076Spjd */
37204076Spjd
38204076Spjd/*
39204076Spjd * On-board device autoconfiguration support for Intel IQ80321
40204076Spjd * evaluation boards.
41204076Spjd */
42204076Spjd
43219620Strociny#include <sys/cdefs.h>
44204076Spjd__FBSDID("$FreeBSD: head/sys/mips/malta/obio.c 202035 2010-01-10 20:06:14Z imp $");
45204076Spjd
46204076Spjd#include <sys/param.h>
47204076Spjd#include <sys/systm.h>
48204076Spjd#include <sys/bus.h>
49204076Spjd#include <sys/kernel.h>
50204076Spjd#include <sys/module.h>
51204076Spjd#include <sys/rman.h>
52204076Spjd#include <sys/malloc.h>
53204076Spjd
54204076Spjd#include <machine/bus.h>
55204076Spjd
56204076Spjd#include <mips/malta/maltareg.h>
57204076Spjd#include <mips/malta/obiovar.h>
58204076Spjd
59204076Spjdint	obio_probe(device_t);
60204076Spjdint	obio_attach(device_t);
61204076Spjd
62204076Spjd/*
63204076Spjd * A bit tricky and hackish. Since we need OBIO to rely
64204076Spjd * on PCI we make it pseudo-pci device. But there should
65204076Spjd * be only one such device, so we use this static flag
66204076Spjd * to prevent false positives on every real PCI device probe.
67204076Spjd */
68204076Spjdstatic int have_one = 0;
69204076Spjd
70204076Spjdint
71204076Spjdobio_probe(device_t dev)
72204076Spjd{
73204076Spjd	if (!have_one) {
74204076Spjd		have_one = 1;
75204076Spjd		return 0;
76204076Spjd	}
77204076Spjd	return (ENXIO);
78204076Spjd}
79204076Spjd
80204076Spjdint
81204076Spjdobio_attach(device_t dev)
82204076Spjd{
83204076Spjd	struct obio_softc *sc = device_get_softc(dev);
84204076Spjd
85204076Spjd	sc->oba_st = mips_bus_space_generic;
86204076Spjd	sc->oba_addr = MIPS_PHYS_TO_KSEG1(MALTA_UART0ADR);
87204076Spjd	sc->oba_size = MALTA_PCIMEM3_SIZE;
88204076Spjd	sc->oba_rman.rm_type = RMAN_ARRAY;
89204076Spjd	sc->oba_rman.rm_descr = "OBIO I/O";
90204076Spjd	if (rman_init(&sc->oba_rman) != 0 ||
91204076Spjd	    rman_manage_region(&sc->oba_rman,
92204076Spjd	    sc->oba_addr, sc->oba_addr + sc->oba_size) != 0)
93204076Spjd		panic("obio_attach: failed to set up I/O rman");
94204076Spjd	sc->oba_irq_rman.rm_type = RMAN_ARRAY;
95204076Spjd	sc->oba_irq_rman.rm_descr = "OBIO IRQ";
96204076Spjd
97204076Spjd	/*
98204076Spjd	 * This module is intended for UART purposes only and
99204076Spjd	 * it's IRQ is 4
100204076Spjd	 */
101204076Spjd	if (rman_init(&sc->oba_irq_rman) != 0 ||
102204076Spjd	    rman_manage_region(&sc->oba_irq_rman, 4, 4) != 0)
103204076Spjd		panic("obio_attach: failed to set up IRQ rman");
104204076Spjd
105204076Spjd	device_add_child(dev, "uart", 0);
106204076Spjd	bus_generic_probe(dev);
107204076Spjd	bus_generic_attach(dev);
108204076Spjd
109204076Spjd	return (0);
110204076Spjd}
111204076Spjd
112204076Spjdstatic struct resource *
113204076Spjdobio_alloc_resource(device_t bus, device_t child, int type, int *rid,
114204076Spjd    u_long start, u_long end, u_long count, u_int flags)
115204076Spjd{
116204076Spjd	struct resource *rv;
117204076Spjd	struct rman *rm;
118204076Spjd	bus_space_tag_t bt = 0;
119204076Spjd	bus_space_handle_t bh = 0;
120204076Spjd	struct obio_softc *sc = device_get_softc(bus);
121204076Spjd
122204076Spjd	switch (type) {
123204076Spjd	case SYS_RES_IRQ:
124204076Spjd		rm = &sc->oba_irq_rman;
125204076Spjd		break;
126204076Spjd	case SYS_RES_MEMORY:
127204076Spjd		return (NULL);
128204076Spjd	case SYS_RES_IOPORT:
129204076Spjd		rm = &sc->oba_rman;
130204076Spjd		bt = sc->oba_st;
131204076Spjd		bh = sc->oba_addr;
132204076Spjd		start = bh;
133204076Spjd		break;
134204076Spjd	default:
135204076Spjd		return (NULL);
136204076Spjd	}
137204076Spjd
138204076Spjd
139204076Spjd	rv = rman_reserve_resource(rm, start, end, count, flags, child);
140204076Spjd	if (rv == NULL)
141204076Spjd		return (NULL);
142204076Spjd	if (type == SYS_RES_IRQ)
143204076Spjd		return (rv);
144204076Spjd	rman_set_rid(rv, *rid);
145204076Spjd	rman_set_bustag(rv, bt);
146204076Spjd	rman_set_bushandle(rv, bh);
147204076Spjd
148204076Spjd	if (0) {
149204076Spjd		if (bus_activate_resource(child, type, *rid, rv)) {
150204076Spjd			rman_release_resource(rv);
151204076Spjd			return (NULL);
152204076Spjd		}
153204076Spjd	}
154204076Spjd	return (rv);
155204076Spjd
156204076Spjd}
157204076Spjd
158204076Spjdstatic int
159204076Spjdobio_activate_resource(device_t bus, device_t child, int type, int rid,
160204076Spjd    struct resource *r)
161204076Spjd{
162204076Spjd	return (0);
163204076Spjd}
164204076Spjdstatic device_method_t obio_methods[] = {
165204076Spjd	DEVMETHOD(device_probe, obio_probe),
166204076Spjd	DEVMETHOD(device_attach, obio_attach),
167204076Spjd
168204076Spjd	DEVMETHOD(bus_alloc_resource, obio_alloc_resource),
169204076Spjd	DEVMETHOD(bus_activate_resource, obio_activate_resource),
170204076Spjd	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
171204076Spjd	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
172204076Spjd
173204076Spjd	{0, 0},
174204076Spjd};
175204076Spjd
176204076Spjdstatic driver_t obio_driver = {
177204076Spjd	"obio",
178204076Spjd	obio_methods,
179204076Spjd	sizeof(struct obio_softc),
180204076Spjd};
181204076Spjdstatic devclass_t obio_devclass;
182204076Spjd
183204076SpjdDRIVER_MODULE(obio, pci, obio_driver, obio_devclass, 0, 0);
184204076Spjd