On Thu, Jul 5, 2018 at 2:34 AM, <m...@marvell.com> wrote: > From: Ken Ma <m...@marvell.com> > > Add a uclass which provides access to MDIO busses and includes > operations required by MDIO. > The implementation is based on the existing mii/phy/mdio data > structures and APIs. > This patch also adds device tree binding for MDIO bus. > > Signed-off-by: Ken Ma <m...@marvell.com> > Reviewed-by: s...@chromium.org, joe.hershber...@ni.com > --- > > Changes in v4: > - Minor updates for comments and Maintainer. > > Changes in v3: > - Move mdio uclass implementation to driver/net folder; > - Replace flat-tree functions with livetree functions and update codes > and comments to be consistent with driver-model codes style; > - Put struct mii_dev to uclass platdata to avoid the mdio alloc and > let driver model framework to alloc the memroy automatically, > meanwhile the mii bus link initialization is added. > > Changes in v2: > - Fix error printing: > - Change some debug to pr_err; > - mii bus has no parent member and it is not a udevice, so dev_err > is changed to pr_err for mii bus error printings. > > MAINTAINERS | 1 + > doc/device-tree-bindings/net/mdio-bus.txt | 54 ++++++++++++++ > drivers/Kconfig | 2 + > drivers/net/Makefile | 1 + > drivers/net/mdio/Kconfig | 18 +++++ > drivers/net/mdio/Makefile | 6 ++ > drivers/net/mdio/mdio-uclass.c | 112 > ++++++++++++++++++++++++++++++ > include/dm/uclass-id.h | 1 + > include/net/mdio.h | 62 +++++++++++++++++ > 9 files changed, 257 insertions(+) > create mode 100644 doc/device-tree-bindings/net/mdio-bus.txt > create mode 100644 drivers/net/mdio/Kconfig > create mode 100644 drivers/net/mdio/Makefile > create mode 100644 drivers/net/mdio/mdio-uclass.c > create mode 100644 include/net/mdio.h > > diff --git a/MAINTAINERS b/MAINTAINERS > index 642c448..07f7c66 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -432,6 +432,7 @@ M: Joe Hershberger <joe.hershber...@ni.com> > S: Maintained > T: git git://git.denx.de/u-boot-net.git > F: drivers/net/ > +F: drivers/net/mdio/ > F: net/ > > NIOS > diff --git a/doc/device-tree-bindings/net/mdio-bus.txt > b/doc/device-tree-bindings/net/mdio-bus.txt > new file mode 100644 > index 0000000..68d8b25 > --- /dev/null > +++ b/doc/device-tree-bindings/net/mdio-bus.txt > @@ -0,0 +1,54 @@ > +MDIO (Management Data Input/Output) busses > + > +MDIO busses can be described with a node for the MDIO master device > +and a set of child nodes for each phy on the bus. > + > +The MDIO node requires the following properties: > +- #address-cells - number of cells required to define phy address on > + the MDIO bus. > +- #size-cells - should be zero. > +- compatible - name of MDIO bus controller following generic names > + recommended practice. > +- reg - address and length of the MDIO register. > + > +Optional property: > +- mdio-name - MDIO bus name > + > +The child nodes of the MDIO driver are the individual PHY devices > +connected to this MDIO bus. They must have a "reg" property given the > +PHY address on the MDIO bus. > +- reg - (required) phy address in MDIO bus. > + > +Example for cp110 MDIO node at the SoC level: > + cp0_mdio: mdio@12a200 { > + #address-cells = <1>; > + #size-cells = <0>; > + compatible = "marvell,orion-mdio"; > + reg = <0x12a200 0x10>; > + mdio-name = "cp0-mdio"; > + }; > + > + cp0_xmdio: mdio@12a600 { > + #address-cells = <1>; > + #size-cells = <0>; > + compatible = "marvell,xmdio"; > + reg = <0x12a600 0x200>; > + mdio-name = "cp0-xmdio"; > + }; > + > +And at the board level, example for armada-8040-mcbin board: > + &cp0_mdio { > + ge_phy: ethernet-phy@0 { > + reg = <0>; > + }; > + }; > + > + &cp0_xmdio { > + phy0: ethernet-phy@0 { > + reg = <0>; > + }; > + > + phy8: ethernet-phy@8 { > + reg = <8>; > + }; > + }; > diff --git a/drivers/Kconfig b/drivers/Kconfig > index 9e21b28..0e0982c 100644 > --- a/drivers/Kconfig > +++ b/drivers/Kconfig > @@ -54,6 +54,8 @@ source "drivers/mtd/Kconfig" > > source "drivers/net/Kconfig" > > +source "drivers/net/mdio/Kconfig"
Please put 'source "drivers/net/mdio/Kconfig"' in drivers/net/Kconfig. > source "drivers/nvme/Kconfig" > > source "drivers/pci/Kconfig" > diff --git a/drivers/net/Makefile b/drivers/net/Makefile > index 584bfdf..1cda03f 100644 > --- a/drivers/net/Makefile > +++ b/drivers/net/Makefile > @@ -70,3 +70,4 @@ obj-$(CONFIG_VSC9953) += vsc9953.o > obj-$(CONFIG_PIC32_ETH) += pic32_mdio.o pic32_eth.o > obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o > obj-$(CONFIG_FSL_PFE) += pfe_eth/ > +obj-$(CONFIG_MDIO) += mdio/ > diff --git a/drivers/net/mdio/Kconfig b/drivers/net/mdio/Kconfig > new file mode 100644 > index 0000000..c065baa > --- /dev/null > +++ b/drivers/net/mdio/Kconfig > @@ -0,0 +1,18 @@ > +# > +# MDIO infrastructure and drivers > +# > + > +menu "MDIO Support" > + > +config MDIO > + bool "Enable MDIO (Management Data Input/Output) drivers" I think it would be smart to mention driver model for now, since many other drivers have MDIO support enabled without this. We can later remove that from the text. > + depends on DM > + help > + Enable driver model for MDIO access. > + Drivers provide methods to management data > + Input/Output. > + MDIO uclass provides interfaces to get mdio > + udevice or mii bus from its child phy node or > + an ethernet udevice which the phy belongs to. > + > +endmenu > diff --git a/drivers/net/mdio/Makefile b/drivers/net/mdio/Makefile > new file mode 100644 > index 0000000..45ae502 > --- /dev/null > +++ b/drivers/net/mdio/Makefile > @@ -0,0 +1,6 @@ > +# SPDX-License-Identifier: GPL-2.0+ > +# > +# Copyright (C) 2018 Marvell International Ltd. > +# Author: Ken Ma<m...@marvell.com> > + > +obj-$(CONFIG_MDIO) += mdio-uclass.o > diff --git a/drivers/net/mdio/mdio-uclass.c b/drivers/net/mdio/mdio-uclass.c > new file mode 100644 > index 0000000..ad4bc8f > --- /dev/null > +++ b/drivers/net/mdio/mdio-uclass.c > @@ -0,0 +1,112 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (C) 2018 Marvell International Ltd. > + * Author: Ken Ma<m...@marvell.com> > + */ > + > +#include <common.h> > +#include <fdtdec.h> You shouldn't need this. > +#include <errno.h> > +#include <dm.h> > +#include <dm/uclass.h> > +#include <dm/uclass-internal.h> > +#include <miiphy.h> > +#include <net/mdio.h> > + > +DECLARE_GLOBAL_DATA_PTR; > + > +int mdio_mii_bus_get(struct udevice *mdio_dev, struct mii_dev **busp) > +{ > + *busp = (struct mii_dev *)dev_get_uclass_platdata(mdio_dev); > + > + return 0; > +} > + > +int mdio_device_get_from_phy(ofnode phy_node, struct udevice **devp) > +{ > + ofnode mdio_node; > + > + mdio_node = ofnode_get_parent(phy_node); > + return uclass_get_device_by_ofnode(UCLASS_MDIO, mdio_node, devp); > +} > + > +int mdio_mii_bus_get_from_phy(ofnode phy_node, struct mii_dev **busp) > +{ > + struct udevice *mdio_dev; > + int ret; > + > + ret = mdio_device_get_from_phy(phy_node, &mdio_dev); > + if (ret) > + return ret; > + > + *busp = (struct mii_dev *)dev_get_uclass_platdata(mdio_dev); > + > + return 0; > +} > + > +int mdio_device_get_from_eth(struct udevice *eth, struct udevice **devp) > +{ > + struct ofnode_phandle_args phy_args; > + int ret; > + > + ret = dev_read_phandle_with_args(eth, "phy", NULL, 0, 0, &phy_args); > + if (!ret) > + return mdio_device_get_from_phy(phy_args.node, devp); > + > + /* > + * If there is no phy reference under the ethernet fdt node, > + * it is not an error since the ethernet device may do not use > + * mode; so in this case, the output mdio device pointer is set > + * as NULL. > + */ > + *devp = NULL; > + return 0; > +} > + > +int mdio_mii_bus_get_from_eth(struct udevice *eth, struct mii_dev **busp) > +{ > + struct udevice *mdio_dev; > + int ret; > + > + ret = mdio_device_get_from_eth(eth, &mdio_dev); > + if (ret) > + return ret; > + > + if (mdio_dev) > + *busp = (struct mii_dev *)dev_get_uclass_platdata(mdio_dev); > + else > + *busp = NULL; > + > + return 0; > +} > + > +static int mdio_uclass_pre_probe(struct udevice *dev) > +{ > + struct mii_dev *bus = (struct mii_dev *)dev_get_uclass_platdata(dev); > + const char *name; > + > + /* initialize mii_dev struct fields, implement mdio_alloc() setup */ > + INIT_LIST_HEAD(&bus->link); > + > + name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), > + "mdio-name", NULL); Please use dev_read_string() here. > + if (name) > + strncpy(bus->name, name, MDIO_NAME_LEN); > + > + return 0; > +} > + > +static int mdio_uclass_post_probe(struct udevice *dev) > +{ > + struct mii_dev *bus = (struct mii_dev *)dev_get_uclass_platdata(dev); > + > + return mdio_register(bus); > +} > + > +UCLASS_DRIVER(mdio) = { > + .id = UCLASS_MDIO, > + .name = "mdio", > + .pre_probe = mdio_uclass_pre_probe, > + .post_probe = mdio_uclass_post_probe, > + .per_device_platdata_auto_alloc_size = sizeof(struct mii_dev), > +}; <snip> _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot