summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authormmel <mmel@FreeBSD.org>2018-04-04 13:23:06 +0000
committermmel <mmel@FreeBSD.org>2018-04-04 13:23:06 +0000
commit07b3d148b9dc169784fe35fce1b25a13b3453d6a (patch)
tree0d46887110d7e2f90a8b7dbeccd8765e6b166978 /sys/arm
parent9272ccc837315f7485064286c0ba1d434b8dfd1b (diff)
downloadFreeBSD-src-07b3d148b9dc169784fe35fce1b25a13b3453d6a.zip
FreeBSD-src-07b3d148b9dc169784fe35fce1b25a13b3453d6a.tar.gz
MFC r328201:
Convert extres/phy to kobj model. Similarly as other extres pseudo-drivers, implement phy by using kobj model. This detaches it from provider device, so single device driver can export multiple different phys. Additionally, this allows phy to be subclassed to more specialized drivers, like is USB OTG phy, or PCIe phy with hot-plug capability.
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/allwinner/a10_ehci.c2
-rw-r--r--sys/arm/allwinner/aw_usbphy.c43
-rw-r--r--sys/arm/nvidia/tegra124/tegra124_xusbpadctl.c70
-rw-r--r--sys/arm/nvidia/tegra_ahci.c2
-rw-r--r--sys/arm/nvidia/tegra_ehci.c2
-rw-r--r--sys/arm/nvidia/tegra_pcie.c2
-rw-r--r--sys/arm/nvidia/tegra_usbphy.c38
-rw-r--r--sys/arm/nvidia/tegra_xhci.c8
8 files changed, 113 insertions, 54 deletions
diff --git a/sys/arm/allwinner/a10_ehci.c b/sys/arm/allwinner/a10_ehci.c
index d750a71..19b4493 100644
--- a/sys/arm/allwinner/a10_ehci.c
+++ b/sys/arm/allwinner/a10_ehci.c
@@ -231,7 +231,7 @@ a10_ehci_attach(device_t self)
device_printf(self, "Could not get phy\n");
goto error;
}
- err = phy_enable(self, aw_sc->phy);
+ err = phy_enable(aw_sc->phy);
if (err != 0) {
device_printf(self, "Could not enable phy\n");
goto error;
diff --git a/sys/arm/allwinner/aw_usbphy.c b/sys/arm/allwinner/aw_usbphy.c
index 221b2cc..942b841 100644
--- a/sys/arm/allwinner/aw_usbphy.c
+++ b/sys/arm/allwinner/aw_usbphy.c
@@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$");
#include <dev/extres/regulator/regulator.h>
#include <dev/extres/phy/phy.h>
-#include "phy_if.h"
+#include "phynode_if.h"
#define USBPHY_NPHYS 4
@@ -72,6 +72,16 @@ struct awusbphy_softc {
int vbus_det_valid;
};
+ /* Phy class and methods. */
+static int awusbphy_phy_enable(struct phynode *phy, bool enable);
+static phynode_method_t awusbphy_phynode_methods[] = {
+ PHYNODEMETHOD(phynode_enable, awusbphy_phy_enable),
+
+ PHYNODEMETHOD_END
+};
+DEFINE_CLASS_1(awusbphy_phynode, awusbphy_phynode_class, awusbphy_phynode_methods,
+ 0, phynode_class);
+
static int
awusbphy_init(device_t dev)
{
@@ -148,12 +158,18 @@ awusbphy_vbus_detect(device_t dev, int *val)
}
static int
-awusbphy_phy_enable(device_t dev, intptr_t phy, bool enable)
+awusbphy_phy_enable(struct phynode *phynode, bool enable)
{
+ device_t dev;
+ intptr_t phy;
struct awusbphy_softc *sc;
regulator_t reg;
int error, vbus_det;
+ dev = phynode_get_device(phynode);
+ phy = phynode_get_id(phynode);
+ sc = device_get_softc(dev);
+
if (phy < 0 || phy >= USBPHY_NPHYS)
return (ERANGE);
@@ -203,6 +219,9 @@ static int
awusbphy_attach(device_t dev)
{
int error;
+ struct phynode *phynode;
+ struct phynode_init_def phy_init;
+ int i;
error = awusbphy_init(dev);
if (error) {
@@ -211,7 +230,22 @@ awusbphy_attach(device_t dev)
return (error);
}
- phy_register_provider(dev);
+ /* Create and register phys. */
+ for (i = 0; i < USBPHY_NPHYS; i++) {
+ bzero(&phy_init, sizeof(phy_init));
+ phy_init.id = i;
+ phy_init.ofw_node = ofw_bus_get_node(dev);
+ phynode = phynode_create(dev, &awusbphy_phynode_class,
+ &phy_init);
+ if (phynode == NULL) {
+ device_printf(dev, "failed to create USB PHY\n");
+ return (ENXIO);
+ }
+ if (phynode_register(phynode) == NULL) {
+ device_printf(dev, "failed to create USB PHY\n");
+ return (ENXIO);
+ }
+ }
return (error);
}
@@ -221,9 +255,6 @@ static device_method_t awusbphy_methods[] = {
DEVMETHOD(device_probe, awusbphy_probe),
DEVMETHOD(device_attach, awusbphy_attach),
- /* PHY interface */
- DEVMETHOD(phy_enable, awusbphy_phy_enable),
-
DEVMETHOD_END
};
diff --git a/sys/arm/nvidia/tegra124/tegra124_xusbpadctl.c b/sys/arm/nvidia/tegra124/tegra124_xusbpadctl.c
index 2b1c9f5..822a0ad 100644
--- a/sys/arm/nvidia/tegra124/tegra124_xusbpadctl.c
+++ b/sys/arm/nvidia/tegra124/tegra124_xusbpadctl.c
@@ -22,10 +22,11 @@
* 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/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
@@ -50,7 +51,7 @@
#include <gnu/dts/include/dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
-#include "phy_if.h"
+#include "phydev_if.h"
/* FUSE calibration data. */
#define FUSE_XUSB_CALIB 0x0F0
@@ -216,7 +217,6 @@ struct padctl_port {
struct padctl_port *port);
/* Runtime data. */
- phandle_t xref;
bool enabled;
regulator_t supply_vbus; /* USB2, USB3 */
bool internal; /* ULPI, USB2, USB3 */
@@ -303,7 +303,6 @@ struct padctl_lane {
int nmux;
/* Runtime data. */
bool enabled;
- phandle_t xref;
struct padctl_pad *pad;
struct padctl_port *port;
int mux_idx;
@@ -353,6 +352,16 @@ static struct padctl_lane_map lane_map_tbl[] = {
LANE_MAP(1, PADCTL_PAD_SATA, 0), /* port USB3-1 -> lane SATA-0 */
};
+ /* Phy class and methods. */
+static int xusbpadctl_phy_enable(struct phynode *phy, bool enable);
+static phynode_method_t xusbpadctl_phynode_methods[] = {
+ PHYNODEMETHOD(phynode_enable, xusbpadctl_phy_enable),
+ PHYNODEMETHOD_END
+
+};
+DEFINE_CLASS_1(xusbpadctl_phynode, xusbpadctl_phynode_class,
+ xusbpadctl_phynode_methods, 0, phynode_class);
+
static struct padctl_port *search_lane_port(struct padctl_softc *sc,
struct padctl_lane *lane);
/* -------------------------------------------------------------------------
@@ -683,13 +692,17 @@ phy_powerdown(struct padctl_softc *sc)
}
static int
-xusbpadctl_phy_enable(device_t dev, intptr_t id, bool enable)
+xusbpadctl_phy_enable(struct phynode *phy, bool enable)
{
+ device_t dev;
+ intptr_t id;
struct padctl_softc *sc;
struct padctl_lane *lane;
struct padctl_pad *pad;
int rv;
+ dev = phynode_get_device(phy);
+ id = phynode_get_id(phy);
sc = device_get_softc(dev);
if (id < 0 || id >= nitems(lanes_tbl)) {
@@ -731,24 +744,6 @@ xusbpadctl_phy_enable(device_t dev, intptr_t id, bool enable)
return (0);
}
-static int
-xusbpadctl_phy_map(device_t provider, phandle_t xref, int ncells,
- pcell_t *cells, intptr_t *id)
-{
- int i;
-
- if (ncells != 0)
- return (ERANGE);
-
- for (i = 0; i < nitems(lanes_tbl); i++) {
- if (lanes_tbl[i].xref == xref) {
- *id = i;
- return (0);
- }
- }
- return (ENXIO);
-}
-
/* -------------------------------------------------------------------------
*
* FDT processing
@@ -871,6 +866,8 @@ static int
process_lane(struct padctl_softc *sc, phandle_t node, struct padctl_pad *pad)
{
struct padctl_lane *lane;
+ struct phynode *phynode;
+ struct phynode_init_def phy_init;
char *name;
char *function;
int rv;
@@ -913,10 +910,25 @@ process_lane(struct padctl_softc *sc, phandle_t node, struct padctl_pad *pad)
rv = ENXIO;
goto end;
}
- lane->xref = OF_xref_from_node(node);
lane->pad = pad;
lane->enabled = true;
pad->lanes[pad->nlanes++] = lane;
+
+ /* Create and register phy. */
+ bzero(&phy_init, sizeof(phy_init));
+ phy_init.id = lane - lanes_tbl;
+ phy_init.ofw_node = node;
+ phynode = phynode_create(sc->dev, &xusbpadctl_phynode_class, &phy_init);
+ if (phynode == NULL) {
+ device_printf(sc->dev, "Cannot create phy\n");
+ rv = ENXIO;
+ goto end;
+ }
+ if (phynode_register(phynode) == NULL) {
+ device_printf(sc->dev, "Cannot create phy\n");
+ return (ENXIO);
+ }
+
rv = 0;
end:
@@ -930,7 +942,6 @@ end:
static int
process_pad(struct padctl_softc *sc, phandle_t node)
{
- phandle_t xref;
struct padctl_pad *pad;
char *name;
int rv;
@@ -963,9 +974,6 @@ process_pad(struct padctl_softc *sc, phandle_t node)
rv = process_lane(sc, node, pad);
if (rv != 0)
goto end;
-
- xref = OF_xref_from_node(node);
- OF_device_register_xref(xref, sc->dev);
}
pad->enabled = true;
rv = 0;
@@ -1194,10 +1202,6 @@ static device_method_t tegra_xusbpadctl_methods[] = {
DEVMETHOD(device_attach, xusbpadctl_attach),
DEVMETHOD(device_detach, xusbpadctl_detach),
- /* phy interface */
- DEVMETHOD(phy_enable, xusbpadctl_phy_enable),
- DEVMETHOD(phy_map, xusbpadctl_phy_map),
-
DEVMETHOD_END
};
diff --git a/sys/arm/nvidia/tegra_ahci.c b/sys/arm/nvidia/tegra_ahci.c
index e1a3c08..41551f7 100644
--- a/sys/arm/nvidia/tegra_ahci.c
+++ b/sys/arm/nvidia/tegra_ahci.c
@@ -372,7 +372,7 @@ enable_fdt_resources(struct tegra_ahci_sc *sc)
return (rv);
}
- rv = phy_enable(sc->dev, sc->phy);
+ rv = phy_enable(sc->phy);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable SATA phy\n");
return (rv);
diff --git a/sys/arm/nvidia/tegra_ehci.c b/sys/arm/nvidia/tegra_ehci.c
index 7a041d5..de0ebd8 100644
--- a/sys/arm/nvidia/tegra_ehci.c
+++ b/sys/arm/nvidia/tegra_ehci.c
@@ -214,7 +214,7 @@ tegra_ehci_attach(device_t dev)
goto out;
}
- rv = phy_enable(sc->dev, sc->phy);
+ rv = phy_enable(sc->phy);
if (rv != 0) {
device_printf(dev, "Cannot enable phy: %d\n", rv);
goto out;
diff --git a/sys/arm/nvidia/tegra_pcie.c b/sys/arm/nvidia/tegra_pcie.c
index 4fe7c71..87f0537 100644
--- a/sys/arm/nvidia/tegra_pcie.c
+++ b/sys/arm/nvidia/tegra_pcie.c
@@ -1310,7 +1310,7 @@ tegra_pcib_enable(struct tegra_pcib_softc *sc)
for (i = 0; i < TEGRA_PCIB_MAX_PORTS; i++) {
if (sc->ports[i] != NULL) {
- rv = phy_enable(sc->dev, sc->ports[i]->phy);
+ rv = phy_enable(sc->ports[i]->phy);
if (rv != 0) {
device_printf(sc->dev,
"Cannot enable phy for port %d\n",
diff --git a/sys/arm/nvidia/tegra_usbphy.c b/sys/arm/nvidia/tegra_usbphy.c
index d1c6eeb..d3333fd 100644
--- a/sys/arm/nvidia/tegra_usbphy.c
+++ b/sys/arm/nvidia/tegra_usbphy.c
@@ -52,7 +52,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
-#include "phy_if.h"
+#include "phynode_if.h"
#define CTRL_ICUSB_CTRL 0x15c
#define ICUSB_CTR_IC_ENB1 (1 << 3)
@@ -300,6 +300,16 @@ static struct ofw_compat_data compat_data[] = {
{NULL, 0},
};
+ /* Phy controller class and methods. */
+static int usbphy_phy_enable(struct phynode *phy, bool enable);
+static phynode_method_t usbphy_phynode_methods[] = {
+ PHYNODEMETHOD(phynode_enable, usbphy_phy_enable),
+
+ PHYNODEMETHOD_END
+};
+DEFINE_CLASS_1(usbphy_phynode, usbphy_phynode_class, usbphy_phynode_methods,
+ 0, phynode_class);
+
#define RD4(sc, offs) \
bus_read_4(sc->mem_res, offs)
@@ -555,11 +565,13 @@ usbphy_utmi_disable(struct usbphy_softc *sc)
}
static int
-usbphy_phy_enable(device_t dev, int id, bool enable)
+usbphy_phy_enable(struct phynode *phy, bool enable)
{
+ device_t dev;
struct usbphy_softc *sc;
int rv = 0;
+ dev = phynode_get_device(phy);
sc = device_get_softc(dev);
if (sc->ifc_type != USB_IFC_TYPE_UTMI) {
@@ -701,9 +713,11 @@ usbphy_probe(device_t dev)
static int
usbphy_attach(device_t dev)
{
- struct usbphy_softc * sc;
+ struct usbphy_softc *sc;
int rid, rv;
phandle_t node;
+ struct phynode *phynode;
+ struct phynode_init_def phy_init;
sc = device_get_softc(dev);
sc->dev = dev;
@@ -803,7 +817,20 @@ usbphy_attach(device_t dev)
}
}
- phy_register_provider(dev);
+ /* Create and register phy. */
+ bzero(&phy_init, sizeof(phy_init));
+ phy_init.id = 1;
+ phy_init.ofw_node = node;
+ phynode = phynode_create(dev, &usbphy_phynode_class, &phy_init);
+ if (phynode == NULL) {
+ device_printf(sc->dev, "Cannot create phy\n");
+ return (ENXIO);
+ }
+ if (phynode_register(phynode) == NULL) {
+ device_printf(sc->dev, "Cannot create phy\n");
+ return (ENXIO);
+ }
+
return (0);
}
@@ -821,9 +848,6 @@ static device_method_t tegra_usbphy_methods[] = {
DEVMETHOD(device_attach, usbphy_attach),
DEVMETHOD(device_detach, usbphy_detach),
- /* phy interface */
- DEVMETHOD(phy_enable, usbphy_phy_enable),
-
DEVMETHOD_END
};
diff --git a/sys/arm/nvidia/tegra_xhci.c b/sys/arm/nvidia/tegra_xhci.c
index a9d3ca6..64bf889 100644
--- a/sys/arm/nvidia/tegra_xhci.c
+++ b/sys/arm/nvidia/tegra_xhci.c
@@ -583,22 +583,22 @@ enable_fdt_resources(struct tegra_xhci_softc *sc)
return (rv);
}
- rv = phy_enable(sc->dev, sc->phy_usb2_0);
+ rv = phy_enable(sc->phy_usb2_0);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable USB2_0 phy\n");
return (rv);
}
- rv = phy_enable(sc->dev, sc->phy_usb2_1);
+ rv = phy_enable(sc->phy_usb2_1);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable USB2_1 phy\n");
return (rv);
}
- rv = phy_enable(sc->dev, sc->phy_usb2_2);
+ rv = phy_enable(sc->phy_usb2_2);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable USB2_2 phy\n");
return (rv);
}
- rv = phy_enable(sc->dev, sc->phy_usb3_0);
+ rv = phy_enable(sc->phy_usb3_0);
if (rv != 0) {
device_printf(sc->dev, "Cannot enable USB3_0 phy\n");
return (rv);
OpenPOWER on IntegriCloud