1/*-
2 * Copyright (c) 2015-2016 Landon Fuller <landon@freebsd.org>
3 * Copyright (c) 2007 Bruce M. Simpson.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD$");
30
31#include <sys/param.h>
32#include <sys/kernel.h>
33#include <sys/bus.h>
34#include <sys/module.h>
35
36#include <machine/bus.h>
37#include <sys/rman.h>
38#include <machine/resource.h>
39
40#include <dev/bhnd/bhnd_ids.h>
41#include <dev/bhnd/bhnd_nexusvar.h>
42#include <dev/bhnd/cores/chipc/chipcreg.h>
43
44#include "sibavar.h"
45
46/*
47 * Supports siba(4) attachment to a MIPS nexus bus.
48 *
49 * Derived from Bruce M. Simpson' original siba(4) driver.
50 */
51
52struct siba_nexus_softc {
53	struct siba_softc		parent_sc;
54	struct bhnd_chipid		siba_cid;
55};
56
57static int
58siba_nexus_probe(device_t dev)
59{
60	struct siba_nexus_softc	*sc;
61	int			 error;
62
63	sc = device_get_softc(dev);
64
65	/* Read the ChipCommon info using the hints the kernel
66	 * was compiled with. */
67	if ((error = bhnd_nexus_read_chipid(dev, &sc->siba_cid)))
68		return (error);
69
70	if (sc->siba_cid.chip_type != BHND_CHIPTYPE_SIBA)
71		return (ENXIO);
72
73	if ((error = siba_probe(dev)) > 0) {
74		device_printf(dev, "error %d in probe\n", error);
75		return (error);
76	}
77
78	return (0);
79}
80
81static int
82siba_nexus_attach(device_t dev)
83{
84	struct siba_nexus_softc	*sc;
85	int error;
86
87	sc = device_get_softc(dev);
88
89	/* Enumerate the bus. */
90	if ((error = siba_add_children(dev, NULL))) {
91		device_printf(dev, "error %d enumerating children\n", error);
92		return (error);
93	}
94
95	return (siba_attach(dev));
96}
97
98static const struct bhnd_chipid *
99siba_nexus_get_chipid(device_t dev, device_t child) {
100	struct siba_nexus_softc	*sc = device_get_softc(dev);
101	return (&sc->siba_cid);
102}
103
104static device_method_t siba_nexus_methods[] = {
105	/* Device interface */
106	DEVMETHOD(device_probe,			siba_nexus_probe),
107	DEVMETHOD(device_attach,		siba_nexus_attach),
108
109	/* bhnd interface */
110	DEVMETHOD(bhnd_bus_get_chipid,		siba_nexus_get_chipid),
111
112	DEVMETHOD_END
113};
114
115DEFINE_CLASS_2(bhnd, siba_nexus_driver, siba_nexus_methods,
116    sizeof(struct siba_nexus_softc), bhnd_nexus_driver, siba_driver);
117
118EARLY_DRIVER_MODULE(siba_nexus, nexus, siba_nexus_driver, bhnd_devclass, 0, 0,
119    BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
120