From 1be17a16532e46997665083897fc226ff99eed08 Mon Sep 17 00:00:00 2001 From: ian Date: Sat, 15 Jun 2019 22:25:39 +0000 Subject: [PATCH] Restructure the pwm device hirearchy and interfaces. The pwm and pwmbus interfaces were nearly identical, this merges them into a single pwmbus interface. The pwmbus driver now implements the pwmbus interface by simply passing all calls through to its parent (the hardware driver). The channel_count method moves from pwm to pwmbus, and the get_bus method is deleted (just no longer needed). The net effect is that the interface for doing pwm stuff is now the same regardless of whether you're a child of pwmbus, or some random driver elsewhere in the hierarchy that is bypassing the pwmbus layer and is talking directly to the hardware driver via cross-hierarchy connections established using fdt data. The pwmc driver is now a child of pwmbus, instead of being its sibling (that's why the get_bus method is no longer needed; pwmc now gets the device_t of the bus using device_get_parent()). --- sys/arm/allwinner/aw_pwm.c | 24 +++------ sys/conf/files | 1 - sys/dev/pwm/ofw_pwm.c | 8 +-- sys/dev/pwm/pwm_if.m | 106 ------------------------------------- sys/dev/pwm/pwmbus.c | 105 +++++++++++++----------------------- sys/dev/pwm/pwmbus.h | 1 - sys/dev/pwm/pwmbus_if.m | 8 +++ sys/dev/pwm/pwmc.c | 14 ++--- 8 files changed, 57 insertions(+), 210 deletions(-) delete mode 100644 sys/dev/pwm/pwm_if.m diff --git a/sys/arm/allwinner/aw_pwm.c b/sys/arm/allwinner/aw_pwm.c index 67e5eec7dd76..6a042e8b2cd6 100644 --- a/sys/arm/allwinner/aw_pwm.c +++ b/sys/arm/allwinner/aw_pwm.c @@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$"); #include -#include "pwm_if.h" +#include "pwmbus_if.h" #define AW_PWM_CTRL 0x00 #define AW_PWM_CTRL_PRESCALE_MASK 0xF @@ -346,28 +346,18 @@ aw_pwm_channel_is_enabled(device_t dev, int channel, bool *enabled) return (0); } -static device_t -aw_pwm_get_bus(device_t dev) -{ - struct aw_pwm_softc *sc; - - sc = device_get_softc(dev); - - return (sc->busdev); -} static device_method_t aw_pwm_methods[] = { /* Device interface */ DEVMETHOD(device_probe, aw_pwm_probe), DEVMETHOD(device_attach, aw_pwm_attach), DEVMETHOD(device_detach, aw_pwm_detach), - /* pwm interface */ - DEVMETHOD(pwm_get_bus, aw_pwm_get_bus), - DEVMETHOD(pwm_channel_count, aw_pwm_channel_count), - DEVMETHOD(pwm_channel_config, aw_pwm_channel_config), - DEVMETHOD(pwm_channel_get_config, aw_pwm_channel_get_config), - DEVMETHOD(pwm_channel_enable, aw_pwm_channel_enable), - DEVMETHOD(pwm_channel_is_enabled, aw_pwm_channel_is_enabled), + /* pwmbus interface */ + DEVMETHOD(pwmbus_channel_count, aw_pwm_channel_count), + DEVMETHOD(pwmbus_channel_config, aw_pwm_channel_config), + DEVMETHOD(pwmbus_channel_get_config, aw_pwm_channel_get_config), + DEVMETHOD(pwmbus_channel_enable, aw_pwm_channel_enable), + DEVMETHOD(pwmbus_channel_is_enabled, aw_pwm_channel_is_enabled), DEVMETHOD_END }; diff --git a/sys/conf/files b/sys/conf/files index 1cf3ad02ce44..c9f7786fdef6 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -2702,7 +2702,6 @@ dev/puc/puc_pccard.c optional puc pccard dev/puc/puc_pci.c optional puc pci dev/pwm/pwmc.c optional pwm | pwmc dev/pwm/pwmbus.c optional pwm | pwmbus -dev/pwm/pwm_if.m optional pwm | pwmbus dev/pwm/pwmbus_if.m optional pwm | pwmbus dev/pwm/ofw_pwm.c optional pwm fdt | pwmbus fdt dev/quicc/quicc_core.c optional quicc diff --git a/sys/dev/pwm/ofw_pwm.c b/sys/dev/pwm/ofw_pwm.c index 198cf105e5e1..d15e5a7e8040 100644 --- a/sys/dev/pwm/ofw_pwm.c +++ b/sys/dev/pwm/ofw_pwm.c @@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$"); #include -#include "pwm_if.h" +#include "pwmbus_if.h" int pwm_get_by_ofw_propidx(device_t consumer, phandle_t node, @@ -62,12 +62,6 @@ pwm_get_by_ofw_propidx(device_t consumer, phandle_t node, return (ENODEV); } - channel.busdev = PWM_GET_BUS(channel.dev); - if (channel.busdev == NULL) { - OF_prop_free(cells); - return (ENODEV); - } - channel.channel = cells[0]; channel.period = cells[1]; diff --git a/sys/dev/pwm/pwm_if.m b/sys/dev/pwm/pwm_if.m deleted file mode 100644 index fbac2066d49f..000000000000 --- a/sys/dev/pwm/pwm_if.m +++ /dev/null @@ -1,106 +0,0 @@ -#- -# SPDX-License-Identifier: BSD-2-Clause-FreeBSD -# -# Copyright (c) 2018 Emmanuel Vadot -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ -# - -#include - -INTERFACE pwm; - -# -# Get the bus -# - -METHOD device_t get_bus { - device_t dev; -}; - -# -# Config the period (Total number of cycle in ns) and -# the duty (active number of cycle in ns) -# -METHOD int channel_config { - device_t dev; - int channel; - unsigned int period; - unsigned duty; -}; - -# -# Get the period (Total number of cycle in ns) and -# the duty (active number of cycle in ns) -# -METHOD int channel_get_config { - device_t dev; - int channel; - unsigned int *period; - unsigned int *duty; -}; - -# -# Set the flags -# -METHOD int channel_set_flags { - device_t dev; - int channel; - uint32_t flags; -}; - -# -# Get the flags -# -METHOD int channel_get_flags { - device_t dev; - int channel; - uint32_t *flags; -}; - -# -# Enable the pwm output -# -METHOD int channel_enable { - device_t dev; - int channel; - bool enable; -}; - -# -# Is the pwm output enabled -# -METHOD int channel_is_enabled { - device_t dev; - int channel; - bool *enabled; -}; - -# -# Get the number of channels -# -METHOD int channel_count { - device_t dev; - int *nchannel; -}; diff --git a/sys/dev/pwm/pwmbus.c b/sys/dev/pwm/pwmbus.c index 45265a4b556a..c9ffdddb645b 100644 --- a/sys/dev/pwm/pwmbus.c +++ b/sys/dev/pwm/pwmbus.c @@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$"); #include #include "pwmbus_if.h" -#include "pwm_if.h" struct pwmbus_channel_data { int reserved; @@ -55,8 +54,8 @@ struct pwmbus_channel_data { }; struct pwmbus_softc { - device_t busdev; device_t dev; + device_t parent; int nchannels; }; @@ -75,15 +74,18 @@ pwmbus_attach(device_t dev) struct pwmbus_softc *sc; sc = device_get_softc(dev); - sc->busdev = dev; - sc->dev = device_get_parent(dev); + sc->dev = dev; + sc->parent = device_get_parent(dev); - if (PWM_CHANNEL_COUNT(sc->dev, &sc->nchannels) != 0 || - sc->nchannels == 0) + if (PWMBUS_CHANNEL_COUNT(sc->parent, &sc->nchannels) != 0 || + sc->nchannels == 0) { + device_printf(sc->dev, "No channels on parent %s\n", + device_get_nameunit(sc->parent)); return (ENXIO); + } + + device_add_child(sc->dev, "pwmc", -1); - if (bootverbose) - device_printf(dev, "Registering %d channel(s)\n", sc->nchannels); bus_generic_probe(dev); return (bus_generic_attach(dev)); @@ -101,96 +103,61 @@ pwmbus_detach(device_t dev) } static int -pwmbus_channel_config(device_t bus, int chan, u_int period, u_int duty) +pwmbus_channel_config(device_t dev, int chan, u_int period, u_int duty) { - struct pwmbus_softc *sc; - - sc = device_get_softc(bus); - - if (chan > sc->nchannels) - return (EINVAL); - - return (PWM_CHANNEL_CONFIG(sc->dev, chan, period, duty)); + return (PWMBUS_CHANNEL_CONFIG(device_get_parent(dev), chan, period, duty)); } static int -pwmbus_channel_get_config(device_t bus, int chan, u_int *period, u_int *duty) +pwmbus_channel_get_config(device_t dev, int chan, u_int *period, u_int *duty) { - struct pwmbus_softc *sc; - - sc = device_get_softc(bus); - - if (chan > sc->nchannels) - return (EINVAL); - - return (PWM_CHANNEL_GET_CONFIG(sc->dev, chan, period, duty)); + return (PWMBUS_CHANNEL_GET_CONFIG(device_get_parent(dev), chan, period, duty)); } static int -pwmbus_channel_set_flags(device_t bus, int chan, uint32_t flags) +pwmbus_channel_get_flags(device_t dev, int chan, uint32_t *flags) { - struct pwmbus_softc *sc; - - sc = device_get_softc(bus); - - if (chan > sc->nchannels) - return (EINVAL); - - return (PWM_CHANNEL_SET_FLAGS(sc->dev, chan, flags)); + return (PWMBUS_CHANNEL_GET_FLAGS(device_get_parent(dev), chan, flags)); } static int -pwmbus_channel_get_flags(device_t bus, int chan, uint32_t *flags) +pwmbus_channel_enable(device_t dev, int chan, bool enable) { - struct pwmbus_softc *sc; - - sc = device_get_softc(bus); - - if (chan > sc->nchannels) - return (EINVAL); - - return (PWM_CHANNEL_GET_FLAGS(sc->dev, chan, flags)); + return (PWMBUS_CHANNEL_ENABLE(device_get_parent(dev), chan, enable)); } static int -pwmbus_channel_enable(device_t bus, int chan, bool enable) +pwmbus_channel_set_flags(device_t dev, int chan, uint32_t flags) { - struct pwmbus_softc *sc; - - sc = device_get_softc(bus); - - if (chan > sc->nchannels) - return (EINVAL); - - return (PWM_CHANNEL_ENABLE(sc->dev, chan, enable)); + return (PWMBUS_CHANNEL_SET_FLAGS(device_get_parent(dev), chan, flags)); } static int -pwmbus_channel_is_enabled(device_t bus, int chan, bool *enable) +pwmbus_channel_is_enabled(device_t dev, int chan, bool *enable) { - struct pwmbus_softc *sc; + return (PWMBUS_CHANNEL_IS_ENABLED(device_get_parent(dev), chan, enable)); +} - sc = device_get_softc(bus); - - if (chan > sc->nchannels) - return (EINVAL); - - return (PWM_CHANNEL_IS_ENABLED(sc->dev, chan, enable)); +static int +pwmbus_channel_count(device_t dev, int *nchannel) +{ + return (PWMBUS_CHANNEL_COUNT(device_get_parent(dev), nchannel)); } static device_method_t pwmbus_methods[] = { /* device_if */ - DEVMETHOD(device_probe, pwmbus_probe), + DEVMETHOD(device_probe, pwmbus_probe), DEVMETHOD(device_attach, pwmbus_attach), DEVMETHOD(device_detach, pwmbus_detach), - /* pwm interface */ - DEVMETHOD(pwmbus_channel_config, pwmbus_channel_config), - DEVMETHOD(pwmbus_channel_get_config, pwmbus_channel_get_config), - DEVMETHOD(pwmbus_channel_set_flags, pwmbus_channel_set_flags), - DEVMETHOD(pwmbus_channel_get_flags, pwmbus_channel_get_flags), - DEVMETHOD(pwmbus_channel_enable, pwmbus_channel_enable), - DEVMETHOD(pwmbus_channel_is_enabled, pwmbus_channel_is_enabled), + /* pwmbus_if */ + DEVMETHOD(pwmbus_channel_count, pwmbus_channel_count), + DEVMETHOD(pwmbus_channel_config, pwmbus_channel_config), + DEVMETHOD(pwmbus_channel_get_config, pwmbus_channel_get_config), + DEVMETHOD(pwmbus_channel_set_flags, pwmbus_channel_set_flags), + DEVMETHOD(pwmbus_channel_get_flags, pwmbus_channel_get_flags), + DEVMETHOD(pwmbus_channel_enable, pwmbus_channel_enable), + DEVMETHOD(pwmbus_channel_is_enabled, pwmbus_channel_is_enabled), DEVMETHOD_END }; diff --git a/sys/dev/pwm/pwmbus.h b/sys/dev/pwm/pwmbus.h index 52bfebe69a4d..7251b9fc79a1 100644 --- a/sys/dev/pwm/pwmbus.h +++ b/sys/dev/pwm/pwmbus.h @@ -34,7 +34,6 @@ struct pwm_channel { device_t dev; - device_t busdev; int channel; uint64_t period; uint64_t duty; diff --git a/sys/dev/pwm/pwmbus_if.m b/sys/dev/pwm/pwmbus_if.m index a08cf29aece7..b156d110969e 100644 --- a/sys/dev/pwm/pwmbus_if.m +++ b/sys/dev/pwm/pwmbus_if.m @@ -105,3 +105,11 @@ METHOD int channel_is_enabled { int channel; bool *enabled; }; + +# +# Get the number of channels +# +METHOD int channel_count { + device_t bus; + int *nchannel; +}; diff --git a/sys/dev/pwm/pwmc.c b/sys/dev/pwm/pwmc.c index 592411cffd1c..2317b52981ca 100644 --- a/sys/dev/pwm/pwmc.c +++ b/sys/dev/pwm/pwmc.c @@ -40,11 +40,9 @@ __FBSDID("$FreeBSD$"); #include #include "pwmbus_if.h" -#include "pwm_if.h" struct pwmc_softc { device_t dev; - device_t pdev; struct cdev *pwm_dev; char name[32]; }; @@ -60,14 +58,12 @@ pwm_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int rv = 0; sc = dev->si_drv1; - bus = PWM_GET_BUS(sc->pdev); - if (bus == NULL) - return (EINVAL); + bus = device_get_parent(sc->dev); switch (cmd) { case PWMMAXCHANNEL: nchannel = -1; - rv = PWM_CHANNEL_COUNT(sc->pdev, &nchannel); + rv = PWMBUS_CHANNEL_COUNT(bus, &nchannel); bcopy(&nchannel, data, sizeof(nchannel)); break; case PWMSETSTATE: @@ -106,7 +102,7 @@ pwmc_probe(device_t dev) { device_set_desc(dev, "PWM Controller"); - return (0); + return (BUS_PROBE_NOWILDCARD); } static int @@ -117,7 +113,6 @@ pwmc_attach(device_t dev) sc = device_get_softc(dev); sc->dev = dev; - sc->pdev = device_get_parent(dev); snprintf(sc->name, sizeof(sc->name), "pwmc%d", device_get_unit(dev)); make_dev_args_init(&args); @@ -161,5 +156,6 @@ static driver_t pwmc_driver = { }; static devclass_t pwmc_devclass; -DRIVER_MODULE(pwmc, pwm, pwmc_driver, pwmc_devclass, 0, 0); +DRIVER_MODULE(pwmc, pwmbus, pwmc_driver, pwmc_devclass, 0, 0); +MODULE_DEPEND(pwmc, pwmbus, 1, 1, 1); MODULE_VERSION(pwmc, 1);