netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support.
@ 2012-05-03  1:16 David Daney
  2012-05-03  1:16 ` [PATCH v6 1/3] netdev/of/phy: New function: of_mdio_find_bus() David Daney
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: David Daney @ 2012-05-03  1:16 UTC (permalink / raw)
  To: Ralf Baechle, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, David S. Miller,
	netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA,
	afleming-Re5JQEeQqe8AvxtiuMwx3w, David Daney,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: David Daney <david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>

This code has been working well for about six months on a couple of
different configurations (boards), so I thought it would be a good
time to send it out again, and I hope get it on the path towards
merging.

v6: Correct Kconfig depends in 2/3 as noticed by David Miller.  Test
    against net-next.

v5: Correct Kconfig depends in 3/3 as noticed by David Miller.

v4: Correct some comment text and rename a couple of variables to
    better reflect their purpose.

v3: Update binding to use "mdio-mux-gpio" compatible property.
    Cleanups suggested by Grant Likely.  Now uses the driver probe
    deferral mechanism if GPIOs or parent bus not available.

v2: Update bindings to use "reg" and "mdio-parent-bus" instead of
    "cell-index" and "parent-bus"

v1:

We have several different boards with a multiplexer in the MDIO bus.
There is an MDIO bus controller connected to a switching device with
several child MDIO busses.

Everything is wired up using device tree bindings.

 1/3 - New of_mdio_find_bus() function used to help configuring the
       driver topology.

 2/3 - MDIO bus multiplexer framework.

 3/3 - A driver for a GPIO controlled multiplexer.

David Daney (3):
  netdev/of/phy: New function: of_mdio_find_bus().
  netdev/of/phy: Add MDIO bus multiplexer support.
  netdev/of/phy: Add MDIO bus multiplexer driven by GPIO lines.

 .../devicetree/bindings/net/mdio-mux-gpio.txt      |  127 +++++++++++++
 Documentation/devicetree/bindings/net/mdio-mux.txt |  136 ++++++++++++++
 drivers/net/phy/Kconfig                            |   19 ++
 drivers/net/phy/Makefile                           |    2 +
 drivers/net/phy/mdio-mux-gpio.c                    |  142 +++++++++++++++
 drivers/net/phy/mdio-mux.c                         |  192 ++++++++++++++++++++
 drivers/net/phy/mdio_bus.c                         |   32 ++++
 drivers/of/of_mdio.c                               |    2 +
 include/linux/mdio-mux.h                           |   21 ++
 include/linux/of_mdio.h                            |    2 +
 10 files changed, 675 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/mdio-mux-gpio.txt
 create mode 100644 Documentation/devicetree/bindings/net/mdio-mux.txt
 create mode 100644 drivers/net/phy/mdio-mux-gpio.c
 create mode 100644 drivers/net/phy/mdio-mux.c
 create mode 100644 include/linux/mdio-mux.h

-- 
1.7.2.3

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v6 1/3] netdev/of/phy: New function: of_mdio_find_bus().
  2012-05-03  1:16 [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support David Daney
@ 2012-05-03  1:16 ` David Daney
  2012-05-08  2:58   ` David Miller
  2012-05-03  1:16 ` [PATCH v6 2/3] netdev/of/phy: Add MDIO bus multiplexer support David Daney
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 15+ messages in thread
From: David Daney @ 2012-05-03  1:16 UTC (permalink / raw)
  To: Ralf Baechle, Grant Likely, Rob Herring, devicetree-discuss,
	David S. Miller, netdev
  Cc: linux-kernel, linux-mips, afleming, galak, David Daney,
	Grant Likely, David S. Miller

From: David Daney <david.daney@cavium.com>

Add of_mdio_find_bus() which allows an mii_bus to be located given its
associated the device tree node.

This is needed by the follow-on patch to add a driver for MDIO bus
multiplexers.

The of_mdiobus_register() function is modified so that the device tree
node is recorded in the mii_bus.  Then we can find it again by
iterating over all mdio_bus_class devices.

Because the OF device tree has now become an integral part of the
kernel, this can live in mdio_bus.c (which contains the needed
mdio_bus_class structure) instead of of_mdio.c.

Signed-off-by: David Daney <david.daney@cavium.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: "David S. Miller" <davem@davemloft.net>
---
 drivers/net/phy/mdio_bus.c |   32 ++++++++++++++++++++++++++++++++
 drivers/of/of_mdio.c       |    2 ++
 include/linux/of_mdio.h    |    2 ++
 3 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 8985cc6..83d5c9f 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -88,6 +88,38 @@ static struct class mdio_bus_class = {
 	.dev_release	= mdiobus_release,
 };
 
+#ifdef CONFIG_OF_MDIO
+/* Helper function for of_mdio_find_bus */
+static int of_mdio_bus_match(struct device *dev, void *mdio_bus_np)
+{
+	return dev->of_node == mdio_bus_np;
+}
+/**
+ * of_mdio_find_bus - Given an mii_bus node, find the mii_bus.
+ * @mdio_np: Pointer to the mii_bus.
+ *
+ * Returns a pointer to the mii_bus, or NULL if none found.
+ *
+ * Because the association of a device_node and mii_bus is made via
+ * of_mdiobus_register(), the mii_bus cannot be found before it is
+ * registered with of_mdiobus_register().
+ *
+ */
+struct mii_bus *of_mdio_find_bus(struct device_node *mdio_bus_np)
+{
+	struct device *d;
+
+	if (!mdio_bus_np)
+		return NULL;
+
+	d = class_find_device(&mdio_bus_class, NULL,  mdio_bus_np,
+			      of_mdio_bus_match);
+
+	return d ? to_mii_bus(d) : NULL;
+}
+EXPORT_SYMBOL(of_mdio_find_bus);
+#endif
+
 /**
  * mdiobus_register - bring up all the PHYs on a given bus and attach them to bus
  * @bus: target mii_bus
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index 483c0ad..2574abd 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -45,6 +45,8 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
 		for (i=0; i<PHY_MAX_ADDR; i++)
 			mdio->irq[i] = PHY_POLL;
 
+	mdio->dev.of_node = np;
+
 	/* Register the MDIO bus */
 	rc = mdiobus_register(mdio);
 	if (rc)
diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h
index 53b94e0..912c27a 100644
--- a/include/linux/of_mdio.h
+++ b/include/linux/of_mdio.h
@@ -22,4 +22,6 @@ extern struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
 					 void (*hndlr)(struct net_device *),
 					 phy_interface_t iface);
 
+extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np);
+
 #endif /* __LINUX_OF_MDIO_H */
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v6 2/3] netdev/of/phy: Add MDIO bus multiplexer support.
  2012-05-03  1:16 [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support David Daney
  2012-05-03  1:16 ` [PATCH v6 1/3] netdev/of/phy: New function: of_mdio_find_bus() David Daney
@ 2012-05-03  1:16 ` David Daney
  2012-05-08  2:58   ` David Miller
       [not found] ` <1336007799-31016-1-git-send-email-ddaney.cavm-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2012-05-18 21:42 ` [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support Tabi Timur-B04825
  3 siblings, 1 reply; 15+ messages in thread
From: David Daney @ 2012-05-03  1:16 UTC (permalink / raw)
  To: Ralf Baechle, Grant Likely, Rob Herring, devicetree-discuss,
	David S. Miller, netdev
  Cc: linux-kernel, linux-mips, afleming, galak, David Daney

From: David Daney <david.daney@cavium.com>

This patch adds a somewhat generic framework for MDIO bus
multiplexers.  It is modeled on the I2C multiplexer.

The multiplexer is needed if there are multiple PHYs with the same
address connected to the same MDIO bus adepter, or if there is
insufficient electrical drive capability for all the connected PHY
devices.

Conceptually it could look something like this:

                   ------------------
                   | Control Signal |
                   --------+---------
                           |
 ---------------   --------+------
 | MDIO MASTER |---| Multiplexer |
 ---------------   --+-------+----
                     |       |
                     C       C
                     h       h
                     i       i
                     l       l
                     d       d
                     |       |
     ---------       A       B   ---------
     |       |       |       |   |       |
     | PHY@1 +-------+       +---+ PHY@1 |
     |       |       |       |   |       |
     ---------       |       |   ---------
     ---------       |       |   ---------
     |       |       |       |   |       |
     | PHY@2 +-------+       +---+ PHY@2 |
     |       |                   |       |
     ---------                   ---------

This framework configures the bus topology from device tree data.  The
mechanics of switching the multiplexer is left to device specific
drivers.

The follow-on patch contains a multiplexer driven by GPIO lines.

Signed-off-by: David Daney <david.daney@cavium.com>
---
 Documentation/devicetree/bindings/net/mdio-mux.txt |  136 ++++++++++++++
 drivers/net/phy/Kconfig                            |    9 +
 drivers/net/phy/Makefile                           |    1 +
 drivers/net/phy/mdio-mux.c                         |  192 ++++++++++++++++++++
 include/linux/mdio-mux.h                           |   21 ++
 5 files changed, 359 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/mdio-mux.txt
 create mode 100644 drivers/net/phy/mdio-mux.c
 create mode 100644 include/linux/mdio-mux.h

diff --git a/Documentation/devicetree/bindings/net/mdio-mux.txt b/Documentation/devicetree/bindings/net/mdio-mux.txt
new file mode 100644
index 0000000..f65606f
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/mdio-mux.txt
@@ -0,0 +1,136 @@
+Common MDIO bus multiplexer/switch properties.
+
+An MDIO bus multiplexer/switch will have several child busses that are
+numbered uniquely in a device dependent manner.  The nodes for an MDIO
+bus multiplexer/switch will have one child node for each child bus.
+
+Required properties:
+- mdio-parent-bus : phandle to the parent MDIO bus.
+- #address-cells = <1>;
+- #size-cells = <0>;
+
+Optional properties:
+- Other properties specific to the multiplexer/switch hardware.
+
+Required properties for child nodes:
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg : The sub-bus number.
+
+
+Example :
+
+	/* The parent MDIO bus. */
+	smi1: mdio@1180000001900 {
+		compatible = "cavium,octeon-3860-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x11800 0x00001900 0x0 0x40>;
+	};
+
+	/*
+	   An NXP sn74cbtlv3253 dual 1-of-4 switch controlled by a
+	   pair of GPIO lines.  Child busses 2 and 3 populated with 4
+	   PHYs each.
+	 */
+	mdio-mux {
+		compatible = "mdio-mux-gpio";
+		gpios = <&gpio1 3 0>, <&gpio1 4 0>;
+		mdio-parent-bus = <&smi1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		mdio@2 {
+			reg = <2>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			phy11: ethernet-phy@1 {
+				reg = <1>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <10 8>; /* Pin 10, active low */
+			};
+			phy12: ethernet-phy@2 {
+				reg = <2>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <10 8>; /* Pin 10, active low */
+			};
+			phy13: ethernet-phy@3 {
+				reg = <3>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <10 8>; /* Pin 10, active low */
+			};
+			phy14: ethernet-phy@4 {
+				reg = <4>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <10 8>; /* Pin 10, active low */
+			};
+		};
+
+		mdio@3 {
+			reg = <3>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			phy21: ethernet-phy@1 {
+				reg = <1>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <12 8>; /* Pin 12, active low */
+			};
+			phy22: ethernet-phy@2 {
+				reg = <2>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <12 8>; /* Pin 12, active low */
+			};
+			phy23: ethernet-phy@3 {
+				reg = <3>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <12 8>; /* Pin 12, active low */
+			};
+			phy24: ethernet-phy@4 {
+				reg = <4>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <12 8>; /* Pin 12, active low */
+			};
+		};
+	};
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 0e01f4e..99c0674a 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -135,6 +135,15 @@ config MDIO_OCTEON
 
 	  If in doubt, say Y.
 
+config MDIO_BUS_MUX
+	tristate
+	depends on OF_MDIO
+	help
+	  This module provides a driver framework for MDIO bus
+	  multiplexers which connect one of several child MDIO busses
+	  to a parent bus.  Switching between child busses is done by
+	  device specific drivers.
+
 endif # PHYLIB
 
 config MICREL_KS8995MA
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index b7438b1..a6b50e7 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -25,3 +25,4 @@ obj-$(CONFIG_MICREL_PHY)	+= micrel.o
 obj-$(CONFIG_MDIO_OCTEON)	+= mdio-octeon.o
 obj-$(CONFIG_MICREL_KS8995MA)	+= spi_ks8995.o
 obj-$(CONFIG_AMD_PHY)		+= amd.o
+obj-$(CONFIG_MDIO_BUS_MUX)	+= mdio-mux.o
diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c
new file mode 100644
index 0000000..39ea067
--- /dev/null
+++ b/drivers/net/phy/mdio-mux.c
@@ -0,0 +1,192 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2011, 2012 Cavium, Inc.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/mdio-mux.h>
+#include <linux/of_mdio.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+
+#define DRV_VERSION "1.0"
+#define DRV_DESCRIPTION "MDIO bus multiplexer driver"
+
+struct mdio_mux_child_bus;
+
+struct mdio_mux_parent_bus {
+	struct mii_bus *mii_bus;
+	int current_child;
+	int parent_id;
+	void *switch_data;
+	int (*switch_fn)(int current_child, int desired_child, void *data);
+
+	/* List of our children linked through their next fields. */
+	struct mdio_mux_child_bus *children;
+};
+
+struct mdio_mux_child_bus {
+	struct mii_bus *mii_bus;
+	struct mdio_mux_parent_bus *parent;
+	struct mdio_mux_child_bus *next;
+	int bus_number;
+	int phy_irq[PHY_MAX_ADDR];
+};
+
+/*
+ * The parent bus' lock is used to order access to the switch_fn.
+ */
+static int mdio_mux_read(struct mii_bus *bus, int phy_id, int regnum)
+{
+	struct mdio_mux_child_bus *cb = bus->priv;
+	struct mdio_mux_parent_bus *pb = cb->parent;
+	int r;
+
+	mutex_lock(&pb->mii_bus->mdio_lock);
+	r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data);
+	if (r)
+		goto out;
+
+	pb->current_child = cb->bus_number;
+
+	r = pb->mii_bus->read(pb->mii_bus, phy_id, regnum);
+out:
+	mutex_unlock(&pb->mii_bus->mdio_lock);
+
+	return r;
+}
+
+/*
+ * The parent bus' lock is used to order access to the switch_fn.
+ */
+static int mdio_mux_write(struct mii_bus *bus, int phy_id,
+			  int regnum, u16 val)
+{
+	struct mdio_mux_child_bus *cb = bus->priv;
+	struct mdio_mux_parent_bus *pb = cb->parent;
+
+	int r;
+
+	mutex_lock(&pb->mii_bus->mdio_lock);
+	r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data);
+	if (r)
+		goto out;
+
+	pb->current_child = cb->bus_number;
+
+	r = pb->mii_bus->write(pb->mii_bus, phy_id, regnum, val);
+out:
+	mutex_unlock(&pb->mii_bus->mdio_lock);
+
+	return r;
+}
+
+static int parent_count;
+
+int mdio_mux_init(struct device *dev,
+		  int (*switch_fn)(int cur, int desired, void *data),
+		  void **mux_handle,
+		  void *data)
+{
+	struct device_node *parent_bus_node;
+	struct device_node *child_bus_node;
+	int r, ret_val;
+	struct mii_bus *parent_bus;
+	struct mdio_mux_parent_bus *pb;
+	struct mdio_mux_child_bus *cb;
+
+	if (!dev->of_node)
+		return -ENODEV;
+
+	parent_bus_node = of_parse_phandle(dev->of_node, "mdio-parent-bus", 0);
+
+	if (!parent_bus_node)
+		return -ENODEV;
+
+	parent_bus = of_mdio_find_bus(parent_bus_node);
+	if (parent_bus == NULL) {
+		ret_val = -EPROBE_DEFER;
+		goto err_parent_bus;
+	}
+
+	pb = devm_kzalloc(dev, sizeof(*pb), GFP_KERNEL);
+	if (pb == NULL) {
+		ret_val = -ENOMEM;
+		goto err_parent_bus;
+	}
+
+	pb->switch_data = data;
+	pb->switch_fn = switch_fn;
+	pb->current_child = -1;
+	pb->parent_id = parent_count++;
+	pb->mii_bus = parent_bus;
+
+	ret_val = -ENODEV;
+	for_each_child_of_node(dev->of_node, child_bus_node) {
+		u32 v;
+
+		r = of_property_read_u32(child_bus_node, "reg", &v);
+		if (r)
+			continue;
+
+		cb = devm_kzalloc(dev, sizeof(*cb), GFP_KERNEL);
+		if (cb == NULL) {
+			dev_err(dev,
+				"Error: Failed to allocate memory for child\n");
+			ret_val = -ENOMEM;
+			break;
+		}
+		cb->bus_number = v;
+		cb->parent = pb;
+		cb->mii_bus = mdiobus_alloc();
+		cb->mii_bus->priv = cb;
+
+		cb->mii_bus->irq = cb->phy_irq;
+		cb->mii_bus->name = "mdio_mux";
+		snprintf(cb->mii_bus->id, MII_BUS_ID_SIZE, "%x.%x",
+			 pb->parent_id, v);
+		cb->mii_bus->parent = dev;
+		cb->mii_bus->read = mdio_mux_read;
+		cb->mii_bus->write = mdio_mux_write;
+		r = of_mdiobus_register(cb->mii_bus, child_bus_node);
+		if (r) {
+			mdiobus_free(cb->mii_bus);
+			devm_kfree(dev, cb);
+		} else {
+			of_node_get(child_bus_node);
+			cb->next = pb->children;
+			pb->children = cb;
+		}
+	}
+	if (pb->children) {
+		*mux_handle = pb;
+		dev_info(dev, "Version " DRV_VERSION "\n");
+		return 0;
+	}
+err_parent_bus:
+	of_node_put(parent_bus_node);
+	return ret_val;
+}
+EXPORT_SYMBOL_GPL(mdio_mux_init);
+
+void mdio_mux_uninit(void *mux_handle)
+{
+	struct mdio_mux_parent_bus *pb = mux_handle;
+	struct mdio_mux_child_bus *cb = pb->children;
+
+	while (cb) {
+		mdiobus_unregister(cb->mii_bus);
+		mdiobus_free(cb->mii_bus);
+		cb = cb->next;
+	}
+}
+EXPORT_SYMBOL_GPL(mdio_mux_uninit);
+
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR("David Daney");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mdio-mux.h b/include/linux/mdio-mux.h
new file mode 100644
index 0000000..a243dbb
--- /dev/null
+++ b/include/linux/mdio-mux.h
@@ -0,0 +1,21 @@
+/*
+ * MDIO bus multiplexer framwork.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2011, 2012 Cavium, Inc.
+ */
+#ifndef __LINUX_MDIO_MUX_H
+#define __LINUX_MDIO_MUX_H
+#include <linux/device.h>
+
+int mdio_mux_init(struct device *dev,
+		  int (*switch_fn) (int cur, int desired, void *data),
+		  void **mux_handle,
+		  void *data);
+
+void mdio_mux_uninit(void *mux_handle);
+
+#endif /* __LINUX_MDIO_MUX_H */
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v6 3/3] netdev/of/phy: Add MDIO bus multiplexer driven by GPIO lines.
       [not found] ` <1336007799-31016-1-git-send-email-ddaney.cavm-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2012-05-03  1:16   ` David Daney
  2012-05-08  2:59     ` David Miller
  0 siblings, 1 reply; 15+ messages in thread
From: David Daney @ 2012-05-03  1:16 UTC (permalink / raw)
  To: Ralf Baechle, Grant Likely, Rob Herring,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, David S. Miller,
	netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA,
	afleming-Re5JQEeQqe8AvxtiuMwx3w, David Daney,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: David Daney <david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>

The GPIO pins select which sub bus is connected to the master.

Initially tested with an sn74cbtlv3253 switch device wired into the
MDIO bus.

Signed-off-by: David Daney <david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
---
 .../devicetree/bindings/net/mdio-mux-gpio.txt      |  127 +++++++++++++++++
 drivers/net/phy/Kconfig                            |   10 ++
 drivers/net/phy/Makefile                           |    1 +
 drivers/net/phy/mdio-mux-gpio.c                    |  142 ++++++++++++++++++++
 4 files changed, 280 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/mdio-mux-gpio.txt
 create mode 100644 drivers/net/phy/mdio-mux-gpio.c

diff --git a/Documentation/devicetree/bindings/net/mdio-mux-gpio.txt b/Documentation/devicetree/bindings/net/mdio-mux-gpio.txt
new file mode 100644
index 0000000..7938411
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/mdio-mux-gpio.txt
@@ -0,0 +1,127 @@
+Properties for an MDIO bus multiplexer/switch controlled by GPIO pins.
+
+This is a special case of a MDIO bus multiplexer.  One or more GPIO
+lines are used to control which child bus is connected.
+
+Required properties in addition to the generic multiplexer properties:
+
+- compatible : mdio-mux-gpio.
+- gpios : GPIO specifiers for each GPIO line.  One or more must be specified.
+
+
+Example :
+
+	/* The parent MDIO bus. */
+	smi1: mdio@1180000001900 {
+		compatible = "cavium,octeon-3860-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x11800 0x00001900 0x0 0x40>;
+	};
+
+	/*
+	   An NXP sn74cbtlv3253 dual 1-of-4 switch controlled by a
+	   pair of GPIO lines.  Child busses 2 and 3 populated with 4
+	   PHYs each.
+	 */
+	mdio-mux {
+		compatible = "mdio-mux-gpio";
+		gpios = <&gpio1 3 0>, <&gpio1 4 0>;
+		mdio-parent-bus = <&smi1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		mdio@2 {
+			reg = <2>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			phy11: ethernet-phy@1 {
+				reg = <1>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <10 8>; /* Pin 10, active low */
+			};
+			phy12: ethernet-phy@2 {
+				reg = <2>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <10 8>; /* Pin 10, active low */
+			};
+			phy13: ethernet-phy@3 {
+				reg = <3>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <10 8>; /* Pin 10, active low */
+			};
+			phy14: ethernet-phy@4 {
+				reg = <4>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <10 8>; /* Pin 10, active low */
+			};
+		};
+
+		mdio@3 {
+			reg = <3>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			phy21: ethernet-phy@1 {
+				reg = <1>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <12 8>; /* Pin 12, active low */
+			};
+			phy22: ethernet-phy@2 {
+				reg = <2>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <12 8>; /* Pin 12, active low */
+			};
+			phy23: ethernet-phy@3 {
+				reg = <3>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <12 8>; /* Pin 12, active low */
+			};
+			phy24: ethernet-phy@4 {
+				reg = <4>;
+				compatible = "marvell,88e1149r";
+				marvell,reg-init = <3 0x10 0 0x5777>,
+					<3 0x11 0 0x00aa>,
+					<3 0x12 0 0x4105>,
+					<3 0x13 0 0x0a60>;
+				interrupt-parent = <&gpio>;
+				interrupts = <12 8>; /* Pin 12, active low */
+			};
+		};
+	};
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 99c0674a..944cdfb 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -144,6 +144,16 @@ config MDIO_BUS_MUX
 	  to a parent bus.  Switching between child busses is done by
 	  device specific drivers.
 
+config MDIO_BUS_MUX_GPIO
+	tristate "Support for GPIO controlled MDIO bus multiplexers"
+	depends on OF_GPIO && OF_MDIO
+	select MDIO_BUS_MUX
+	help
+	  This module provides a driver for MDIO bus multiplexers that
+	  are controlled via GPIO lines.  The multiplexer connects one of
+	  several child MDIO busses to a parent bus.  Child bus
+	  selection is under the control of GPIO lines.
+
 endif # PHYLIB
 
 config MICREL_KS8995MA
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index a6b50e7..f51af68 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_MDIO_OCTEON)	+= mdio-octeon.o
 obj-$(CONFIG_MICREL_KS8995MA)	+= spi_ks8995.o
 obj-$(CONFIG_AMD_PHY)		+= amd.o
 obj-$(CONFIG_MDIO_BUS_MUX)	+= mdio-mux.o
