Derive PHY class to new one specialized for USB PHY functions.

Submitted by:	mmel
This commit is contained in:
Emmanuel Vadot 2018-11-23 19:43:18 +00:00
parent c15faaac95
commit f9f020a409
6 changed files with 371 additions and 50 deletions

View File

@ -1734,6 +1734,8 @@ dev/extres/clk/clk_mux.c optional ext_resources clk fdt
dev/extres/phy/phy.c optional ext_resources phy fdt
dev/extres/phy/phydev_if.m optional ext_resources phy fdt
dev/extres/phy/phynode_if.m optional ext_resources phy fdt
dev/extres/phy/phy_usb.c optional ext_resources phy fdt
dev/extres/phy/phynode_usb_if.m optional ext_resources phy fdt
dev/extres/hwreset/hwreset.c optional ext_resources hwreset fdt
dev/extres/hwreset/hwreset_if.m optional ext_resources hwreset fdt
dev/extres/nvmem/nvmem.c optional ext_resources nvmem fdt

View File

@ -43,18 +43,12 @@ __FBSDID("$FreeBSD$");
#endif
#include <dev/extres/phy/phy.h>
#include <dev/extres/phy/phy_internal.h>
#include "phydev_if.h"
MALLOC_DEFINE(M_PHY, "phy", "Phy framework");
/* Forward declarations. */
struct phy;
struct phynode;
typedef TAILQ_HEAD(phynode_list, phynode) phynode_list_t;
typedef TAILQ_HEAD(phy_list, phy) phy_list_t;
/* Default phy methods. */
static int phynode_method_init(struct phynode *phynode);
static int phynode_method_enable(struct phynode *phynode, bool disable);
@ -73,53 +67,10 @@ static phynode_method_t phynode_methods[] = {
};
DEFINE_CLASS_0(phynode, phynode_class, phynode_methods, 0);
/*
* Phy node
*/
struct phynode {
KOBJ_FIELDS;
TAILQ_ENTRY(phynode) phylist_link; /* Global list entry */
phy_list_t consumers_list; /* Consumers list */
/* Details of this device. */
const char *name; /* Globally unique name */
device_t pdev; /* Producer device_t */
void *softc; /* Producer softc */
intptr_t id; /* Per producer unique id */
#ifdef FDT
phandle_t ofw_node; /* OFW node of phy */
#endif
struct sx lock; /* Lock for this phy */
int ref_cnt; /* Reference counter */
int enable_cnt; /* Enabled counter */
};
struct phy {
device_t cdev; /* consumer device*/
struct phynode *phynode;
TAILQ_ENTRY(phy) link; /* Consumers list entry */
int enable_cnt;
};
static phynode_list_t phynode_list = TAILQ_HEAD_INITIALIZER(phynode_list);
static struct sx phynode_topo_lock;
SX_SYSINIT(phy_topology, &phynode_topo_lock, "Phy topology lock");
#define PHY_TOPO_SLOCK() sx_slock(&phynode_topo_lock)
#define PHY_TOPO_XLOCK() sx_xlock(&phynode_topo_lock)
#define PHY_TOPO_UNLOCK() sx_unlock(&phynode_topo_lock)
#define PHY_TOPO_ASSERT() sx_assert(&phynode_topo_lock, SA_LOCKED)
#define PHY_TOPO_XASSERT() sx_assert(&phynode_topo_lock, SA_XLOCKED)
#define PHYNODE_SLOCK(_sc) sx_slock(&((_sc)->lock))
#define PHYNODE_XLOCK(_sc) sx_xlock(&((_sc)->lock))
#define PHYNODE_UNLOCK(_sc) sx_unlock(&((_sc)->lock))
/* ----------------------------------------------------------------------------
*
* Default phy methods for base class.

View File

@ -0,0 +1,83 @@
/*-
* Copyright 2018 Michal Meloun <mmel@FreeBSD.org>
* All rights reserved.
*
* 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 ``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 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$
*/
#ifndef DEV_EXTRES_PHY_INTERNAL_H
#define DEV_EXTRES_PHY_INTERNAL_H
/* Forward declarations. */
struct phy;
struct phynode;
typedef TAILQ_HEAD(phynode_list, phynode) phynode_list_t;
typedef TAILQ_HEAD(phy_list, phy) phy_list_t;
/*
* Phy node
*/
struct phynode {
KOBJ_FIELDS;
TAILQ_ENTRY(phynode) phylist_link; /* Global list entry */
phy_list_t consumers_list; /* Consumers list */
/* Details of this device. */
const char *name; /* Globally unique name */
device_t pdev; /* Producer device_t */
void *softc; /* Producer softc */
intptr_t id; /* Per producer unique id */
#ifdef FDT
phandle_t ofw_node; /* OFW node of phy */
#endif
struct sx lock; /* Lock for this phy */
int ref_cnt; /* Reference counter */
int enable_cnt; /* Enabled counter */
};
struct phy {
device_t cdev; /* consumer device*/
struct phynode *phynode;
TAILQ_ENTRY(phy) link; /* Consumers list entry */
int enable_cnt;
};
#define PHY_TOPO_SLOCK() sx_slock(&phynode_topo_lock)
#define PHY_TOPO_XLOCK() sx_xlock(&phynode_topo_lock)
#define PHY_TOPO_UNLOCK() sx_unlock(&phynode_topo_lock)
#define PHY_TOPO_ASSERT() sx_assert(&phynode_topo_lock, SA_LOCKED)
#define PHY_TOPO_XASSERT() sx_assert(&phynode_topo_lock, SA_XLOCKED)
#define PHYNODE_SLOCK(_sc) sx_slock(&((_sc)->lock))
#define PHYNODE_XLOCK(_sc) sx_xlock(&((_sc)->lock))
#define PHYNODE_UNLOCK(_sc) sx_unlock(&((_sc)->lock))
struct sx phynode_topo_lock;
#endif /* DEV_EXTRES_PHY_INTERNAL_H */

