linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
To: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Cc: Andrew Lunn <andrew@lunn.ch>, Jason Cooper <jason@lakedaemon.net>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linuxppc-dev@lists.ozlabs.org, David Miller <davem@davemloft.net>,
	Lennert Buytenhek <buytenh@wantstofly.org>
Subject: [PATCH v4 05/12] net: mv643xx_eth: add DT parsing support
Date: Tue, 21 May 2013 18:41:43 +0200	[thread overview]
Message-ID: <1369154510-4927-6-git-send-email-sebastian.hesselbarth@gmail.com> (raw)
In-Reply-To: <1369154510-4927-1-git-send-email-sebastian.hesselbarth@gmail.com>

This adds device tree parsing support for the shared driver of mv643xx_eth.
As the bindings are slightly different from current PPC bindings new binding
documentation is also added. Following PPC-style device setup, the shared
driver now also adds port platform_devices and sets up port platform_data.

Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
---
Note: Although different, device tree bindings are compatible with PPC
bindings. As I do not have access to any PPC platform using mv643xx_eth,
I leave conversion ("phy" vs "phy-handle") and compatible string name
up to PPC guys.

Due to hang reports for modular built mvmdio and mv643xx_eth, I have
tested module loading/unloading/reloading on CuBox (Dove) and Dockstar
(Kirkwood) without any issues for the whole patch set.

Changelog:
v3->v4:
- separation of independent patches (phy, of_mdio, devm)
- stand-alone device tree binding compatible to existing mv64x60 binding
- device node match for shared driver only
- device node registration for port drivers
- properly return -EPROBE_DEFER on missing of phy (Reported by Simon Baatz)

v2->v3:
- rebase on top of mv643xx_eth clean-ups
- do not reparse existing platform_data
- use managed devm_kzalloc for parsed platform_data
- use of_property_read_u32 where applicable
- add phy_node to platform_data
- use of_connect_phy if DT phy node was found

v1->v2:
- properly ifdef of_platform_bus_probe with CONFIG_OF
- handle of_platform_bus_probe errors and cleanup accordingly
- use of_property_read_u32 where applicable
- parse "duplex" and "speed" property in PHY-less configuration

Cc: David Miller <davem@davemloft.net>
Cc: Lennert Buytenhek <buytenh@wantstofly.org>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: netdev@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-kernel@vger.kernel.org
---
 .../devicetree/bindings/net/marvell-orion-net.txt  |   83 +++++++++++
 drivers/net/ethernet/marvell/mv643xx_eth.c         |  152 +++++++++++++++++++-
 2 files changed, 231 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/marvell-orion-net.txt

diff --git a/Documentation/devicetree/bindings/net/marvell-orion-net.txt b/Documentation/devicetree/bindings/net/marvell-orion-net.txt
new file mode 100644
index 0000000..23ffd57
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/marvell-orion-net.txt
@@ -0,0 +1,83 @@
+Marvell Orion/Discovery ethernet controller
+=============================================
+
+The Marvell Discovery ethernet controller can be found on Marvell Orion SoCs
+(Kirkwood, Dove, Orion5x, and Discovery Innovation) and as part of Marvell
+Discovery system controller chips (mv64[345]60).
+
+The Discovery ethernet controller is described with two levels of nodes. The
+first level describes the ethernet controller itself and the second level
+describes up to 3 ethernet port nodes within that controller. The reason for
+the multiple levels is that the port registers are interleaved within a single
+set of controller registers. Each port node describes port-specific properties.
+
+Note: The above separation is only true for Discovery system controllers.
+For Orion SoCs we stick to the separation, although there each controller has
+only one port associated. Multiple ports are implemented as multiple single-port
+controllers.
+
+* Ethernet controller node
+
+Required controller properties:
+ - #address-cells: shall be 1.
+ - #size-cells: shall be 0.
+ - compatible: shall be "marvell,orion-eth".
+ - reg: address and length of the controller registers.
+
+Optional controller properties:
+ - clocks: phandle reference to the controller clock.
+ - marvell,tx-checksum-limit: max tx packet size for hardware checksum.
+
+* Ethernet port node
+
+Required port properties:
+ - device_type: shall be "network".
+ - compatible: shall be "marvell,orion-eth-port".
+ - reg: port number relative to ethernet controller, shall be 0, 1, or 2.
+ - interrupts: port interrupt.
+ - local-mac-address: 6 bytes MAC address.
+
+Optional port properties:
+ - marvell,tx-queue-size: size of the transmit ring buffer.
+ - marvell,tx-sram-addr: address of transmit descriptor buffer located in SRAM.
+ - marvell,tx-sram-size: size of transmit descriptor buffer located in SRAM.
+ - marvell,rx-queue-size: size of the receive ring buffer.
+ - marvell,rx-sram-addr: address of receive descriptor buffer located in SRAM.
+ - marvell,rx-sram-size: size of receive descriptor buffer located in SRAM.
+
+and
+
+ - phy-handle: phandle reference to ethernet PHY.
+
+or
+
+ - speed: port speed if no PHY connected.
+ - duplex: port mode if no PHY connected.
+
+* Node example:
+
+mdio-bus {
+	...
+	ethphy: ethernet-phy@8 {
+		device_type = "ethernet-phy";
+		...
+	};
+};
+
+eth: ethernet-controller@72000 {
+	compatible = "marvell,orion-eth";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	reg = <0x72000 0x2000>;
+	clocks = <&gate_clk 2>;
+	marvell,tx-checksum-limit = <1600>;
+
+	ethernet@0 {
+		device_type = "network";
+		compatible = "marvell,orion-eth-port";
+		reg = <0>;
+		interrupts = <29>;
+		phy-handle = <&ethphy>;
+		local-mac-address = [00 00 00 00 00 00];
+	};
+};
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 0f5c3c2..f2c229c 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -60,6 +60,9 @@
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_net.h>
 #include <linux/of_mdio.h>
 
 static char mv643xx_eth_driver_name[] = "mv643xx_eth";
