[U-Boot] [PATCH v4 1/2] dm: mdio: add a uclass for MDIO
Joe Hershberger
joe.hershberger at ni.com
Mon Jul 9 21:05:09 UTC 2018
On Thu, Jul 5, 2018 at 2:34 AM, <make at marvell.com> wrote:
> From: Ken Ma <make at 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 <make at marvell.com>
> Reviewed-by: sjg at chromium.org, joe.hershberger at 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.hershberger at 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 at 12a200 {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + compatible = "marvell,orion-mdio";
> + reg = <0x12a200 0x10>;
> + mdio-name = "cp0-mdio";
> + };
> +
> + cp0_xmdio: mdio at 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 at 0 {
> + reg = <0>;
> + };
> + };
> +
> + &cp0_xmdio {
> + phy0: ethernet-phy at 0 {
> + reg = <0>;
> + };
> +
> + phy8: ethernet-phy at 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<make at 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<make at 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>
More information about the U-Boot
mailing list