+obj-$(CONFIG_MDIO_BUS_MUX_GPIO)	+= mdio-mux-gpio.o
diff --git a/drivers/net/phy/mdio-mux-gpio.c b/drivers/net/phy/mdio-mux-gpio.c
new file mode 100644
index 0000000..e0cc4ef
--- /dev/null
+++ b/drivers/net/phy/mdio-mux-gpio.c
@@ -0,0 +1,142 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2011, 2012 Cavium, Inc.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/of_mdio.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/phy.h>
+#include <linux/mdio-mux.h>
+#include <linux/of_gpio.h>
+
+#define DRV_VERSION "1.0"
+#define DRV_DESCRIPTION "GPIO controlled MDIO bus multiplexer driver"
+
+#define MDIO_MUX_GPIO_MAX_BITS 8
+
+struct mdio_mux_gpio_state {
+	int gpio[MDIO_MUX_GPIO_MAX_BITS];
+	unsigned int num_gpios;
+	void *mux_handle;
+};
+
+static int mdio_mux_gpio_switch_fn(int current_child, int desired_child,
+				   void *data)
+{
+	int change;
+	unsigned int n;
+	struct mdio_mux_gpio_state *s = data;
+
+	if (current_child == desired_child)
+		return 0;
+
+	change = current_child == -1 ? -1 : current_child ^ desired_child;
+
+	for (n = 0; n < s->num_gpios; n++) {
+		if (change & 1)
+			gpio_set_value_cansleep(s->gpio[n],
+						(desired_child & 1) != 0);
+		change >>= 1;
+		desired_child >>= 1;
+	}
+
+	return 0;
+}
+
+static int __devinit mdio_mux_gpio_probe(struct platform_device *pdev)
+{
+	enum of_gpio_flags f;
+	struct mdio_mux_gpio_state *s;
+	unsigned int num_gpios;
+	unsigned int n;
+	int r;
+
+	if (!pdev->dev.of_node)
+		return -ENODEV;
+
+	num_gpios = of_gpio_count(pdev->dev.of_node);
+	if (num_gpios == 0 || num_gpios > MDIO_MUX_GPIO_MAX_BITS)
+		return -ENODEV;
+
+	s = devm_kzalloc(&pdev->dev, sizeof(*s), GFP_KERNEL);
+	if (!s)
+		return -ENOMEM;
+
+	s->num_gpios = num_gpios;
+
+	for (n = 0; n < num_gpios; ) {
+		int gpio = of_get_gpio_flags(pdev->dev.of_node, n, &f);
+		if (gpio < 0) {
+			r = (gpio == -ENODEV) ? -EPROBE_DEFER : gpio;
+			goto err;
+		}
+		s->gpio[n] = gpio;
+
+		n++;
+
+		r = gpio_request(gpio, "mdio_mux_gpio");
+		if (r)
+			goto err;
+
+		r = gpio_direction_output(gpio, 0);
+		if (r)
+			goto err;
+	}
+
+	r = mdio_mux_init(&pdev->dev,
+			  mdio_mux_gpio_switch_fn, &s->mux_handle, s);
+
+	if (r == 0) {
+		pdev->dev.platform_data = s;
+		return 0;
+	}
+err:
+	while (n) {
+		n--;
+		gpio_free(s->gpio[n]);
+	}
+	devm_kfree(&pdev->dev, s);
+	return r;
+}
+
+static int __devexit mdio_mux_gpio_remove(struct platform_device *pdev)
+{
+	struct mdio_mux_gpio_state *s = pdev->dev.platform_data;
+	mdio_mux_uninit(s->mux_handle);
+	return 0;
+}
+
+static struct of_device_id mdio_mux_gpio_match[] = {
+	{
+		.compatible = "mdio-mux-gpio",
+	},
+	{
+		/* Legacy compatible property. */
+		.compatible = "cavium,mdio-mux-sn74cbtlv3253",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, mdio_mux_gpio_match);
+
+static struct platform_driver mdio_mux_gpio_driver = {
+	.driver = {
+		.name		= "mdio-mux-gpio",
+		.owner		= THIS_MODULE,
+		.of_match_table = mdio_mux_gpio_match,
+	},
+	.probe		= mdio_mux_gpio_probe,
+	.remove		= __devexit_p(mdio_mux_gpio_remove),
+};
+
+module_platform_driver(mdio_mux_gpio_driver);
+
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR("David Daney");
+MODULE_LICENSE("GPL");
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v6 1/3] netdev/of/phy: New function: of_mdio_find_bus().
  2012-05-03  1:16 ` [PATCH v6 1/3] netdev/of/phy: New function: of_mdio_find_bus() David Daney
@ 2012-05-08  2:58   ` David Miller
  0 siblings, 0 replies; 15+ messages in thread
