#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/bus.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/systm.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <dev/bhnd/bhnd.h>
#include "bhnd_pmureg.h"
#include "bhnd_pmuvar.h"
static const struct bhnd_device bhnd_pmucore_devices[] = {
BHND_DEVICE(BCM, PMU, NULL, NULL),
BHND_DEVICE_END
};
static int
bhnd_pmu_core_probe(device_t dev)
{
const struct bhnd_device *id;
int error;
id = bhnd_device_lookup(dev, bhnd_pmucore_devices,
sizeof(bhnd_pmucore_devices[0]));
if (id == NULL)
return (ENXIO);
if ((error = bhnd_pmu_probe(dev)) > 0)
return (error);
bhnd_set_default_core_desc(dev);
return (BUS_PROBE_DEFAULT);
}
static int
bhnd_pmu_core_attach(device_t dev)
{
struct bhnd_pmu_softc *sc;
struct bhnd_resource *res;
int error;
sc = device_get_softc(dev);
res = bhnd_alloc_resource_any(dev, SYS_RES_MEMORY, 0, RF_ACTIVE);
if (res == NULL) {
device_printf(dev, "failed to allocate resources\n");
return (ENXIO);
}
if ((error = bhnd_alloc_pmu(dev))) {
device_printf(sc->dev, "failed to allocate PMU state: %d\n",
error);
return (error);
}
if ((error = bhnd_pmu_attach(dev, res))) {
bhnd_release_resource(dev, res);
return (error);
}
return (0);
}
static int
bhnd_pmu_core_detach(device_t dev)
{
struct bhnd_pmu_softc *sc;
int error;
sc = device_get_softc(dev);
if ((error = bhnd_pmu_detach(dev)))
return (error);
bhnd_release_resource(dev, sc->res);
return (0);
}
static device_method_t bhnd_pmucore_methods[] = {
DEVMETHOD(device_probe, bhnd_pmu_core_probe),
DEVMETHOD(device_attach, bhnd_pmu_core_attach),
DEVMETHOD(device_detach, bhnd_pmu_core_detach),
DEVMETHOD_END
};
DEFINE_CLASS_1(bhnd_pmu, bhnd_pmucore_driver, bhnd_pmucore_methods,
sizeof(struct bhnd_pmu_softc), bhnd_pmu_driver);
EARLY_DRIVER_MODULE(bhnd_pmu, bhnd, bhnd_pmucore_driver, NULL, NULL,
BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
MODULE_DEPEND(bhnd_pmu_core, bhnd_pmu, 1, 1, 1);
MODULE_VERSION(bhnd_pmu_core, 1);