From 1c8edc1ed8e08ef4a6687f547c6696adaa81b8b8 Mon Sep 17 00:00:00 2001 From: "Landon J. Fuller" Date: Fri, 19 Jan 2018 21:58:48 +0000 Subject: [PATCH] bhnd(4): fix a few bugs in pwrctl/fixed-clock device support. - Do not panic on siba(4) detach when the bhnd(4) bus calls bhnd_get_pmu_info() on a PMU-less device. - Fix bhnd_pwrctl attach/detach on fixed-clock devices: - Treat bhnd_pwrctl_updateclk() as a no-op on fixed-clock devices. - Use bhnd_pwrctl_updateclk() to perform the appropriate clock transition on detach. Sponsored by: The FreeBSD Foundation --- sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl.c | 12 ++++++++---- sys/dev/bhnd/siba/siba.c | 6 +++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl.c b/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl.c index 006f31452db6..1858357dab5e 100644 --- a/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl.c +++ b/sys/dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl.c @@ -209,12 +209,12 @@ bhnd_pwrctl_detach(device_t dev) if ((error = bhnd_deregister_provider(dev, BHND_SERVICE_ANY))) return (error); + /* Update clock state */ PWRCTL_LOCK(sc); - - if ((error = bhnd_pwrctl_setclk(sc, BHND_CLOCK_DYN))) - return (error); - + error = bhnd_pwrctl_updateclk(sc, BHND_PWRCTL_WAR_DOWN); PWRCTL_UNLOCK(sc); + if (error) + return (error); STAILQ_FOREACH_SAFE(clkres, &sc->clkres_list, cr_link, crnext) free(clkres, M_DEVBUF); @@ -344,6 +344,10 @@ bhnd_pwrctl_updateclk(struct bhnd_pwrctl_softc *sc, bhnd_pwrctl_wars wars) PWRCTL_LOCK_ASSERT(sc, MA_OWNED); + /* Nothing to update on fixed clock devices */ + if (PWRCTL_QUIRK(sc, FIXED_CLK)) + return (0); + /* Default clock target */ clock = BHND_CLOCK_DYN; diff --git a/sys/dev/bhnd/siba/siba.c b/sys/dev/bhnd/siba/siba.c index 1f6e4cecddc1..984399f00abd 100644 --- a/sys/dev/bhnd/siba/siba.c +++ b/sys/dev/bhnd/siba/siba.c @@ -170,9 +170,9 @@ siba_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) case SIBA_PMU_PWRCTL: case SIBA_PMU_FIXED: - panic("bhnd_get_pmu_info() called with siba PMU state " - "%d", dinfo->pmu_state); - return (ENXIO); + *result = (uintptr_t)NULL; + SIBA_UNLOCK(sc); + return (0); } panic("invalid PMU state: %d", dinfo->pmu_state);