From: David Miller @ 2012-05-08  2:58 UTC (permalink / raw)
  To: ddaney.cavm
  Cc: ralf, grant.likely, rob.herring, devicetree-discuss, netdev,
	linux-kernel, linux-mips, afleming, galak, david.daney

From: David Daney <ddaney.cavm@gmail.com>
Date: Wed,  2 May 2012 18:16:37 -0700

> From: David Daney <david.daney@cavium.com>
> 
> Add of_mdio_find_bus() which allows an mii_bus to be located given its
> associated the device tree node.
> 
> This is needed by the follow-on patch to add a driver for MDIO bus
> multiplexers.
> 
> The of_mdiobus_register() function is modified so that the device tree
> node is recorded in the mii_bus.  Then we can find it again by
> iterating over all mdio_bus_class devices.
> 
> Because the OF device tree has now become an integral part of the
> kernel, this can live in mdio_bus.c (which contains the needed
> mdio_bus_class structure) instead of of_mdio.c.
> 
> Signed-off-by: David Daney <david.daney@cavium.com>

Applied.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v6 2/3] netdev/of/phy: Add MDIO bus multiplexer support.
  2012-05-03  1:16 ` [PATCH v6 2/3] netdev/of/phy: Add MDIO bus multiplexer support David Daney
@ 2012-05-08  2:58   ` David Miller
  0 siblings, 0 replies; 15+ messages in thread
