From: Leon Romanovsky <leon@kernel.org>
To: Robert Marko <robert.marko@sartura.hr>
Cc: andrew@lunn.ch, f.fainelli@gmail.com, hkallweit1@gmail.com,
linux@armlinux.org.uk, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, agross@kernel.org,
bjorn.andersson@linaro.org, robh+dt@kernel.org,
mark.rutland@arm.com, linux-arm-msm@vger.kernel.org,
devicetree@vger.kernel.org,
Christian Lamparter <chunkeey@gmail.com>,
Luka Perkov <luka.perkov@sartura.hr>
Subject: Re: [PATCH v3 1/3] net: phy: mdio: add IPQ40xx MDIO driver
Date: Thu, 16 Apr 2020 10:28:01 +0300 [thread overview]
Message-ID: <20200416072801.GG1309273@unreal> (raw)
In-Reply-To: <20200415150244.2737206-1-robert.marko@sartura.hr>
On Wed, Apr 15, 2020 at 05:02:43PM +0200, Robert Marko wrote:
> This patch adds the driver for the MDIO interface
> inside of Qualcomm IPQ40xx series SoC-s.
>
> Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
> Signed-off-by: Robert Marko <robert.marko@sartura.hr>
> Cc: Luka Perkov <luka.perkov@sartura.hr>
> ---
> Changes from v2 to v3:
> * Rename registers
> * Remove unnecessary variable initialisations
> * Switch to readl_poll_timeout() instead of custom solution
> * Drop unused header
>
> Changes from v1 to v2:
> * Remove magic default value
> * Remove lockdep_assert_held
> * Add C45 check
> * Simplify the driver
> * Drop device and mii_bus structs from private struct
> * Use devm_mdiobus_alloc_size()
>
> drivers/net/phy/Kconfig | 7 ++
> drivers/net/phy/Makefile | 1 +
> drivers/net/phy/mdio-ipq40xx.c | 160 +++++++++++++++++++++++++++++++++
> 3 files changed, 168 insertions(+)
> create mode 100644 drivers/net/phy/mdio-ipq40xx.c
>
> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
> index 3fa33d27eeba..23bb5db033e3 100644
> --- a/drivers/net/phy/Kconfig
> +++ b/drivers/net/phy/Kconfig
> @@ -157,6 +157,13 @@ config MDIO_I2C
>
> This is library mode.
>
> +config MDIO_IPQ40XX
> + tristate "Qualcomm IPQ40xx MDIO interface"
> + depends on HAS_IOMEM && OF_MDIO
> + help
> + This driver supports the MDIO interface found in Qualcomm
> + IPQ40xx series Soc-s.
> +
> config MDIO_IPQ8064
> tristate "Qualcomm IPQ8064 MDIO interface support"
> depends on HAS_IOMEM && OF_MDIO
> diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
> index 2f5c7093a65b..36aafc6128c4 100644
> --- a/drivers/net/phy/Makefile
> +++ b/drivers/net/phy/Makefile
> @@ -37,6 +37,7 @@ obj-$(CONFIG_MDIO_CAVIUM) += mdio-cavium.o
> obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o
> obj-$(CONFIG_MDIO_HISI_FEMAC) += mdio-hisi-femac.o
> obj-$(CONFIG_MDIO_I2C) += mdio-i2c.o
> +obj-$(CONFIG_MDIO_IPQ40XX) += mdio-ipq40xx.o
> obj-$(CONFIG_MDIO_IPQ8064) += mdio-ipq8064.o
> obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o
> obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o
> diff --git a/drivers/net/phy/mdio-ipq40xx.c b/drivers/net/phy/mdio-ipq40xx.c
> new file mode 100644
> index 000000000000..acf1230341bd
> --- /dev/null
> +++ b/drivers/net/phy/mdio-ipq40xx.c
> @@ -0,0 +1,160 @@
> +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
> +/* Copyright (c) 2015, The Linux Foundation. All rights reserved. */
> +/* Copyright (c) 2020 Sartura Ltd. */
> +
> +#include <linux/delay.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/of_address.h>
> +#include <linux/of_mdio.h>
> +#include <linux/phy.h>
> +#include <linux/platform_device.h>
> +
> +#define MDIO_ADDR_REG 0x44
> +#define MDIO_DATA_WRITE_REG 0x48
> +#define MDIO_DATA_READ_REG 0x4c
> +#define MDIO_CMD_REG 0x50
> +#define MDIO_CMD_ACCESS_BUSY BIT(16)
> +#define MDIO_CMD_ACCESS_START BIT(8)
> +#define MDIO_CMD_ACCESS_CODE_READ 0
> +#define MDIO_CMD_ACCESS_CODE_WRITE 1
> +
> +#define IPQ40XX_MDIO_TIMEOUT 10000
> +#define IPQ40XX_MDIO_SLEEP 10
> +
> +struct ipq40xx_mdio_data {
> + void __iomem *membase;
> +};
> +
> +static int ipq40xx_mdio_wait_busy(struct mii_bus *bus)
> +{
> + struct ipq40xx_mdio_data *priv = bus->priv;
> + unsigned int busy;
> +
> + return readl_poll_timeout(priv->membase + MDIO_CMD_REG, busy,
> + (busy & MDIO_CMD_ACCESS_BUSY) == 0,
> + IPQ40XX_MDIO_SLEEP, IPQ40XX_MDIO_TIMEOUT);
> +}
> +
> +static int ipq40xx_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
> +{
> + struct ipq40xx_mdio_data *priv = bus->priv;
> + unsigned int cmd;
> +
> + /* Reject clause 45 */
> + if (regnum & MII_ADDR_C45)
> + return -EOPNOTSUPP;
> +
> + if (ipq40xx_mdio_wait_busy(bus))
> + return -ETIMEDOUT;
> +
> + /* issue the phy address and reg */
> + writel((mii_id << 8) | regnum, priv->membase + MDIO_ADDR_REG);
> +
> + cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_READ;
> +
> + /* issue read command */
> + writel(cmd, priv->membase + MDIO_CMD_REG);
> +
> + /* Wait read complete */
> + if (ipq40xx_mdio_wait_busy(bus))
> + return -ETIMEDOUT;
> +
> + /* Read and return data */
> + return readl(priv->membase + MDIO_DATA_READ_REG);
> +}
> +
> +static int ipq40xx_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
> + u16 value)
> +{
> + struct ipq40xx_mdio_data *priv = bus->priv;
> + unsigned int cmd;
> +
> + /* Reject clause 45 */
> + if (regnum & MII_ADDR_C45)
> + return -EOPNOTSUPP;
> +
> + if (ipq40xx_mdio_wait_busy(bus))
> + return -ETIMEDOUT;
> +
> + /* issue the phy address and reg */
> + writel((mii_id << 8) | regnum, priv->membase + MDIO_ADDR_REG);
> +
> + /* issue write data */
> + writel(value, priv->membase + MDIO_DATA_WRITE_REG);
> +
> + cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_WRITE;
> + /* issue write command */
> + writel(cmd, priv->membase + MDIO_CMD_REG);
> +
> + /* Wait write complete */
> + if (ipq40xx_mdio_wait_busy(bus))
> + return -ETIMEDOUT;
> +
> + return 0;
> +}
> +
> +static int ipq40xx_mdio_probe(struct platform_device *pdev)
> +{
> + struct ipq40xx_mdio_data *priv;
> + struct mii_bus *bus;
> + int ret;
> +
> + bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*priv));
> + if (!bus)
> + return -ENOMEM;
> +
> + priv = bus->priv;
> +
> + priv->membase = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(priv->membase))
> + return PTR_ERR(priv->membase);
> +
> + bus->name = "ipq40xx_mdio";
> + bus->read = ipq40xx_mdio_read;
> + bus->write = ipq40xx_mdio_write;
> + bus->parent = &pdev->dev;
> + snprintf(bus->id, MII_BUS_ID_SIZE, "%s%d", pdev->name, pdev->id);
> +
> + ret = of_mdiobus_register(bus, pdev->dev.of_node);
> + if (ret) {
> + dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
> + return ret;
> + }
> +
> + platform_set_drvdata(pdev, bus);
> +
> + return 0;
> +}
> +
> +static int ipq40xx_mdio_remove(struct platform_device *pdev)
> +{
> + struct mii_bus *bus = platform_get_drvdata(pdev);
> +
> + mdiobus_unregister(bus);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id ipq40xx_mdio_dt_ids[] = {
> + { .compatible = "qcom,ipq40xx-mdio" },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, ipq40xx_mdio_dt_ids);
> +
> +static struct platform_driver ipq40xx_mdio_driver = {
> + .probe = ipq40xx_mdio_probe,
> + .remove = ipq40xx_mdio_remove,
> + .driver = {
> + .name = "ipq40xx-mdio",
> + .of_match_table = ipq40xx_mdio_dt_ids,
> + },
> +};
> +
> +module_platform_driver(ipq40xx_mdio_driver);
> +
> +MODULE_DESCRIPTION("IPQ40XX MDIO interface driver");
> +MODULE_AUTHOR("Qualcomm Atheros");
Strictly saying, but author can't be company.
> +MODULE_LICENSE("Dual BSD/GPL");
> --
> 2.26.0
>
prev parent reply other threads:[~2020-04-16 7:28 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-15 15:02 [PATCH v3 1/3] net: phy: mdio: add IPQ40xx MDIO driver Robert Marko
2020-04-15 15:02 ` [PATCH v3 2/3] dt-bindings: add Qualcomm IPQ4019 MDIO bindings Robert Marko
2020-04-15 23:49 ` Andrew Lunn
2020-04-15 23:55 ` Florian Fainelli
2020-04-16 8:43 ` Robert Marko
2020-04-28 15:09 ` Rob Herring
2020-04-28 16:40 ` Robert Marko
2020-04-15 15:02 ` [PATCH v3 3/3] ARM: dts: qcom: ipq4019: add MDIO node Robert Marko
2020-04-15 23:51 ` Andrew Lunn
2020-04-15 23:56 ` Florian Fainelli
2020-04-15 23:48 ` [PATCH v3 1/3] net: phy: mdio: add IPQ40xx MDIO driver Andrew Lunn
2020-04-16 8:43 ` Robert Marko
2020-04-15 23:57 ` Florian Fainelli
2020-04-16 7:28 ` Leon Romanovsky [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200416072801.GG1309273@unreal \
--to=leon@kernel.org \
--cc=agross@kernel.org \
--cc=andrew@lunn.ch \
--cc=bjorn.andersson@linaro.org \
--cc=chunkeey@gmail.com \
--cc=devicetree@vger.kernel.org \
--cc=f.fainelli@gmail.com \
--cc=hkallweit1@gmail.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=luka.perkov@sartura.hr \
--cc=mark.rutland@arm.com \
--cc=netdev@vger.kernel.org \
--cc=robert.marko@sartura.hr \
--cc=robh+dt@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.