/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2015 Landon Fuller <[email protected]>4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer,11* without modification.12* 2. Redistributions in binary form must reproduce at minimum a disclaimer13* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any14* redistribution must be conditioned upon including a substantially15* similar Disclaimer requirement for further binary redistribution.16*17* NO WARRANTY18* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY21* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL22* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,23* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF24* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS25* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER26* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)27* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF28* THE POSSIBILITY OF SUCH DAMAGES.29*/3031#include <sys/param.h>32#include <sys/kernel.h>33#include <sys/bus.h>34#include <sys/module.h>3536#include <dev/bhnd/bhnd_ids.h>37#include <dev/bhnd/bhndb/bhndbvar.h>38#include <dev/bhnd/bhndb/bhndb_hwdata.h>3940#include "bcmavar.h"4142#include "bcma_eromreg.h"43#include "bcma_eromvar.h"4445/*46* Supports attachment of bcma(4) bus devices via a bhndb bridge.47*/4849static int50bcma_bhndb_probe(device_t dev)51{52const struct bhnd_chipid *cid;53int error;5455/* Defer to default probe implementation */56if ((error = bcma_probe(dev)) > 0)57return (error);5859/* Check bus type */60cid = BHNDB_GET_CHIPID(device_get_parent(dev), dev);61if (cid->chip_type != BHND_CHIPTYPE_BCMA)62return (ENXIO);6364/* Set device description */65bhnd_set_default_bus_desc(dev, cid);6667return (error);68}6970static int71bcma_bhndb_attach(device_t dev)72{73int error;7475/* Perform initial attach and enumerate our children. */76if ((error = bcma_attach(dev)))77goto failed;7879/* Delegate remainder to standard bhnd method implementation */80if ((error = bhnd_generic_attach(dev)))81goto failed;8283return (0);8485failed:86device_delete_children(dev);87return (error);88}8990static int91bcma_bhndb_suspend_child(device_t dev, device_t child)92{93struct bcma_devinfo *dinfo;94int error;9596if (device_get_parent(child) != dev)97BUS_SUSPEND_CHILD(device_get_parent(dev), child);9899if (device_is_suspended(child))100return (EBUSY);101102dinfo = device_get_ivars(child);103104/* Suspend the child */105if ((error = bhnd_generic_br_suspend_child(dev, child)))106return (error);107108/* Suspend child's agent resource */109if (dinfo->res_agent != NULL)110BHNDB_SUSPEND_RESOURCE(device_get_parent(dev), dev,111SYS_RES_MEMORY, dinfo->res_agent->res);112113return (0);114}115116static int117bcma_bhndb_resume_child(device_t dev, device_t child)118{119struct bcma_devinfo *dinfo;120int error;121122if (device_get_parent(child) != dev)123BUS_SUSPEND_CHILD(device_get_parent(dev), child);124125if (!device_is_suspended(child))126return (EBUSY);127128dinfo = device_get_ivars(child);129130/* Resume child's agent resource */131if (dinfo->res_agent != NULL) {132error = BHNDB_RESUME_RESOURCE(device_get_parent(dev), dev,133SYS_RES_MEMORY, dinfo->res_agent->res);134if (error)135return (error);136}137138/* Resume the child */139if ((error = bhnd_generic_br_resume_child(dev, child))) {140/* On failure, re-suspend the agent resource */141if (dinfo->res_agent != NULL) {142BHNDB_SUSPEND_RESOURCE(device_get_parent(dev), dev,143SYS_RES_MEMORY, dinfo->res_agent->res);144}145146return (error);147}148149return (0);150}151152static device_method_t bcma_bhndb_methods[] = {153/* Device interface */154DEVMETHOD(device_probe, bcma_bhndb_probe),155DEVMETHOD(device_attach, bcma_bhndb_attach),156157/* Bus interface */158DEVMETHOD(bus_suspend_child, bcma_bhndb_suspend_child),159DEVMETHOD(bus_resume_child, bcma_bhndb_resume_child),160161DEVMETHOD_END162};163164DEFINE_CLASS_2(bhnd, bcma_bhndb_driver, bcma_bhndb_methods,165sizeof(struct bcma_softc), bhnd_bhndb_driver, bcma_driver);166167DRIVER_MODULE(bcma_bhndb, bhndb, bcma_bhndb_driver, NULL, NULL);168169MODULE_VERSION(bcma_bhndb, 1);170MODULE_DEPEND(bcma_bhndb, bcma, 1, 1, 1);171MODULE_DEPEND(bcma_bhndb, bhnd, 1, 1, 1);172MODULE_DEPEND(bcma_bhndb, bhndb, 1, 1, 1);173174175