From: David Miller @ 2012-05-08  2:58 UTC (permalink / raw)
  To: ddaney.cavm
  Cc: ralf, grant.likely, rob.herring, devicetree-discuss, netdev,
	linux-kernel, linux-mips, afleming, galak, david.daney

From: David Daney <ddaney.cavm@gmail.com>
Date: Wed,  2 May 2012 18:16:38 -0700

> From: David Daney <david.daney@cavium.com>
> 
> This patch adds a somewhat generic framework for MDIO bus
> multiplexers.  It is modeled on the I2C multiplexer.
> 
> The multiplexer is needed if there are multiple PHYs with the same
> address connected to the same MDIO bus adepter, or if there is
> insufficient electrical drive capability for all the connected PHY
> devices.
> 
> Conceptually it could look something like this:
 ...
> This framework configures the bus topology from device tree data.  The
> mechanics of switching the multiplexer is left to device specific
> drivers.
> 
> The follow-on patch contains a multiplexer driven by GPIO lines.
> 
> Signed-off-by: David Daney <david.daney@cavium.com>

Applied.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v6 3/3] netdev/of/phy: Add MDIO bus multiplexer driven by GPIO lines.
  2012-05-03  1:16   ` [PATCH v6 3/3] netdev/of/phy: Add MDIO bus multiplexer driven by GPIO lines David Daney
@ 2012-05-08  2:59     ` David Miller
  0 siblings, 0 replies; 15+ messages in thread