@@ -2451,13 +2454,147 @@ static void infer_hw_params(struct mv643xx_eth_shared_private *msp)
 	}
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id mv643xx_eth_shared_ids[] = {
+	{ .compatible = "marvell,orion-eth", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mv643xx_eth_shared_ids);
+#endif
+
+#if defined(CONFIG_OF) && !defined(CONFIG_MV64X60)
+#define mv643xx_eth_property(_np, _name, _v)				\
+	do {								\
+		u32 tmp;						\
+		if (!of_property_read_u32(_np, "marvell," _name, &tmp))	\
+			_v = tmp;					\
+	} while (0)
+
+static struct platform_device *port_platdev[3];
+
+static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev,
+					  struct device_node *pnp)
+{
+	struct platform_device *ppdev;
+	struct mv643xx_eth_platform_data ppd;
+	struct resource res;
+	const char *mac_addr;
+	int ret;
+
+	memset(&ppd, 0, sizeof(ppd));
+	ppd.shared = pdev;
+
+	memset(&res, 0, sizeof(res));
+	if (!of_irq_to_resource(pnp, 0, &res)) {
+		dev_err(&pdev->dev, "missing interrupt on %s\n", pnp->name);
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32(pnp, "reg", &ppd.port_number)) {
+		dev_err(&pdev->dev, "missing reg property on %s\n", pnp->name);
+		return -EINVAL;
+	}
+
+	if (ppd.port_number >= 3) {
+		dev_err(&pdev->dev, "invalid reg property on %s\n", pnp->name);
+		return -EINVAL;
+	}
+
+	mac_addr = of_get_mac_address(pnp);
+	if (mac_addr)
+		memcpy(ppd.mac_addr, mac_addr, 6);
+
+	mv643xx_eth_property(pnp, "tx-queue-size", ppd.tx_queue_size);
+	mv643xx_eth_property(pnp, "tx-sram-addr", ppd.tx_sram_addr);
+	mv643xx_eth_property(pnp, "tx-sram-size", ppd.tx_sram_size);
+	mv643xx_eth_property(pnp, "rx-queue-size", ppd.rx_queue_size);
+	mv643xx_eth_property(pnp, "rx-sram-addr", ppd.rx_sram_addr);
+	mv643xx_eth_property(pnp, "rx-sram-size", ppd.rx_sram_size);
+
+	ppd.phy_node = of_parse_phandle(pnp, "phy-handle", 0);
+	if (!ppd.phy_node) {
+		ppd.phy_addr = MV643XX_ETH_PHY_NONE;
+		of_property_read_u32(pnp, "speed", &ppd.speed);
+		of_property_read_u32(pnp, "duplex", &ppd.duplex);
+	}
+
+	ppdev = platform_device_alloc(MV643XX_ETH_NAME, ppd.port_number);
+	if (!ppdev)
+		return -ENOMEM;
+	ppdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+	ret = platform_device_add_resources(ppdev, &res, 1);
+	if (ret)
+		goto port_err;
+
+	ret = platform_device_add_data(ppdev, &ppd, sizeof(ppd));
+	if (ret)
+		goto port_err;
+
+	ret = platform_device_add(ppdev);
+	if (ret)
+		goto port_err;
+
+	port_platdev[ppd.port_number] = ppdev;
+
+	return 0;
+
+port_err:
+	platform_device_put(ppdev);
+	return ret;
+}
+
+static int mv643xx_eth_shared_of_probe(struct platform_device *pdev)
+{
+	struct mv643xx_eth_shared_platform_data *pd;
+	struct device_node *pnp, *np = pdev->dev.of_node;
+	int ret;
+
+	/* bail out if not registered from DT */
+	if (!np)
+		return 0;
+
+	pd = devm_kzalloc(&pdev->dev, sizeof(*pd), GFP_KERNEL);
+	if (!pd)
+		return -ENOMEM;
+	pdev->dev.platform_data = pd;
+
+	mv643xx_eth_property(np, "tx-checksum-limit", pd->tx_csum_limit);
+
+	for_each_available_child_of_node(np, pnp) {
+		ret = mv643xx_eth_shared_of_add_port(pdev, pnp);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+
+static void mv643xx_eth_shared_of_remove(void)
+{
+	int n;
+
+	for (n = 0; n < 3; n++) {
+		platform_device_del(port_platdev[n]);
+		port_platdev[n] = NULL;
+	}
+}
+#else
+static int mv643xx_eth_shared_of_probe(struct platform_device *pdev)
+{
+	return 0
+}
+
+#define mv643xx_eth_shared_of_remove()
+#endif
+
 static int mv643xx_eth_shared_probe(struct platform_device *pdev)
 {
 	static int mv643xx_eth_version_printed;
-	struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;
+	struct mv643xx_eth_shared_platform_data *pd;
 	struct mv643xx_eth_shared_private *msp;
 	const struct mbus_dram_target_info *dram;
 	struct resource *res;
+	int ret;
 
 	if (!mv643xx_eth_version_printed++)
 		pr_notice("MV-643xx 10/100/1000 ethernet driver version %s\n",
@@ -2470,6 +2607,7 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
 	msp = devm_kzalloc(&pdev->dev, sizeof(*msp), GFP_KERNEL);
 	if (msp == NULL)
 		return -ENOMEM;
+	platform_set_drvdata(pdev, msp);
 
 	msp->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
 	if (msp->base == NULL)
@@ -2486,12 +2624,15 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
 	if (dram)
 		mv643xx_eth_conf_mbus_windows(msp, dram);
 
+	ret = mv643xx_eth_shared_of_probe(pdev);
+	if (ret)
+		return ret;
+	pd = pdev->dev.platform_data;
+
 	msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ?
 					pd->tx_csum_limit : 9 * 1024;
 	infer_hw_params(msp);
 
-	platform_set_drvdata(pdev, msp);
-
 	return 0;
 }
 
@@ -2499,9 +2640,9 @@ static int mv643xx_eth_shared_remove(struct platform_device *pdev)
 {
 	struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev);
 
+	mv643xx_eth_shared_of_remove();
 	if (!IS_ERR(msp->clk))
 		clk_disable_unprepare(msp->clk);
-
 	return 0;
 }
 
@@ -2511,6 +2652,7 @@ static struct platform_driver mv643xx_eth_shared_driver = {
 	.driver = {
 		.name	= MV643XX_ETH_SHARED_NAME,
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(mv643xx_eth_shared_ids),
 	},
 };
 
@@ -2710,6 +2852,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
 	if (!IS_ERR(mp->clk)) {
 		clk_prepare_enable(mp->clk);
 		mp->t_clk = clk_get_rate(mp->clk);
+	} else if (!IS_ERR(mp->shared->clk)) {
+		mp->t_clk = clk_get_rate(mp->shared->clk);
 	}
 
 	set_params(mp, pd);
-- 
1.7.10.4

  parent reply	other threads:[~2013-05-21 16:42 UTC|newest]

Thread overview: 93+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1367854420-8006-1-git-send-email-sebastian.hesselbarth@gmail.com>
2013-05-21 16:41 ` [PATCH v4 00/12] net: mv643xx_eth DT support and fixes Sebastian Hesselbarth
2013-05-21 16:41   ` [PATCH v4 01/12] net: mv643xx_eth: use phy_disconnect instead of phy_detach Sebastian Hesselbarth
2013-05-21 16:41   ` [PATCH v4 02/12] net: mv643xx_eth: use managed devm_ioremap for port registers Sebastian Hesselbarth
2013-05-21 16:41   ` [PATCH v4 03/12] net: mv643xx_eth: add phy_node to platform_data struct Sebastian Hesselbarth
2013-05-21 16:41   ` [PATCH v4 04/12] net: mv643xx_eth: use of_phy_connect if phy_node present Sebastian Hesselbarth
2013-05-21 16:41   ` Sebastian Hesselbarth [this message]
2013-05-21 16:41   ` [PATCH v4 06/12] ARM: dove: add gigabit ethernet and mvmdio device tree nodes Sebastian Hesselbarth
2013-05-21 17:48     ` Andrew Lunn
2013-05-22  9:43       ` Sebastian Hesselbarth
2013-05-22 10:04         ` tiejun.chen
2013-05-22 10:13           ` Sebastian Hesselbarth
2013-05-22 13:10             ` Jason Cooper
2013-05-22 16:59               ` Jason Gunthorpe
2013-05-22 17:01                 ` Jason Cooper
2013-05-22 17:32                 ` Sebastian Hesselbarth
2013-05-22 17:35                   ` Jason Cooper
2013-05-22 17:42                     ` Sebastian Hesselbarth
2013-05-22 17:48                       ` Jason Cooper
2013-05-22 18:44                         ` Sebastian Hesselbarth
2013-05-22 18:49                           ` Jason Cooper
2013-05-22 18:55                             ` Sebastian Hesselbarth
2013-05-22 18:58                               ` Jason Cooper
2013-05-22 19:52                         ` Sebastian Hesselbarth
2013-05-22 18:24                   ` Jason Gunthorpe
2013-05-22 18:51                     ` Sebastian Hesselbarth
2013-05-21 16:41   ` [PATCH v4 07/12] ARM: kirkwood: " Sebastian Hesselbarth
2013-05-21 16:41   ` [PATCH v4 08/12] ARM: orion5x: " Sebastian Hesselbarth
2013-05-21 16:41   ` [PATCH v4 09/12] ARM: dove: remove legacy mv643xx_eth setup Sebastian Hesselbarth
2013-05-21 16:41   ` [PATCH v4 10/12] ARM: kirkwood: remove legacy clk alias for mv643xx_eth Sebastian Hesselbarth
2013-05-21 16:41   ` [PATCH v4 11/12] ARM: kirkwood: remove redundant DT board files Sebastian Hesselbarth
2013-05-22 20:36     ` Simon Baatz
2013-05-22 20:55       ` Sebastian Hesselbarth
2013-05-22 21:02         ` Jason Cooper
2013-05-22 21:17           ` Sebastian Hesselbarth
2013-05-21 16:41   ` [PATCH v4 12/12] ARM: orion5x: remove legacy mv643xx_eth board setup Sebastian Hesselbarth
2013-05-22 16:16   ` [PATCH v4 00/12] net: mv643xx_eth DT support and fixes Andrew Lunn
2013-05-22 20:04   ` [PATCH 1/2] ARM: kirkwood: proper retain MAC address workaround on DT ethernet Sebastian Hesselbarth
2013-05-22 20:04     ` [PATCH 2/2] net: mv643xx_eth: proper initialization for Kirkwood SoCs Sebastian Hesselbarth
2013-05-22 20:16       ` Jason Gunthorpe
2013-05-22 21:02         ` Sebastian Hesselbarth
2013-05-23 16:01         ` Jason Cooper
2013-05-23 17:11           ` Jason Gunthorpe
2013-05-23 17:23             ` Jason Cooper
2013-05-23 17:53               ` Jason Gunthorpe
2013-05-23 18:40                 ` Jason Cooper
2013-05-23 19:01                   ` Jason Gunthorpe
2013-05-24 16:46                     ` Jason Cooper
2013-05-24 16:53                       ` Andrew Lunn
2013-05-24 17:03                         ` Jason Cooper
2013-05-24 17:33                       ` Jason Gunthorpe
2013-05-28 18:02                         ` Jason Cooper
2013-05-23 22:40                   ` Sebastian Hesselbarth
2013-05-24 11:03                     ` Linus Walleij
2013-05-24 17:01                       ` Jason Cooper
2013-05-24 17:13                         ` Russell King - ARM Linux
2013-05-24 17:25                           ` Sebastian Hesselbarth
2013-05-24 16:53                     ` Jason Cooper
2013-05-26  4:04     ` [PATCH 1/2] ARM: kirkwood: proper retain MAC address workaround on DT ethernet David Miller
2013-05-26 20:06       ` Sebastian Hesselbarth
2013-05-27  9:23         ` David Miller
2013-05-27  9:39           ` Benjamin Herrenschmidt
2013-05-27 10:24             ` Sebastian Hesselbarth
2013-05-27 11:50               ` Benjamin Herrenschmidt
2013-05-27 12:47                 ` Arnd Bergmann
2013-05-27 21:50                   ` Benjamin Herrenschmidt
2013-05-27 22:12                     ` Sebastian Hesselbarth
2013-05-27 22:17                     ` David Miller
2013-05-27 20:18                 ` David Miller
2013-05-27 21:48                   ` Benjamin Herrenschmidt
2013-05-27  9:38         ` Benjamin Herrenschmidt
2013-05-29 19:32   ` [PATCH v5 00/13] net: mv643xx_eth DT support and fixes Sebastian Hesselbarth
2013-05-29 19:32     ` [PATCH v5 01/13] net: mv643xx_eth: use phy_disconnect instead of phy_detach Sebastian Hesselbarth
2013-05-29 20:00       ` Jason Cooper
2013-05-29 19:32     ` [PATCH v5 02/13] net: mv643xx_eth: use managed devm_ioremap for port registers Sebastian Hesselbarth
2013-05-29 19:32     ` [PATCH v5 03/13] net: mv643xx_eth: add phy_node to platform_data struct Sebastian Hesselbarth
2013-05-29 19:32     ` [PATCH v5 04/13] net: mv643xx_eth: use of_phy_connect if phy_node present Sebastian Hesselbarth
2013-05-29 19:32     ` [PATCH v5 05/13] net: mv643xx_eth: proper initialization for Kirkwood SoCs Sebastian Hesselbarth
2013-05-29 19:32     ` [PATCH v5 06/13] net: mv643xx_eth: add DT parsing support Sebastian Hesselbarth
2013-05-29 19:32     ` [PATCH v5 07/13] ARM: dove: add gigabit ethernet and mvmdio device tree nodes Sebastian Hesselbarth
2013-05-29 19:32     ` [PATCH v5 08/13] ARM: kirkwood: " Sebastian Hesselbarth
2013-05-29 19:32     ` [PATCH v5 09/13] ARM: orion5x: " Sebastian Hesselbarth
2013-05-29 19:32     ` [PATCH v5 10/13] ARM: dove: remove legacy mv643xx_eth setup Sebastian Hesselbarth
2013-05-29 19:32     ` [PATCH v5 11/13] ARM: kirkwood: remove legacy clk alias for mv643xx_eth Sebastian Hesselbarth
2013-05-29 19:32     ` [PATCH v5 12/13] ARM: kirkwood: remove redundant DT board files Sebastian Hesselbarth
2013-05-30  9:06       ` Arnaud Ebalard
2013-05-30  9:08         ` Sebastian Hesselbarth
2013-05-30 19:37         ` Jason Cooper
2013-05-30 22:28           ` Arnaud Ebalard
2013-05-31 11:54             ` Jason Cooper
2013-05-29 19:32     ` [PATCH v5 13/13] ARM: orion5x: remove legacy mv643xx_eth board setup Sebastian Hesselbarth
2013-05-31  0:55     ` [PATCH v5 00/13] net: mv643xx_eth DT support and fixes David Miller
2013-05-31  6:28       ` Sebastian Hesselbarth
2013-05-31  9:32         ` David Miller

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=1369154510-4927-6-git-send-email-sebastian.hesselbarth@gmail.com \
    --to=sebastian.hesselbarth@gmail.com \
    --cc=andrew@lunn.ch \
    --cc=buytenh@wantstofly.org \
    --cc=davem@davemloft.net \
    --cc=jason@lakedaemon.net \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=netdev@vger.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 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).