1296077Sadrian/*-
2301410Slandonf * Copyright (c) 2015-2016 Landon Fuller <landon@freebsd.org>
3296077Sadrian * Copyright (c) 2007 Bruce M. Simpson.
4296077Sadrian * All rights reserved.
5296077Sadrian *
6296077Sadrian * Redistribution and use in source and binary forms, with or without
7296077Sadrian * modification, are permitted provided that the following conditions
8296077Sadrian * are met:
9296077Sadrian * 1. Redistributions of source code must retain the above copyright
10296077Sadrian *    notice, this list of conditions and the following disclaimer.
11296077Sadrian * 2. Redistributions in binary form must reproduce the above copyright
12296077Sadrian *    notice, this list of conditions and the following disclaimer in the
13296077Sadrian *    documentation and/or other materials provided with the distribution.
14296077Sadrian *
15296077Sadrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16296077Sadrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17296077Sadrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18296077Sadrian * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19296077Sadrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20296077Sadrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21296077Sadrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22296077Sadrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23296077Sadrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24296077Sadrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25296077Sadrian * SUCH DAMAGE.
26296077Sadrian */
27296077Sadrian
28296077Sadrian#include <sys/cdefs.h>
29296077Sadrian__FBSDID("$FreeBSD$");
30296077Sadrian
31296077Sadrian#include <sys/param.h>
32301410Slandonf#include <sys/kernel.h>
33296077Sadrian#include <sys/bus.h>
34296077Sadrian#include <sys/module.h>
35296077Sadrian
36296077Sadrian#include <machine/bus.h>
37301410Slandonf#include <sys/rman.h>
38301410Slandonf#include <machine/resource.h>
39296077Sadrian
40296077Sadrian#include <dev/bhnd/bhnd_ids.h>
41301410Slandonf#include <dev/bhnd/bhnd_nexusvar.h>
42301410Slandonf#include <dev/bhnd/cores/chipc/chipcreg.h>
43296077Sadrian
44296077Sadrian#include "sibavar.h"
45296077Sadrian
46296077Sadrian/*
47296077Sadrian * Supports siba(4) attachment to a MIPS nexus bus.
48296077Sadrian *
49301410Slandonf * Derived from Bruce M. Simpson' original siba(4) driver.
50296077Sadrian */
51296077Sadrian
52296077Sadrianstruct siba_nexus_softc {
53296077Sadrian	struct siba_softc		parent_sc;
54296077Sadrian	struct bhnd_chipid		siba_cid;
55296077Sadrian};
56296077Sadrian
57296077Sadrianstatic int
58296077Sadriansiba_nexus_probe(device_t dev)
59296077Sadrian{
60301410Slandonf	struct siba_nexus_softc	*sc;
61301410Slandonf	int			 error;
62296077Sadrian
63301410Slandonf	sc = device_get_softc(dev);
64296077Sadrian
65301410Slandonf	/* Read the ChipCommon info using the hints the kernel
66301410Slandonf	 * was compiled with. */
67301410Slandonf	if ((error = bhnd_nexus_read_chipid(dev, &sc->siba_cid)))
68301410Slandonf		return (error);
69296077Sadrian
70301410Slandonf	if (sc->siba_cid.chip_type != BHND_CHIPTYPE_SIBA)
71296077Sadrian		return (ENXIO);
72296077Sadrian
73301410Slandonf	if ((error = siba_probe(dev)) > 0) {
74301410Slandonf		device_printf(dev, "error %d in probe\n", error);
75301410Slandonf		return (error);
76296077Sadrian	}
77296077Sadrian
78296077Sadrian	return (0);
79296077Sadrian}
80296077Sadrian
81296077Sadrianstatic int
82296077Sadriansiba_nexus_attach(device_t dev)
83296077Sadrian{
84301410Slandonf	struct siba_nexus_softc	*sc;
85301410Slandonf	int error;
86296077Sadrian
87301410Slandonf	sc = device_get_softc(dev);
88296077Sadrian
89296077Sadrian	/* Enumerate the bus. */
90301410Slandonf	if ((error = siba_add_children(dev, NULL))) {
91301410Slandonf		device_printf(dev, "error %d enumerating children\n", error);
92296077Sadrian		return (error);
93296077Sadrian	}
94296077Sadrian
95296077Sadrian	return (siba_attach(dev));
96296077Sadrian}
97296077Sadrian
98296077Sadrianstatic const struct bhnd_chipid *
99296077Sadriansiba_nexus_get_chipid(device_t dev, device_t child) {
100296077Sadrian	struct siba_nexus_softc	*sc = device_get_softc(dev);
101296077Sadrian	return (&sc->siba_cid);
102296077Sadrian}
103296077Sadrian
104296077Sadrianstatic device_method_t siba_nexus_methods[] = {
105296077Sadrian	/* Device interface */
106301410Slandonf	DEVMETHOD(device_probe,			siba_nexus_probe),
107301410Slandonf	DEVMETHOD(device_attach,		siba_nexus_attach),
108296077Sadrian
109296077Sadrian	/* bhnd interface */
110301410Slandonf	DEVMETHOD(bhnd_bus_get_chipid,		siba_nexus_get_chipid),
111296077Sadrian
112296077Sadrian	DEVMETHOD_END
113296077Sadrian};
114296077Sadrian
115301410SlandonfDEFINE_CLASS_2(bhnd, siba_nexus_driver, siba_nexus_methods,
116301410Slandonf    sizeof(struct siba_nexus_softc), bhnd_nexus_driver, siba_driver);
117296077Sadrian
118301698SlandonfEARLY_DRIVER_MODULE(siba_nexus, nexus, siba_nexus_driver, bhnd_devclass, 0, 0,
119301698Slandonf    BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
120