From: David Miller @ 2012-05-08  2:59 UTC (permalink / raw)
  To: ddaney.cavm
  Cc: ralf, grant.likely, rob.herring, devicetree-discuss, netdev,
	linux-kernel, linux-mips, afleming, galak, david.daney

From: David Daney <ddaney.cavm@gmail.com>
Date: Wed,  2 May 2012 18:16:39 -0700

> From: David Daney <david.daney@cavium.com>
> 
> The GPIO pins select which sub bus is connected to the master.
> 
> Initially tested with an sn74cbtlv3253 switch device wired into the
> MDIO bus.
> 
> Signed-off-by: David Daney <david.daney@cavium.com>

Applied.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support.
  2012-05-03  1:16 [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support David Daney
                   ` (2 preceding siblings ...)
       [not found] ` <1336007799-31016-1-git-send-email-ddaney.cavm-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2012-05-18 21:42 ` Tabi Timur-B04825
  2012-05-18 22:03   ` David Daney
  3 siblings, 1 reply; 15+ messages in thread
From: Tabi Timur-B04825 @ 2012-05-18 21:42 UTC (permalink / raw)
  To: David Daney; +Cc: devicetree-discuss, netdev, linuxppc-dev

On Wed, May 2, 2012 at 8:16 PM, David Daney <ddaney.cavm@gmail.com> wrote:
> From: David Daney <david.daney@cavium.com>
>
> This code has been working well for about six months on a couple of
> different configurations (boards), so I thought it would be a good
> time to send it out again, and I hope get it on the path towards
> merging.

David,

I'm trying to implement this feature on our boards, which don't use
GPIOs but rather a memory-mapped FPGA.  I control the mux by setting
some bits in one of the FPGA registers.

Do you have a real device tree I can use as an example?

I'm not sure what the "parent" MDIO bus node is supposed to represent.
 Is that that device that actually controls the muxing hardware, which
in our case would be the FPGA?

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support.
  2012-05-18 21:42 ` [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support Tabi Timur-B04825
@ 2012-05-18 22:03   ` David Daney
  2012-05-18 22:09     ` Timur Tabi
  0 siblings, 1 reply; 15+ messages in thread
From: David Daney @ 2012-05-18 22:03 UTC (permalink / raw)
  To: Tabi Timur-B04825; +Cc: devicetree-discuss, netdev, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 1511 bytes --]

On 05/18/2012 02:42 PM, Tabi Timur-B04825 wrote:
> On Wed, May 2, 2012 at 8:16 PM, David Daney<ddaney.cavm@gmail.com>  wrote:
>> From: David Daney<david.daney@cavium.com>
>>
>> This code has been working well for about six months on a couple of
>> different configurations (boards), so I thought it would be a good
>> time to send it out again, and I hope get it on the path towards
>> merging.
>
> David,
>
> I'm trying to implement this feature on our boards, which don't use
> GPIOs but rather a memory-mapped FPGA.  I control the mux by setting
> some bits in one of the FPGA registers.

You can either:

1) write a standard GPIO driver for the thing that controls the mux, and 
then use mdio-mux-gpio.c, or...

2) Write a new driver modeled on mdio-mux-gpio.c for your switch control.

>
> Do you have a real device tree I can use as an example?
>

Attached.

> I'm not sure what the "parent" MDIO bus node is supposed to represent.
>   Is that that device that actually controls the muxing hardware

No.  It is the device that implements the master 802.3 clause {22,45} 
MDIO Station Management (STA) protocol.

>, which in our case would be the FPGA?

I have no idea what your FPGA implements, so it is hard to say.

A sane person would implement a separate MDIO STA controller for each 
bus, in which case you wouldn't use the multiplexer driver.

Only people dealing with insane hardware need the multiplexer.  The 
patch in net-next has a nice ASCII art picture of such an insane design.

David Daney

[-- Attachment #2: ebb6600.dts --]
[-- Type: audio/vnd.dts, Size: 16812 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support.
  2012-05-18 22:03   ` David Daney
@ 2012-05-18 22:09     ` Timur Tabi
  2012-05-18 22:23       ` David Daney
  0 siblings, 1 reply; 15+ messages in thread
From: Timur Tabi @ 2012-05-18 22:09 UTC (permalink / raw)
  To: David Daney; +Cc: devicetree-discuss, netdev, linuxppc-dev

David Daney wrote:
>> > I'm not sure what the "parent" MDIO bus node is supposed to represent.
>> >   Is that that device that actually controls the muxing hardware

> No.  It is the device that implements the master 802.3 clause {22,45} 
> MDIO Station Management (STA) protocol.

Ah, I think I get it.  It is *the* MDIO node that would normally exist if
muxing we're necessary on the board.  From the looks of it, that node
would look exactly the same if you didn't need muxing?

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support.
  2012-05-18 22:09     ` Timur Tabi
@ 2012-05-18 22:23       ` David Daney
  2012-05-24 18:28         ` Timur Tabi
  0 siblings, 1 reply; 15+ messages in thread
From: David Daney @ 2012-05-18 22:23 UTC (permalink / raw)
  To: Timur Tabi; +Cc: devicetree-discuss, netdev, linuxppc-dev

On 05/18/2012 03:09 PM, Timur Tabi wrote:
> David Daney wrote:
>>>> I'm not sure what the "parent" MDIO bus node is supposed to represent.
>>>>    Is that that device that actually controls the muxing hardware
>
>> No.  It is the device that implements the master 802.3 clause {22,45}
>> MDIO Station Management (STA) protocol.
>
> Ah, I think I get it.  It is *the* MDIO node that would normally exist if
> muxing we're necessary on the board.  From the looks of it, that node
> would look exactly the same if you didn't need muxing?
>

Yes.  You may note in the DTS file I attached in the parent (sorry for 
the fubar mime types), that there are two, almost identical, MDIO 
masters.  smi0 has two directly attached PHYs.  smi1 goes to the mux, 
and each child of the mux has four attached PHYs.

This is a fairly complex configuration as the GPIOs controlling the MDIO 
mux are on I2C GPIO expanders which are themselves behind an I2C mux...

The nice thing about this is that the Linux I2C and MDIO infrastructure 
is all configured dynamically from the device tree and everything works 
well together with no locking issues.  The addition of the deferred 
driver probe mechanism was the last part of the puzzle (I think... 
actually I don't know if all my I2C things are merged yet...).

David Daney

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support.
  2012-05-18 22:23       ` David Daney
@ 2012-05-24 18:28         ` Timur Tabi
  2012-05-24 18:50           ` David Daney
  0 siblings, 1 reply; 15+ messages in thread
From: Timur Tabi @ 2012-05-24 18:28 UTC (permalink / raw)
  To: David Daney; +Cc: devicetree-discuss, netdev, linuxppc-dev

David Daney wrote:
> Yes.  You may note in the DTS file I attached in the parent (sorry for 
> the fubar mime types), that there are two, almost identical, MDIO 
> masters.  smi0 has two directly attached PHYs.  smi1 goes to the mux, 
> and each child of the mux has four attached PHYs.

I'm till have trouble understanding all this.  I'm just hacking things up
in order to help me understand it, but it's a slow and painful process.

This call in mdio_mux_init() is failing:

	parent_bus = of_mdio_find_bus(parent_bus_node);

It returns NULL.  Here is my MDIO node:

		fman0: fman@400000 {
			enet0: ethernet@e0000 {
				tbi-handle = <&tbi0>;
				phy-handle = <&phy0>;
				phy-connection-type = "sgmii";
			};

			mdio0: mdio@e1120 {
				gpios = <&gpio0 0 0
					 &gpio0 1 0>;

				tbi0: tbi-phy@8 {
					reg = <0x8>;
					device_type = "tbi-phy";
				};

				phy0: ethernet-phy@1c {
					reg = <0x1c>;
				};
			};
		};

What am I missing?  What do I need to do in order to get
of_mdio_find_bus() to return a real value?

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support.
  2012-05-24 18:28         ` Timur Tabi
@ 2012-05-24 18:50           ` David Daney
  2012-05-24 19:03             ` Timur Tabi
  0 siblings, 1 reply; 15+ messages in thread
From: David Daney @ 2012-05-24 18:50 UTC (permalink / raw)
  To: Timur Tabi; +Cc: devicetree-discuss, netdev, linuxppc-dev

On 05/24/2012 11:28 AM, Timur Tabi wrote:
> David Daney wrote:
>> Yes.  You may note in the DTS file I attached in the parent (sorry for
>> the fubar mime types), that there are two, almost identical, MDIO
>> masters.  smi0 has two directly attached PHYs.  smi1 goes to the mux,
>> and each child of the mux has four attached PHYs.
>
> I'm till have trouble understanding all this.  I'm just hacking things up
> in order to help me understand it, but it's a slow and painful process.
>
> This call in mdio_mux_init() is failing:
>
> 	parent_bus = of_mdio_find_bus(parent_bus_node);
>

Well, the MDIO bus must have an associated device tree node.

For my OCTEON code, the MDIO bus device is created as a result of the 
call to of_platform_bus_probe(), which takes care of filling in all the 
device tree nodes of the devices it finds and creates.

> It returns NULL.  Here is my MDIO node:
>
> 		fman0: fman@400000 {
> 			enet0: ethernet@e0000 {
> 				tbi-handle =<&tbi0>;
> 				phy-handle =<&phy0>;
> 				phy-connection-type = "sgmii";
> 			};
>
> 			mdio0: mdio@e1120 {
> 				gpios =<&gpio0 0 0
> 					&gpio0 1 0>;
>
> 				tbi0: tbi-phy@8 {
> 					reg =<0x8>;
> 					device_type = "tbi-phy";
> 				};
>
> 				phy0: ethernet-phy@1c {
> 					reg =<0x1c>;
> 				};
> 			};
> 		};
>
> What am I missing?

For starters, I do not see any compatible properties that would allow 
the proper drivers to be bound to anything.

Also I see no MDIO mux node there, so it is unclear why you are even 
asking these questions.

David Daney

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support.
  2012-05-24 18:50           ` David Daney
@ 2012-05-24 19:03             ` Timur Tabi
       [not found]               ` <4FBE8605.2020507-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
  0 siblings, 1 reply; 15+ messages in thread
From: Timur Tabi @ 2012-05-24 19:03 UTC (permalink / raw)
  To: David Daney; +Cc: devicetree-discuss, netdev, linuxppc-dev

David Daney wrote:

> Well, the MDIO bus must have an associated device tree node.
> 
> For my OCTEON code, the MDIO bus device is created as a result of the 
> call to of_platform_bus_probe(), which takes care of filling in all the 
> device tree nodes of the devices it finds and creates.

Ok, let me give you some background.  We actually already have MDIO muxing
code in-house, but it's different from yours.  So now I'm rewriting it to
use your design instead.

So our current code looks for "virtual MDIO nodes", and we call
mdiobus_alloc() and then of_mdiobus_register().  I think this is what I'm
missing now.

I just don't know what to do next.  Part of the problem is that I don't
have much experience with MDIO drivers.

>> It returns NULL.  Here is my MDIO node:
>>
>> 		fman0: fman@400000 {
>> 			enet0: ethernet@e0000 {
>> 				tbi-handle =<&tbi0>;
>> 				phy-handle =<&phy0>;
>> 				phy-connection-type = "sgmii";
>> 			};
>>
>> 			mdio0: mdio@e1120 {
>> 				gpios =<&gpio0 0 0
>> 					&gpio0 1 0>;
>>
>> 				tbi0: tbi-phy@8 {
>> 					reg =<0x8>;
>> 					device_type = "tbi-phy";
>> 				};
>>
>> 				phy0: ethernet-phy@1c {
>> 					reg =<0x1c>;
>> 				};
>> 			};
>> 		};
>>
>> What am I missing?
> 
> For starters, I do not see any compatible properties that would allow 
> the proper drivers to be bound to anything.

Ok, that makes sense.

> Also I see no MDIO mux node there, so it is unclear why you are even 
> asking these questions.

I only gave you part of the device tree.  Here's my mdio mux node:

	mdio-mux {
		compatible = "mdio-mux-gpio";
		gpios = <&gpio0 0 0>, <&gpio0 1 0>;
		mdio-parent-bus = <&mdio0>;
		#address-cells = <1>;
		#size-cells = <0>;

		mdio@2 {
			reg = <2>;
			#address-cells = <1>;
			#size-cells = <0>;

			phy21: ethernet-phy@1 {
				reg = <1>;
//				compatible = "marvell,88e1149r", "ethernet-phy-ieee802.3-c22";
				marvell,reg-init = <3 0x10 0 0x5777>,
					<3 0x11 0 0x00aa>,
					<3 0x12 0 0x4105>,
					<3 0x13 0 0x0a60>;
				interrupt-parent = <&gpio0>;
//				interrupts = <10 8>; /* Pin 10, active low */
			};
		};
	};
};




