Просмотр исходного кода

ipq40xx: decouple mdio-ipq40xx and ar40xx

This makes it possible to delete the ar40xx driver in the
future by just removing the file.

Signed-off-by: Christian Lamparter <[email protected]>
Christian Lamparter 6 лет назад
Родитель
Сommit
fd58035a8e

+ 230 - 0
target/linux/ipq40xx/patches-4.19/700-net-add-qualcomm-mdio.patch

@@ -0,0 +1,230 @@
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -519,6 +519,13 @@ config XILINX_GMII2RGMII
+ 	  the Reduced Gigabit Media Independent Interface(RGMII) between
+ 	  Ethernet physical media devices and the Gigabit Ethernet controller.
+ 
++config MDIO_IPQ40XX
++	tristate "Qualcomm Atheros ipq40xx MDIO interface"
++	depends on HAS_IOMEM && OF
++	---help---
++	  This driver supports the MDIO interface found in Qualcomm
++	  Atheros ipq40xx Soc chip.
++
+ endif # PHYLIB
+ 
+ config MICREL_KS8995MA
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -48,6 +48,7 @@ obj-$(CONFIG_MDIO_CAVIUM)	+= mdio-cavium
+ 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_MOXART)	+= mdio-moxart.o
+ obj-$(CONFIG_MDIO_MSCC_MIIM)	+= mdio-mscc-miim.o
+ obj-$(CONFIG_MDIO_OCTEON)	+= mdio-octeon.o
+--- /dev/null
++++ b/drivers/net/phy/mdio-ipq40xx.c
+@@ -0,0 +1,201 @@
++/*
++ * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
++ *
++ * Permission to use, copy, modify, and/or distribute this software for
++ * any purpose with or without fee is hereby granted, provided that the
++ * above copyright notice and this permission notice appear in all copies.
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
++ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <linux/delay.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/mutex.h>
++#include <linux/io.h>
++#include <linux/of_address.h>
++#include <linux/of_mdio.h>
++#include <linux/phy.h>
++#include <linux/platform_device.h>
++
++#define MDIO_CTRL_0_REG		0x40
++#define MDIO_CTRL_1_REG		0x44
++#define MDIO_CTRL_2_REG		0x48
++#define MDIO_CTRL_3_REG		0x4c
++#define MDIO_CTRL_4_REG		0x50
++#define MDIO_CTRL_4_ACCESS_BUSY		BIT(16)
++#define MDIO_CTRL_4_ACCESS_START		BIT(8)
++#define MDIO_CTRL_4_ACCESS_CODE_READ		0
++#define MDIO_CTRL_4_ACCESS_CODE_WRITE	1
++#define CTRL_0_REG_DEFAULT_VALUE	0x150FF
++
++#define IPQ40XX_MDIO_RETRY	1000
++#define IPQ40XX_MDIO_DELAY	10
++
++struct ipq40xx_mdio_data {
++	struct mii_bus	*mii_bus;
++	void __iomem	*membase;
++	int		phy_irq[PHY_MAX_ADDR];
++	struct device	*dev;
++};
++
++static int ipq40xx_mdio_wait_busy(struct ipq40xx_mdio_data *am)
++{
++	int i;
++
++	for (i = 0; i < IPQ40XX_MDIO_RETRY; i++) {
++		unsigned int busy;
++
++		busy = readl(am->membase + MDIO_CTRL_4_REG) &
++			MDIO_CTRL_4_ACCESS_BUSY;
++		if (!busy)
++			return 0;
++
++		/* BUSY might take to be cleard by 15~20 times of loop */
++		udelay(IPQ40XX_MDIO_DELAY);
++	}
++
++	dev_err(am->dev, "%s: MDIO operation timed out\n", am->mii_bus->name);
++
++	return -ETIMEDOUT;
++}
++
++static int ipq40xx_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
++{
++	struct ipq40xx_mdio_data *am = bus->priv;
++	int value = 0;
++	unsigned int cmd = 0;
++
++	lockdep_assert_held(&bus->mdio_lock);
++
++	if (ipq40xx_mdio_wait_busy(am))
++		return -ETIMEDOUT;
++
++	/* issue the phy address and reg */
++	writel((mii_id << 8) | regnum, am->membase + MDIO_CTRL_1_REG);
++
++	cmd = MDIO_CTRL_4_ACCESS_START|MDIO_CTRL_4_ACCESS_CODE_READ;
++
++	/* issue read command */
++	writel(cmd, am->membase + MDIO_CTRL_4_REG);
++
++	/* Wait read complete */
++	if (ipq40xx_mdio_wait_busy(am))
++		return -ETIMEDOUT;
++
++	/* Read data */
++	value = readl(am->membase + MDIO_CTRL_3_REG);
++
++	return value;
++}
++
++static int ipq40xx_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
++			    u16 value)
++{
++	struct ipq40xx_mdio_data *am = bus->priv;
++	unsigned int cmd = 0;
++
++	lockdep_assert_held(&bus->mdio_lock);
++
++	if (ipq40xx_mdio_wait_busy(am))
++		return -ETIMEDOUT;
++
++	/* issue the phy address and reg */
++	writel((mii_id << 8) | regnum, am->membase + MDIO_CTRL_1_REG);
++
++	/* issue write data */
++	writel(value, am->membase + MDIO_CTRL_2_REG);
++
++	cmd = MDIO_CTRL_4_ACCESS_START|MDIO_CTRL_4_ACCESS_CODE_WRITE;
++	/* issue write command */
++	writel(cmd, am->membase + MDIO_CTRL_4_REG);
++
++	/* Wait write complete */
++	if (ipq40xx_mdio_wait_busy(am))
++		return -ETIMEDOUT;
++
++	return 0;
++}
++
++static int ipq40xx_mdio_probe(struct platform_device *pdev)
++{
++	struct ipq40xx_mdio_data *am;
++	struct resource *res;
++	int i;
++
++	am = devm_kzalloc(&pdev->dev, sizeof(*am), GFP_KERNEL);
++	if (!am)
++		return -ENOMEM;
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!res) {
++		dev_err(&pdev->dev, "no iomem resource found\n");
++		return -ENXIO;
++	}
++
++	am->membase = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(am->membase)) {
++		dev_err(&pdev->dev, "unable to ioremap registers\n");
++		return PTR_ERR(am->membase);
++	}
++
++	am->mii_bus = devm_mdiobus_alloc(&pdev->dev);
++	if (!am->mii_bus)
++		return  -ENOMEM;
++
++	writel(CTRL_0_REG_DEFAULT_VALUE, am->membase + MDIO_CTRL_0_REG);
++
++	am->mii_bus->name = "ipq40xx_mdio";
++	am->mii_bus->read = ipq40xx_mdio_read;
++	am->mii_bus->write = ipq40xx_mdio_write;
++	am->mii_bus->priv = am;
++	am->mii_bus->parent = &pdev->dev;
++	snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev));
++
++	for (i = 0; i < PHY_MAX_ADDR; i++)
++		am->phy_irq[i] = PHY_POLL;
++
++	memcpy(am->mii_bus->irq, am->phy_irq, sizeof(am->phy_irq));
++	am->dev = &pdev->dev;
++	platform_set_drvdata(pdev, am);
++
++	return of_mdiobus_register(am->mii_bus, pdev->dev.of_node);
++}
++
++static int ipq40xx_mdio_remove(struct platform_device *pdev)
++{
++	struct ipq40xx_mdio_data *am = platform_get_drvdata(pdev);
++
++	mdiobus_unregister(am->mii_bus);
++
++	return 0;
++}
++
++static const struct of_device_id ipq40xx_mdio_dt_ids[] = {
++	{ .compatible = "qcom,ipq4019-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);
++
++#define DRV_VERSION     "1.0"
++
++MODULE_DESCRIPTION("IPQ40XX MDIO interface driver");
++MODULE_AUTHOR("Qualcomm Atheros");
++MODULE_VERSION(DRV_VERSION);
++MODULE_LICENSE("Dual BSD/GPL");

+ 4 - 235
target/linux/ipq40xx/patches-4.19/700-net-add-qualcomm-mdio-and-phy.patch → target/linux/ipq40xx/patches-4.19/705-net-add-qualcomm-ar40xx-phy.patch

@@ -1,26 +1,9 @@
-From 5a71a2005a2e1e6bbe36f00386c495ad6626beb2 Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <[email protected]>
-Date: Thu, 19 Jan 2017 01:59:43 +0100
-Subject: [PATCH 30/38] NET: add qualcomm mdio and PHY
-
----
- drivers/net/phy/Kconfig  | 14 ++++++++++++++
- drivers/net/phy/Makefile |  2 ++
- 2 files changed, 16 insertions(+)
-
 --- a/drivers/net/phy/Kconfig
 +++ b/drivers/net/phy/Kconfig
-@@ -519,6 +519,20 @@ config XILINX_GMII2RGMII
- 	  the Reduced Gigabit Media Independent Interface(RGMII) between
- 	  Ethernet physical media devices and the Gigabit Ethernet controller.
+@@ -526,6 +526,13 @@ config MDIO_IPQ40XX
+ 	  This driver supports the MDIO interface found in Qualcomm
+ 	  Atheros ipq40xx Soc chip.
  
-+config MDIO_IPQ40XX
-+	tristate "Qualcomm Atheros ipq40xx MDIO interface"
-+	depends on HAS_IOMEM && OF
-+	---help---
-+	  This driver supports the MDIO interface found in Qualcomm
-+	  Atheros ipq40xx Soc chip.
-+
 +config AR40XX_PHY
 +	tristate "Driver for Qualcomm Atheros IPQ40XX switches"
 +	depends on HAS_IOMEM && OF
@@ -33,15 +16,7 @@ Subject: [PATCH 30/38] NET: add qualcomm mdio and PHY
  config MICREL_KS8995MA
 --- a/drivers/net/phy/Makefile
 +++ b/drivers/net/phy/Makefile
-@@ -48,6 +48,7 @@ obj-$(CONFIG_MDIO_CAVIUM)	+= mdio-cavium
- 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_MOXART)	+= mdio-moxart.o
- obj-$(CONFIG_MDIO_MSCC_MIIM)	+= mdio-mscc-miim.o
- obj-$(CONFIG_MDIO_OCTEON)	+= mdio-octeon.o
-@@ -61,6 +62,7 @@ obj-y				+= $(sfp-obj-y) $(sfp-obj-m)
+@@ -62,6 +62,7 @@ obj-y				+= $(sfp-obj-y) $(sfp-obj-m)
  
  obj-$(CONFIG_AMD_PHY)		+= amd.o
  obj-$(CONFIG_AQUANTIA_PHY)	+= aquantia.o
@@ -2482,209 +2457,3 @@ Subject: [PATCH 30/38] NET: add qualcomm mdio and PHY
 +}
 +
 +#endif
