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()).
This commit is contained in:
parent
6bb8042535
commit
f8f8d87cd9
@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <dev/pwm/pwmbus.h>
|
||||
|
||||
#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
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <dev/pwm/pwmbus.h>
|
||||
|
||||
#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];
|
||||
|
||||
|
@ -1,106 +0,0 @@
|
||||
#-
|
||||
# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
#
|
||||
# Copyright (c) 2018 Emmanuel Vadot <manu@FreeBSD.org>
|
||||
#
|
||||
# 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 <sys/bus.h>
|
||||
|
||||
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;
|
||||
};
|
@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/pwm/pwmbus.h>
|
||||
|
||||
#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
|
||||
};
|
||||
|
@ -34,7 +34,6 @@
|
||||
|
||||
struct pwm_channel {
|
||||
device_t dev;
|
||||
device_t busdev;
|
||||
int channel;
|
||||
uint64_t period;
|
||||
uint64_t duty;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -40,11 +40,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/pwm/pwmc.h>
|
||||
|
||||
#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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user