> 
> David Daney
> 


-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support.
       [not found]               ` <4FBE8605.2020507-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
@ 2012-05-24 19:19                 ` David Daney
  0 siblings, 0 replies; 15+ messages in thread
From: David Daney @ 2012-05-24 19:19 UTC (permalink / raw)
  To: Timur Tabi
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ

On 05/24/2012 12:03 PM, Timur Tabi wrote:
> David Daney wrote:
>
>> Well, the MDIO bus must have an associated device tree node.
>>
>> For my OCTEON code, the MDIO bus device is created as a result of the
>> call to of_platform_bus_probe(), which takes care of filling in all the
>> device tree nodes of the devices it finds and creates.
>
> Ok, let me give you some background.  We actually already have MDIO muxing
> code in-house, but it's different from yours.  So now I'm rewriting it to
> use your design instead.
>
> So our current code looks for "virtual MDIO nodes", and we call
> mdiobus_alloc() and then of_mdiobus_register().  I think this is what I'm
> missing now.
>
> I just don't know what to do next.

You will have to debug it and find out why the device match is failing, 
then fix it.

David Daney

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2012-05-24 19:19 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-03  1:16 [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support David Daney
2012-05-03  1:16 ` [PATCH v6 1/3] netdev/of/phy: New function: of_mdio_find_bus() David Daney
2012-05-08  2:58   ` David Miller
2012-05-03  1:16 ` [PATCH v6 2/3] netdev/of/phy: Add MDIO bus multiplexer support David Daney
2012-05-08  2:58   ` David Miller
     [not found] ` <1336007799-31016-1-git-send-email-ddaney.cavm-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2012-05-03  1:16   ` [PATCH v6 3/3] netdev/of/phy: Add MDIO bus multiplexer driven by GPIO lines David Daney
2012-05-08  2:59     ` David Miller
2012-05-18 21:42 ` [PATCH v6 0/3] netdev/of/phy: MDIO bus multiplexer support Tabi Timur-B04825
2012-05-18 22:03   ` David Daney
2012-05-18 22:09     ` Timur Tabi
2012-05-18 22:23       ` David Daney
2012-05-24 18:28         ` Timur Tabi
2012-05-24 18:50           ` David Daney
2012-05-24 19:03             ` Timur Tabi
     [not found]               ` <4FBE8605.2020507-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
2012-05-24 19:19                 ` David Daney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).