View File

@ -0,0 +1,149 @@
/*-
* Copyright 2018 Michal Meloun <mmel@FreeBSD.org>
* All rights reserved.
*
* 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/queue.h>
#include <sys/sx.h>
#include <dev/extres/phy/phy_usb.h>
#include <dev/extres/phy/phy_internal.h>
#include "phydev_if.h"
/*
* USB phy controller methods.
*/
static phynode_usb_method_t phynode_usb_methods[] = {
PHYNODEUSBMETHOD_END
};
DEFINE_CLASS_1(phynode_usb, phynode_usb_class, phynode_usb_methods,
0, phynode_class);
/*
* Create and initialize phy object, but do not register it.
*/
struct phynode *
phynode_usb_create(device_t pdev, phynode_class_t phynode_class,
struct phynode_usb_init_def *def)
{
struct phynode *phynode;
struct phynode_usb_sc *sc;
phynode = phynode_create(pdev, phynode_class, &def->phynode_init_def);
if (phynode == NULL)
return (NULL);
sc = phynode_get_softc(phynode);
sc->std_param = def->std_param;
return (phynode);
}
struct phynode
*phynode_usb_register(struct phynode *phynode)
{
return (phynode_register(phynode));
}
/* --------------------------------------------------------------------------
*
* Real consumers executive
*
*/
/*
* Set USB phy mode. (PHY_USB_MODE_*)
*/
int
phynode_usb_set_mode(struct phynode *phynode, int usb_mode)
{
int rv;
PHY_TOPO_ASSERT();
PHYNODE_XLOCK(phynode);
rv = PHYNODE_USB_SET_MODE(phynode, usb_mode);
PHYNODE_UNLOCK(phynode);
return (rv);
}
/*
* Get USB phy mode. (PHY_USB_MODE_*)
*/
int
phynode_usb_get_mode(struct phynode *phynode, int *usb_mode)
{
int rv;
PHY_TOPO_ASSERT();
PHYNODE_XLOCK(phynode);
rv = PHYNODE_USB_GET_MODE(phynode, usb_mode);
PHYNODE_UNLOCK(phynode);
return (rv);
}
/* --------------------------------------------------------------------------
*
* USB phy consumers interface.
*
*/
int phy_usb_set_mode(phy_t phy, int usb_mode)
{
int rv;
struct phynode *phynode;
phynode = phy->phynode;
KASSERT(phynode->ref_cnt > 0,
("Attempt to access unreferenced phy.\n"));
PHY_TOPO_SLOCK();
rv = phynode_usb_set_mode(phynode, usb_mode);
PHY_TOPO_UNLOCK();
return (rv);
}
int phy_usb_get_mode(phy_t phy, int *usb_mode)
{
int rv;
struct phynode *phynode;
phynode = phy->phynode;
KASSERT(phynode->ref_cnt > 0,
("Attempt to access unreferenced phy.\n"));
PHY_TOPO_SLOCK();
rv = phynode_usb_get_mode(phynode, usb_mode);
PHY_TOPO_UNLOCK();
return (rv);
}