---- /dev/null
-+++ b/drivers/net/phy/mdio-ipq40xx.c
-@@ -0,0 +1,203 @@
-+/*
-+ * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for
-+ * any purpose with or without fee is hereby granted, provided that the
-+ * above copyright notice and this permission notice appear in all copies.
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ */
-+
-+#include <linux/delay.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/mutex.h>
-+#include <linux/io.h>
-+#include <linux/of_address.h>
-+#include <linux/of_mdio.h>
-+#include <linux/phy.h>
-+#include <linux/platform_device.h>
-+
-+#define MDIO_CTRL_0_REG		0x40
-+#define MDIO_CTRL_1_REG		0x44
-+#define MDIO_CTRL_2_REG		0x48
-+#define MDIO_CTRL_3_REG		0x4c
-+#define MDIO_CTRL_4_REG		0x50
-+#define MDIO_CTRL_4_ACCESS_BUSY		BIT(16)
-+#define MDIO_CTRL_4_ACCESS_START		BIT(8)
-+#define MDIO_CTRL_4_ACCESS_CODE_READ		0
-+#define MDIO_CTRL_4_ACCESS_CODE_WRITE	1
-+#define CTRL_0_REG_DEFAULT_VALUE	0x150FF
-+
-+#define IPQ40XX_MDIO_RETRY	1000
-+#define IPQ40XX_MDIO_DELAY	10
-+
-+struct ipq40xx_mdio_data {
-+	struct mii_bus	*mii_bus;
-+	void __iomem	*membase;
-+	int		phy_irq[PHY_MAX_ADDR];
-+	struct device	*dev;
-+};
-+
-+static int ipq40xx_mdio_wait_busy(struct ipq40xx_mdio_data *am)
-+{
-+	int i;
-+
-+	for (i = 0; i < IPQ40XX_MDIO_RETRY; i++) {
-+		unsigned int busy;
-+
-+		busy = readl(am->membase + MDIO_CTRL_4_REG) &
-+			MDIO_CTRL_4_ACCESS_BUSY;
-+		if (!busy)
-+			return 0;
-+
-+		/* BUSY might take to be cleard by 15~20 times of loop */
-+		udelay(IPQ40XX_MDIO_DELAY);
-+	}
-+
-+	dev_err(am->dev, "%s: MDIO operation timed out\n", am->mii_bus->name);
-+
-+	return -ETIMEDOUT;
-+}
-+
-+static int ipq40xx_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
-+{
-+	struct ipq40xx_mdio_data *am = bus->priv;
-+	int value = 0;
-+	unsigned int cmd = 0;
-+
-+	lockdep_assert_held(&bus->mdio_lock);
-+
-+	if (ipq40xx_mdio_wait_busy(am))
-+		return -ETIMEDOUT;
-+
-+	/* issue the phy address and reg */
-+	writel((mii_id << 8) | regnum, am->membase + MDIO_CTRL_1_REG);
-+
-+	cmd = MDIO_CTRL_4_ACCESS_START|MDIO_CTRL_4_ACCESS_CODE_READ;
-+
-+	/* issue read command */
-+	writel(cmd, am->membase + MDIO_CTRL_4_REG);
-+
-+	/* Wait read complete */
-+	if (ipq40xx_mdio_wait_busy(am))
-+		return -ETIMEDOUT;
-+
-+	/* Read data */
-+	value = readl(am->membase + MDIO_CTRL_3_REG);
-+
-+	return value;
-+}
-+
-+static int ipq40xx_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
-+			    u16 value)
-+{
-+	struct ipq40xx_mdio_data *am = bus->priv;
-+	unsigned int cmd = 0;
-+
-+	lockdep_assert_held(&bus->mdio_lock);
-+
-+	if (ipq40xx_mdio_wait_busy(am))
-+		return -ETIMEDOUT;
-+
-+	/* issue the phy address and reg */
-+	writel((mii_id << 8) | regnum, am->membase + MDIO_CTRL_1_REG);
-+
-+	/* issue write data */
-+	writel(value, am->membase + MDIO_CTRL_2_REG);
-+
-+	cmd = MDIO_CTRL_4_ACCESS_START|MDIO_CTRL_4_ACCESS_CODE_WRITE;
-+	/* issue write command */
-+	writel(cmd, am->membase + MDIO_CTRL_4_REG);
-+
-+	/* Wait write complete */
-+	if (ipq40xx_mdio_wait_busy(am))
-+		return -ETIMEDOUT;
-+
-+	return 0;
-+}
-+
-+static int ipq40xx_mdio_probe(struct platform_device *pdev)
-+{
-+	struct ipq40xx_mdio_data *am;
-+	struct resource *res;
-+	int i;
-+
-+	am = devm_kzalloc(&pdev->dev, sizeof(*am), GFP_KERNEL);
-+	if (!am)
-+		return -ENOMEM;
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	if (!res) {
-+		dev_err(&pdev->dev, "no iomem resource found\n");
-+		return -ENXIO;
-+	}
-+
-+	am->membase = devm_ioremap_resource(&pdev->dev, res);
-+	if (IS_ERR(am->membase)) {
-+		dev_err(&pdev->dev, "unable to ioremap registers\n");
-+		return PTR_ERR(am->membase);
-+	}
-+
-+	am->mii_bus = devm_mdiobus_alloc(&pdev->dev);
-+	if (!am->mii_bus)
-+		return  -ENOMEM;
-+
-+	writel(CTRL_0_REG_DEFAULT_VALUE, am->membase + MDIO_CTRL_0_REG);
-+
-+	am->mii_bus->name = "ipq40xx_mdio";
-+	am->mii_bus->read = ipq40xx_mdio_read;
-+	am->mii_bus->write = ipq40xx_mdio_write;
-+	am->mii_bus->priv = am;
-+	am->mii_bus->parent = &pdev->dev;
-+	snprintf(am->mii_bus->id, MII_BUS_ID_SIZE, "%s", dev_name(&pdev->dev));
-+
-+	for (i = 0; i < PHY_MAX_ADDR; i++)
-+		am->phy_irq[i] = PHY_POLL;
-+
-+	memcpy(am->mii_bus->irq, am->phy_irq, sizeof(am->phy_irq));
-+	am->dev = &pdev->dev;
-+	platform_set_drvdata(pdev, am);
-+
-+	/* edma_axi_probe() use "am" drvdata.
-+	 * ipq40xx_mdio_probe() must be called first.
-+	 */
-+	return of_mdiobus_register(am->mii_bus, pdev->dev.of_node);
-+}
-+
-+static int ipq40xx_mdio_remove(struct platform_device *pdev)
-+{
-+	struct ipq40xx_mdio_data *am = platform_get_drvdata(pdev);
-+
-+	mdiobus_unregister(am->mii_bus);
-+	return 0;
-+}
-+
-+static const struct of_device_id ipq40xx_mdio_dt_ids[] = {
-+	{ .compatible = "qcom,ipq4019-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);
-+
-+#define DRV_VERSION     "1.0"
-+
-+MODULE_DESCRIPTION("IPQ40XX MDIO interface driver");
-+MODULE_AUTHOR("Qualcomm Atheros");
-+MODULE_VERSION(DRV_VERSION);
-+MODULE_LICENSE("Dual BSD/GPL");