View File

@ -0,0 +1,85 @@
/*-
* Copyright 2018 Michal Meloun <mmel@FreeBSD.org>
* All rights reserved.
*
* 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$
*/
#ifndef _DEV_EXTRES_PHY_USB_H_
#define _DEV_EXTRES_PHY_USB_H_
#include <dev/extres/phy/phy.h>
#include "phynode_usb_if.h"
#define PHY_USB_MODE_UNKNOWN 0
#define PHY_USB_MODE_HOST 1
#define PHY_USB_MODE_OTG 2
#define PHY_USB_MODE_DEVICE 3
/* Standard USB phy parameters. */
struct phynode_usb_std_param {
int usb_mode;
};
struct phynode_usb_sc {
struct phynode_usb_std_param std_param;
};
/* Initialization parameters. */
struct phynode_usb_init_def {
struct phynode_init_def phynode_init_def;
struct phynode_usb_std_param std_param; /* Standard parameters */
};
/*
* Shorthands for constructing method tables.
*/
#define PHYNODEUSBMETHOD KOBJMETHOD
#define PHYNODEUSBMETHOD_END KOBJMETHOD_END
#define phynode_usb_method_t kobj_method_t
#define phynode_usb_class_t kobj_class_t
DECLARE_CLASS(phynode_usb_class);
struct phynode *phynode_usb_create(device_t pdev, phynode_class_t phynode_class,
struct phynode_usb_init_def *def);
struct phynode *phynode_usb_register(struct phynode *phynode);
#if 0
/* XXX to be implemented */
#ifdef FDT
int phynode_usb_parse_ofw_stdparam(device_t dev, phandle_t node,
struct phynode_usb_init_def *def);
#endif
#endif
/* Phynode functions. */
int phynode_usb_set_mode(struct phynode *phynode, int usb_mode);
int phynode_usb_get_mode(struct phynode *phynode, int *usb_mode);
/* Consumer functions. */
int phy_usb_set_mode(phy_t phy, int usb_mode);
int phy_usb_get_mode(phy_t phy, int *usb_mode);
#endif /*_DEV_EXTRES_PHY_USB_H_*/

View File

@ -0,0 +1,51 @@
#-
# Copyright 2018 Michal Meloun <mmel@FreeBSD.org>
# All rights reserved.
#
# 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$
#
INTERFACE phynode_usb;
HEADER {
struct phynode;
}
#
# Set USB mode for phy
# Returns 0 on success or a standard errno value.
#
METHOD int set_mode {
struct phynode *phynode;
int usb_mode; /* PHY_USB_MODE_* */
};
#
# Get USB mode
# Returns 0 on success or a standard errno value.
#
METHOD int get_mode {
struct phynode *phynode;
int *usb_mode; /* PHY_USB_MODE_* */
};