All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/3] ethernet: arc: remove use of 'struct platform_device'
@ 2014-08-26  9:23 Romain Perier
  2014-08-26  9:23 ` [PATCH v3 2/3] ethernet: arc: mdio refactoring for future specific SoC glue layer devicetree bindings addition Romain Perier
  2014-08-26  9:23 ` [PATCH v3 3/3] ethernet: arc: Add support for specific SoC glue layer device tree bindings Romain Perier
  0 siblings, 2 replies; 5+ messages in thread
From: Romain Perier @ 2014-08-26  9:23 UTC (permalink / raw)
  To: davem
  Cc: heiko, tklauser, b.galvani, eric.dumazet, yongjun_wei,
	f.fainelli, netdev, arnd

This is a preparation of an api changes for the emac_main.c module.
The involved functions are arc_emac_probe and arc_emac_remove.

Signed-off-by: Romain Perier <romain.perier@gmail.com>
---
 drivers/net/ethernet/arc/emac_main.c | 64 +++++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 31 deletions(-)

diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index fe5cfea..761b936 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -673,6 +673,7 @@ static const struct net_device_ops arc_emac_netdev_ops = {
 
 static int arc_emac_probe(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
 	struct resource res_regs;
 	struct device_node *phy_node;
 	struct arc_emac_priv *priv;
@@ -681,27 +682,27 @@ static int arc_emac_probe(struct platform_device *pdev)
 	unsigned int id, clock_frequency, irq;
 	int err;
 
-	if (!pdev->dev.of_node)
+	if (!dev->of_node)
 		return -ENODEV;
 
 	/* Get PHY from device tree */
-	phy_node = of_parse_phandle(pdev->dev.of_node, "phy", 0);
+	phy_node = of_parse_phandle(dev->of_node, "phy", 0);
 	if (!phy_node) {
-		dev_err(&pdev->dev, "failed to retrieve phy description from device tree\n");
+		dev_err(dev, "failed to retrieve phy description from device tree\n");
 		return -ENODEV;
 	}
 
 	/* Get EMAC registers base address from device tree */
-	err = of_address_to_resource(pdev->dev.of_node, 0, &res_regs);
+	err = of_address_to_resource(dev->of_node, 0, &res_regs);
 	if (err) {
-		dev_err(&pdev->dev, "failed to retrieve registers base from device tree\n");
+		dev_err(dev, "failed to retrieve registers base from device tree\n");
 		return -ENODEV;
 	}
 
 	/* Get IRQ from device tree */
-	irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+	irq = irq_of_parse_and_map(dev->of_node, 0);
 	if (!irq) {
-		dev_err(&pdev->dev, "failed to retrieve <irq> value from device tree\n");
+		dev_err(dev, "failed to retrieve <irq> value from device tree\n");
 		return -ENODEV;
 	}
 
@@ -709,8 +710,8 @@ static int arc_emac_probe(struct platform_device *pdev)
 	if (!ndev)
 		return -ENOMEM;
 
-	platform_set_drvdata(pdev, ndev);
-	SET_NETDEV_DEV(ndev, &pdev->dev);
+	dev_set_drvdata(dev, ndev);
+	SET_NETDEV_DEV(ndev, dev);
 
 	ndev->netdev_ops = &arc_emac_netdev_ops;
 	ndev->ethtool_ops = &arc_emac_ethtool_ops;
@@ -719,28 +720,28 @@ static int arc_emac_probe(struct platform_device *pdev)
 	ndev->flags &= ~IFF_MULTICAST;
 
 	priv = netdev_priv(ndev);
-	priv->dev = &pdev->dev;
+	priv->dev = dev;
 
-	priv->regs = devm_ioremap_resource(&pdev->dev, &res_regs);
+	priv->regs = devm_ioremap_resource(dev, &res_regs);
 	if (IS_ERR(priv->regs)) {
 		err = PTR_ERR(priv->regs);
 		goto out_netdev;
 	}
-	dev_dbg(&pdev->dev, "Registers base address is 0x%p\n", priv->regs);
+	dev_dbg(dev, "Registers base address is 0x%p\n", priv->regs);
 
-	priv->clk = of_clk_get(pdev->dev.of_node, 0);
+	priv->clk = of_clk_get(dev->of_node, 0);
 	if (IS_ERR(priv->clk)) {
 		/* Get CPU clock frequency from device tree */
-		if (of_property_read_u32(pdev->dev.of_node, "clock-frequency",
+		if (of_property_read_u32(dev->of_node, "clock-frequency",
 					&clock_frequency)) {
-			dev_err(&pdev->dev, "failed to retrieve <clock-frequency> from device tree\n");
+			dev_err(dev, "failed to retrieve <clock-frequency> from device tree\n");
 			err = -EINVAL;
 			goto out_netdev;
 		}
 	} else {
 		err = clk_prepare_enable(priv->clk);
 		if (err) {
-			dev_err(&pdev->dev, "failed to enable clock\n");
+			dev_err(dev, "failed to enable clock\n");
 			goto out_clkget;
 		}
 
@@ -751,28 +752,28 @@ static int arc_emac_probe(struct platform_device *pdev)
 
 	/* Check for EMAC revision 5 or 7, magic number */
 	if (!(id == 0x0005fd02 || id == 0x0007fd02)) {
-		dev_err(&pdev->dev, "ARC EMAC not detected, id=0x%x\n", id);
+		dev_err(dev, "ARC EMAC not detected, id=0x%x\n", id);
 		err = -ENODEV;
 		goto out_clken;
 	}
-	dev_info(&pdev->dev, "ARC EMAC detected with id: 0x%x\n", id);
+	dev_info(dev, "ARC EMAC detected with id: 0x%x\n", id);
 
 	/* Set poll rate so that it polls every 1 ms */
 	arc_reg_set(priv, R_POLLRATE, clock_frequency / 1000000);
 
 	ndev->irq = irq;
-	dev_info(&pdev->dev, "IRQ is %d\n", ndev->irq);
+	dev_info(dev, "IRQ is %d\n", ndev->irq);
 
 	/* Register interrupt handler for device */
-	err = devm_request_irq(&pdev->dev, ndev->irq, arc_emac_intr, 0,
+	err = devm_request_irq(dev, ndev->irq, arc_emac_intr, 0,
 			       ndev->name, ndev);
 	if (err) {
-		dev_err(&pdev->dev, "could not allocate IRQ\n");
+		dev_err(dev, "could not allocate IRQ\n");
 		goto out_clken;
 	}
 
 	/* Get MAC address from device tree */
-	mac_addr = of_get_mac_address(pdev->dev.of_node);
+	mac_addr = of_get_mac_address(dev->of_node);
 
 	if (mac_addr)
 		memcpy(ndev->dev_addr, mac_addr, ETH_ALEN);
@@ -780,14 +781,14 @@ static int arc_emac_probe(struct platform_device *pdev)
 		eth_hw_addr_random(ndev);
 
 	arc_emac_set_address_internal(ndev);
-	dev_info(&pdev->dev, "MAC address is now %pM\n", ndev->dev_addr);
+	dev_info(dev, "MAC address is now %pM\n", ndev->dev_addr);
 
 	/* Do 1 allocation instead of 2 separate ones for Rx and Tx BD rings */
-	priv->rxbd = dmam_alloc_coherent(&pdev->dev, RX_RING_SZ + TX_RING_SZ,
+	priv->rxbd = dmam_alloc_coherent(dev, RX_RING_SZ + TX_RING_SZ,
 					 &priv->rxbd_dma, GFP_KERNEL);
 
 	if (!priv->rxbd) {
-		dev_err(&pdev->dev, "failed to allocate data buffers\n");
+		dev_err(dev, "failed to allocate data buffers\n");
 		err = -ENOMEM;
 		goto out_clken;
 	}
@@ -795,31 +796,31 @@ static int arc_emac_probe(struct platform_device *pdev)
 	priv->txbd = priv->rxbd + RX_BD_NUM;
 
 	priv->txbd_dma = priv->rxbd_dma + RX_RING_SZ;
-	dev_dbg(&pdev->dev, "EMAC Device addr: Rx Ring [0x%x], Tx Ring[%x]\n",
+	dev_dbg(dev, "EMAC Device addr: Rx Ring [0x%x], Tx Ring[%x]\n",
 		(unsigned int)priv->rxbd_dma, (unsigned int)priv->txbd_dma);
 
 	err = arc_mdio_probe(pdev, priv);
 	if (err) {
-		dev_err(&pdev->dev, "failed to probe MII bus\n");
+		dev_err(dev, "failed to probe MII bus\n");
 		goto out_clken;
 	}
 
 	priv->phy_dev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0,
 				       PHY_INTERFACE_MODE_MII);
 	if (!priv->phy_dev) {
-		dev_err(&pdev->dev, "of_phy_connect() failed\n");
+		dev_err(dev, "of_phy_connect() failed\n");
 		err = -ENODEV;
 		goto out_mdio;
 	}
 
-	dev_info(&pdev->dev, "connected to %s phy with id 0x%x\n",
+	dev_info(dev, "connected to %s phy with id 0x%x\n",
 		 priv->phy_dev->drv->name, priv->phy_dev->phy_id);
 
 	netif_napi_add(ndev, &priv->napi, arc_emac_poll, ARC_EMAC_NAPI_WEIGHT);
 
 	err = register_netdev(ndev);
 	if (err) {
-		dev_err(&pdev->dev, "failed to register network device\n");
+		dev_err(dev, "failed to register network device\n");
 		goto out_netif_api;
 	}
 
@@ -844,7 +845,8 @@ out_netdev:
 
 static int arc_emac_remove(struct platform_device *pdev)
 {
-	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+	struct net_device *ndev = dev_get_drvdata(dev);
 	struct arc_emac_priv *priv = netdev_priv(ndev);
 
 	phy_disconnect(priv->phy_dev);
-- 
1.9.1

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

* [PATCH v3 2/3] ethernet: arc: mdio refactoring for future specific SoC glue layer devicetree bindings addition
  2014-08-26  9:23 [PATCH v3 1/3] ethernet: arc: remove use of 'struct platform_device' Romain Perier
@ 2014-08-26  9:23 ` Romain Perier
  2014-08-26  9:23 ` [PATCH v3 3/3] ethernet: arc: Add support for specific SoC glue layer device tree bindings Romain Perier
  1 sibling, 0 replies; 5+ messages in thread
From: Romain Perier @ 2014-08-26  9:23 UTC (permalink / raw)
  To: davem
  Cc: heiko, tklauser, b.galvani, eric.dumazet, yongjun_wei,
	f.fainelli, netdev, arnd

This is an api changes for the emac_mdio.c module.
It will be required later when arc_emac_probe/arc_emac_remove
will no longer use 'struct platform_device'.

Signed-off-by: Romain Perier <romain.perier@gmail.com>
---
 drivers/net/ethernet/arc/emac.h      | 2 +-
 drivers/net/ethernet/arc/emac_main.c | 2 +-
 drivers/net/ethernet/arc/emac_mdio.c | 7 +++----
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h
index 36cc9bd..8011445 100644
--- a/drivers/net/ethernet/arc/emac.h
+++ b/drivers/net/ethernet/arc/emac.h
@@ -204,7 +204,7 @@ static inline void arc_reg_clr(struct arc_emac_priv *priv, int reg, int mask)
 	arc_reg_set(priv, reg, value & ~mask);
 }
 
-int arc_mdio_probe(struct platform_device *pdev, struct arc_emac_priv *priv);
+int arc_mdio_probe(struct arc_emac_priv *priv);
 int arc_mdio_remove(struct arc_emac_priv *priv);
 
 #endif /* ARC_EMAC_H */
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index 761b936..bbc3157 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -799,7 +799,7 @@ static int arc_emac_probe(struct platform_device *pdev)
 	dev_dbg(dev, "EMAC Device addr: Rx Ring [0x%x], Tx Ring[%x]\n",
 		(unsigned int)priv->rxbd_dma, (unsigned int)priv->txbd_dma);
 
-	err = arc_mdio_probe(pdev, priv);
+	err = arc_mdio_probe(priv);
 	if (err) {
 		dev_err(dev, "failed to probe MII bus\n");
 		goto out_clken;
diff --git a/drivers/net/ethernet/arc/emac_mdio.c b/drivers/net/ethernet/arc/emac_mdio.c
index 26ba242..d5ee986 100644
--- a/drivers/net/ethernet/arc/emac_mdio.c
+++ b/drivers/net/ethernet/arc/emac_mdio.c
@@ -100,7 +100,6 @@ static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
 
 /**
  * arc_mdio_probe - MDIO probe function.
- * @pdev:	Pointer to platform device.
  * @priv:	Pointer to ARC EMAC private data structure.
  *
  * returns:	0 on success, -ENOMEM when mdiobus_alloc
@@ -108,7 +107,7 @@ static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
  *
  * Sets up and registers the MDIO interface.
  */
-int arc_mdio_probe(struct platform_device *pdev, struct arc_emac_priv *priv)
+int arc_mdio_probe(struct arc_emac_priv *priv)
 {
 	struct mii_bus *bus;
 	int error;
@@ -124,9 +123,9 @@ int arc_mdio_probe(struct platform_device *pdev, struct arc_emac_priv *priv)
 	bus->read = &arc_mdio_read;
 	bus->write = &arc_mdio_write;
 
-	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", pdev->name);
+	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", bus->name);
 
-	error = of_mdiobus_register(bus, pdev->dev.of_node);
+	error = of_mdiobus_register(bus, priv->dev->of_node);
 	if (error) {
 		dev_err(priv->dev, "cannot register MDIO bus %s\n", bus->name);
 		mdiobus_free(bus);
-- 
1.9.1

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

* [PATCH v3 3/3] ethernet: arc: Add support for specific SoC glue layer device tree bindings
  2014-08-26  9:23 [PATCH v3 1/3] ethernet: arc: remove use of 'struct platform_device' Romain Perier
  2014-08-26  9:23 ` [PATCH v3 2/3] ethernet: arc: mdio refactoring for future specific SoC glue layer devicetree bindings addition Romain Perier
@ 2014-08-26  9:23 ` Romain Perier
  2014-08-26  9:26   ` PERIER Romain
  2014-08-26  9:44   ` Arnd Bergmann
  1 sibling, 2 replies; 5+ messages in thread
From: Romain Perier @ 2014-08-26  9:23 UTC (permalink / raw)
  To: davem
  Cc: heiko, tklauser, b.galvani, eric.dumazet, yongjun_wei,
	f.fainelli, netdev, arnd

Some platforms have special bank registers which might be used to select
the correct clock or the right mode for Media Indepent Interface controllers.
Sometimes, it is also required to activate vcc regulators in the right order to supply
the ethernet controller at the right time. This patch is an architecture refactoring
of the arc-emac device driver. it adds a new software design which allows to add specific
platform glue layer. Each platform has now its own module which performs custom initialization
and remove for the target and then calls to the core driver.

Signed-off-by: Romain Perier <romain.perier@gmail.com>
---
 drivers/net/ethernet/arc/Kconfig     |  8 ++-
 drivers/net/ethernet/arc/Makefile    |  3 +-
 drivers/net/ethernet/arc/emac.h      |  4 ++
 drivers/net/ethernet/arc/emac_arc.c  | 95 ++++++++++++++++++++++++++++++++++++
 drivers/net/ethernet/arc/emac_main.c | 80 +++++++++---------------------
 5 files changed, 129 insertions(+), 61 deletions(-)
 create mode 100644 drivers/net/ethernet/arc/emac_arc.c

diff --git a/drivers/net/ethernet/arc/Kconfig b/drivers/net/ethernet/arc/Kconfig
index 514c57f..e193826 100644
--- a/drivers/net/ethernet/arc/Kconfig
+++ b/drivers/net/ethernet/arc/Kconfig
@@ -17,12 +17,16 @@ config NET_VENDOR_ARC
 
 if NET_VENDOR_ARC
 
-config ARC_EMAC
-	tristate "ARC EMAC support"
+config ARC_EMAC_CORE
+	bool
 	select MII
 	select PHYLIB
 	depends on OF_IRQ
 	depends on OF_NET
+
+config ARC_EMAC
+	tristate "ARC EMAC support"
+	select ARC_EMAC_CORE
 	---help---
 	  On some legacy ARC (Synopsys) FPGA boards such as ARCAngel4/ML50x
 	  non-standard on-chip ethernet device ARC EMAC 10/100 is used.
diff --git a/drivers/net/ethernet/arc/Makefile b/drivers/net/ethernet/arc/Makefile
index 00c8657..241bb80 100644
--- a/drivers/net/ethernet/arc/Makefile
+++ b/drivers/net/ethernet/arc/Makefile
@@ -3,4 +3,5 @@
 #
 
 arc_emac-objs := emac_main.o emac_mdio.o
-obj-$(CONFIG_ARC_EMAC) += arc_emac.o
+obj-$(CONFIG_ARC_EMAC_CORE) += arc_emac.o
+obj-$(CONFIG_ARC_EMAC) += emac_arc.o
diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h
index 8011445..eb2ba67 100644
--- a/drivers/net/ethernet/arc/emac.h
+++ b/drivers/net/ethernet/arc/emac.h
@@ -124,6 +124,8 @@ struct buffer_state {
  */
 struct arc_emac_priv {
 	/* Devices */
+	const char *drv_name;
+	const char *drv_version;
 	struct device *dev;
 	struct phy_device *phy_dev;
 	struct mii_bus *bus;
@@ -206,5 +208,7 @@ static inline void arc_reg_clr(struct arc_emac_priv *priv, int reg, int mask)
 
 int arc_mdio_probe(struct arc_emac_priv *priv);
 int arc_mdio_remove(struct arc_emac_priv *priv);
+int arc_emac_probe(struct net_device *ndev, int interface);
+int arc_emac_remove(struct net_device *ndev);
 
 #endif /* ARC_EMAC_H */
diff --git a/drivers/net/ethernet/arc/emac_arc.c b/drivers/net/ethernet/arc/emac_arc.c
new file mode 100644
index 0000000..f9cb99b
--- /dev/null
+++ b/drivers/net/ethernet/arc/emac_arc.c
@@ -0,0 +1,95 @@
+/**
+ * emac_arc.c - ARC EMAC specific glue layer
+ *
+ * Copyright (C) 2014 Romain Perier
+ *
+ * Romain Perier  <romain.perier@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/module.h>
+#include <linux/of_net.h>
+#include <linux/platform_device.h>
+
+#include "emac.h"
+
+#define DRV_NAME    "emac_arc"
+#define DRV_VERSION "1.0"
+
+static int emac_arc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct net_device *ndev;
+	struct arc_emac_priv *priv;
+	int interface, err;
+
+	if (!dev->of_node)
+		return -ENODEV;
+
+	ndev = alloc_etherdev(sizeof(struct arc_emac_priv));
+	if (!ndev)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, ndev);
+	SET_NETDEV_DEV(ndev, dev);
+
+	priv = netdev_priv(ndev);
+	priv->drv_name = DRV_NAME;
+	priv->drv_version = DRV_VERSION;
+
+	interface = of_get_phy_mode(dev->of_node);
+	if (interface < 0)
+		interface = PHY_INTERFACE_MODE_MII;
+
+	priv->clk = devm_clk_get(dev, "hclk");
+	if (IS_ERR(priv->clk)) {
+		dev_err(dev, "failed to retrieve host clock from device tree\n");
+		err = -EINVAL;
+		goto out_netdev;
+	}
+
+	err = arc_emac_probe(ndev, interface);
+out_netdev:
+	if (err)
+		free_netdev(ndev);
+	return err;
+}
+
+static int emac_arc_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	int err;
+
+	err = arc_emac_remove(ndev);
+	free_netdev(ndev);
+	return err;
+}
+
+static const struct of_device_id emac_arc_dt_ids[] = {
+	{ .compatible = "snps,arc-emac" },
+	{ /* Sentinel */ }
+};
+
+static struct platform_driver emac_arc_driver = {
+	.probe = emac_arc_probe,
+	.remove = emac_arc_remove,
+	.driver = {
+		.name = DRV_NAME,
+		.of_match_table  = emac_arc_dt_ids,
+	},
+};
+
+module_platform_driver(emac_arc_driver);
+
+MODULE_AUTHOR("Romain Perier <romain.perier@gmail.com>");
+MODULE_DESCRIPTION("ARC EMAC platform driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index bbc3157..b35c69e 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -26,8 +26,6 @@
 
 #include "emac.h"
 
-#define DRV_NAME	"arc_emac"
-#define DRV_VERSION	"1.0"
 
 /**
  * arc_emac_adjust_link - Adjust the PHY link duplex.
@@ -120,8 +118,10 @@ static int arc_emac_set_settings(struct net_device *ndev,
 static void arc_emac_get_drvinfo(struct net_device *ndev,
 				 struct ethtool_drvinfo *info)
 {
-	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
-	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+	struct arc_emac_priv *priv = netdev_priv(ndev);
+
+	strlcpy(info->driver, priv->drv_name, sizeof(info->driver));
+	strlcpy(info->version, priv->drv_version, sizeof(info->version));
 }
 
 static const struct ethtool_ops arc_emac_ethtool_ops = {
@@ -671,19 +671,16 @@ static const struct net_device_ops arc_emac_netdev_ops = {
 #endif
 };
 
-static int arc_emac_probe(struct platform_device *pdev)
+int arc_emac_probe(struct net_device *ndev, int interface)
 {
-	struct device *dev = &pdev->dev;
+	struct device *dev = ndev->dev.parent;
 	struct resource res_regs;
 	struct device_node *phy_node;
 	struct arc_emac_priv *priv;
-	struct net_device *ndev;
 	const char *mac_addr;
 	unsigned int id, clock_frequency, irq;
 	int err;
 
-	if (!dev->of_node)
-		return -ENODEV;
 
 	/* Get PHY from device tree */
 	phy_node = of_parse_phandle(dev->of_node, "phy", 0);
@@ -706,12 +703,6 @@ static int arc_emac_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	ndev = alloc_etherdev(sizeof(struct arc_emac_priv));
-	if (!ndev)
-		return -ENOMEM;
-
-	dev_set_drvdata(dev, ndev);
-	SET_NETDEV_DEV(ndev, dev);
 
 	ndev->netdev_ops = &arc_emac_netdev_ops;
 	ndev->ethtool_ops = &arc_emac_ethtool_ops;
@@ -724,28 +715,25 @@ static int arc_emac_probe(struct platform_device *pdev)
 
 	priv->regs = devm_ioremap_resource(dev, &res_regs);
 	if (IS_ERR(priv->regs)) {
-		err = PTR_ERR(priv->regs);
-		goto out_netdev;
+		return PTR_ERR(priv->regs);
 	}
 	dev_dbg(dev, "Registers base address is 0x%p\n", priv->regs);
 
-	priv->clk = of_clk_get(dev->of_node, 0);
-	if (IS_ERR(priv->clk)) {
-		/* Get CPU clock frequency from device tree */
-		if (of_property_read_u32(dev->of_node, "clock-frequency",
-					&clock_frequency)) {
-			dev_err(dev, "failed to retrieve <clock-frequency> from device tree\n");
-			err = -EINVAL;
-			goto out_netdev;
-		}
-	} else {
+	if (priv->clk) {
 		err = clk_prepare_enable(priv->clk);
 		if (err) {
 			dev_err(dev, "failed to enable clock\n");
-			goto out_clkget;
+			return err;
 		}
 
 		clock_frequency = clk_get_rate(priv->clk);
+	} else {
+		/* Get CPU clock frequency from device tree */
+		if (of_property_read_u32(dev->of_node, "clock-frequency",
+					 &clock_frequency)) {
+			dev_err(dev, "failed to retrieve <clock-frequency> from device tree\n");
+			return -EINVAL;
+		}
 	}
 
 	id = arc_reg_get(priv, R_ID);
@@ -806,7 +794,7 @@ static int arc_emac_probe(struct platform_device *pdev)
 	}
 
 	priv->phy_dev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0,
-				       PHY_INTERFACE_MODE_MII);
+				       interface);
 	if (!priv->phy_dev) {
 		dev_err(dev, "of_phy_connect() failed\n");
 		err = -ENODEV;
@@ -833,20 +821,15 @@ out_netif_api:
 out_mdio:
 	arc_mdio_remove(priv);
 out_clken:
-	if (!IS_ERR(priv->clk))
+	if (priv->clk)
 		clk_disable_unprepare(priv->clk);
-out_clkget:
-	if (!IS_ERR(priv->clk))
-		clk_put(priv->clk);
-out_netdev:
-	free_netdev(ndev);
 	return err;
 }
+EXPORT_SYMBOL_GPL(arc_emac_probe);
 
-static int arc_emac_remove(struct platform_device *pdev)
+int arc_emac_remove(struct net_device *ndev)
 {
-	struct device *dev = &pdev->dev;
-	struct net_device *ndev = dev_get_drvdata(dev);
+	struct device *dev = ndev->dev.parent;
 	struct arc_emac_priv *priv = netdev_priv(ndev);
 
 	phy_disconnect(priv->phy_dev);
@@ -857,31 +840,12 @@ static int arc_emac_remove(struct platform_device *pdev)
 
 	if (!IS_ERR(priv->clk)) {
 		clk_disable_unprepare(priv->clk);
-		clk_put(priv->clk);
 	}
 
-	free_netdev(ndev);
 
 	return 0;
 }
-
-static const struct of_device_id arc_emac_dt_ids[] = {
-	{ .compatible = "snps,arc-emac" },
-	{ /* Sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, arc_emac_dt_ids);
-
-static struct platform_driver arc_emac_driver = {
-	.probe = arc_emac_probe,
-	.remove = arc_emac_remove,
-	.driver = {
-		.name = DRV_NAME,
-		.owner = THIS_MODULE,
-		.of_match_table  = arc_emac_dt_ids,
-		},
-};
-
-module_platform_driver(arc_emac_driver);
+EXPORT_SYMBOL_GPL(arc_emac_remove);
 
 MODULE_AUTHOR("Alexey Brodkin <abrodkin@synopsys.com>");
 MODULE_DESCRIPTION("ARC EMAC driver");
-- 
1.9.1

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

* Re: [PATCH v3 3/3] ethernet: arc: Add support for specific SoC glue layer device tree bindings
  2014-08-26  9:23 ` [PATCH v3 3/3] ethernet: arc: Add support for specific SoC glue layer device tree bindings Romain Perier
@ 2014-08-26  9:26   ` PERIER Romain
  2014-08-26  9:44   ` Arnd Bergmann
  1 sibling, 0 replies; 5+ messages in thread
From: PERIER Romain @ 2014-08-26  9:26 UTC (permalink / raw)
  To: davem
  Cc: Heiko Stübner, Tobias Klauser, Beniamino Galvani,
	eric.dumazet, yongjun_wei, Florian Fainelli, netdev,
	Arnd Bergmann

PS: I will add callback function for set_mac_speed from platform
driver and a priv data inline function (like netdev_priv for arc_emac)
into another seperated commit, I think.

Romain

2014-08-26 11:23 GMT+02:00 Romain Perier <romain.perier@gmail.com>:
> Some platforms have special bank registers which might be used to select
> the correct clock or the right mode for Media Indepent Interface controllers.
> Sometimes, it is also required to activate vcc regulators in the right order to supply
> the ethernet controller at the right time. This patch is an architecture refactoring
> of the arc-emac device driver. it adds a new software design which allows to add specific
> platform glue layer. Each platform has now its own module which performs custom initialization
> and remove for the target and then calls to the core driver.
>
> Signed-off-by: Romain Perier <romain.perier@gmail.com>
> ---
>  drivers/net/ethernet/arc/Kconfig     |  8 ++-
>  drivers/net/ethernet/arc/Makefile    |  3 +-
>  drivers/net/ethernet/arc/emac.h      |  4 ++
>  drivers/net/ethernet/arc/emac_arc.c  | 95 ++++++++++++++++++++++++++++++++++++
>  drivers/net/ethernet/arc/emac_main.c | 80 +++++++++---------------------
>  5 files changed, 129 insertions(+), 61 deletions(-)
>  create mode 100644 drivers/net/ethernet/arc/emac_arc.c
>
> diff --git a/drivers/net/ethernet/arc/Kconfig b/drivers/net/ethernet/arc/Kconfig
> index 514c57f..e193826 100644
> --- a/drivers/net/ethernet/arc/Kconfig
> +++ b/drivers/net/ethernet/arc/Kconfig
> @@ -17,12 +17,16 @@ config NET_VENDOR_ARC
>
>  if NET_VENDOR_ARC
>
> -config ARC_EMAC
> -       tristate "ARC EMAC support"
> +config ARC_EMAC_CORE
> +       bool
>         select MII
>         select PHYLIB
>         depends on OF_IRQ
>         depends on OF_NET
> +
> +config ARC_EMAC
> +       tristate "ARC EMAC support"
> +       select ARC_EMAC_CORE
>         ---help---
>           On some legacy ARC (Synopsys) FPGA boards such as ARCAngel4/ML50x
>           non-standard on-chip ethernet device ARC EMAC 10/100 is used.
> diff --git a/drivers/net/ethernet/arc/Makefile b/drivers/net/ethernet/arc/Makefile
> index 00c8657..241bb80 100644
> --- a/drivers/net/ethernet/arc/Makefile
> +++ b/drivers/net/ethernet/arc/Makefile
> @@ -3,4 +3,5 @@
>  #
>
>  arc_emac-objs := emac_main.o emac_mdio.o
> -obj-$(CONFIG_ARC_EMAC) += arc_emac.o
> +obj-$(CONFIG_ARC_EMAC_CORE) += arc_emac.o
> +obj-$(CONFIG_ARC_EMAC) += emac_arc.o
> diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h
> index 8011445..eb2ba67 100644
> --- a/drivers/net/ethernet/arc/emac.h
> +++ b/drivers/net/ethernet/arc/emac.h
> @@ -124,6 +124,8 @@ struct buffer_state {
>   */
>  struct arc_emac_priv {
>         /* Devices */
> +       const char *drv_name;
> +       const char *drv_version;
>         struct device *dev;
>         struct phy_device *phy_dev;
>         struct mii_bus *bus;
> @@ -206,5 +208,7 @@ static inline void arc_reg_clr(struct arc_emac_priv *priv, int reg, int mask)
>
>  int arc_mdio_probe(struct arc_emac_priv *priv);
>  int arc_mdio_remove(struct arc_emac_priv *priv);
> +int arc_emac_probe(struct net_device *ndev, int interface);
> +int arc_emac_remove(struct net_device *ndev);
>
>  #endif /* ARC_EMAC_H */
> diff --git a/drivers/net/ethernet/arc/emac_arc.c b/drivers/net/ethernet/arc/emac_arc.c
> new file mode 100644
> index 0000000..f9cb99b
> --- /dev/null
> +++ b/drivers/net/ethernet/arc/emac_arc.c
> @@ -0,0 +1,95 @@
> +/**
> + * emac_arc.c - ARC EMAC specific glue layer
> + *
> + * Copyright (C) 2014 Romain Perier
> + *
> + * Romain Perier  <romain.perier@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/etherdevice.h>
> +#include <linux/module.h>
> +#include <linux/of_net.h>
> +#include <linux/platform_device.h>
> +
> +#include "emac.h"
> +
> +#define DRV_NAME    "emac_arc"
> +#define DRV_VERSION "1.0"
> +
> +static int emac_arc_probe(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct net_device *ndev;
> +       struct arc_emac_priv *priv;
> +       int interface, err;
> +
> +       if (!dev->of_node)
> +               return -ENODEV;
> +
> +       ndev = alloc_etherdev(sizeof(struct arc_emac_priv));
> +       if (!ndev)
> +               return -ENOMEM;
> +       platform_set_drvdata(pdev, ndev);
> +       SET_NETDEV_DEV(ndev, dev);
> +
> +       priv = netdev_priv(ndev);
> +       priv->drv_name = DRV_NAME;
> +       priv->drv_version = DRV_VERSION;
> +
> +       interface = of_get_phy_mode(dev->of_node);
> +       if (interface < 0)
> +               interface = PHY_INTERFACE_MODE_MII;
> +
> +       priv->clk = devm_clk_get(dev, "hclk");
> +       if (IS_ERR(priv->clk)) {
> +               dev_err(dev, "failed to retrieve host clock from device tree\n");
> +               err = -EINVAL;
> +               goto out_netdev;
> +       }
> +
> +       err = arc_emac_probe(ndev, interface);
> +out_netdev:
> +       if (err)
> +               free_netdev(ndev);
> +       return err;
> +}
> +
> +static int emac_arc_remove(struct platform_device *pdev)
> +{
> +       struct net_device *ndev = platform_get_drvdata(pdev);
> +       int err;
> +
> +       err = arc_emac_remove(ndev);
> +       free_netdev(ndev);
> +       return err;
> +}
> +
> +static const struct of_device_id emac_arc_dt_ids[] = {
> +       { .compatible = "snps,arc-emac" },
> +       { /* Sentinel */ }
> +};
> +
> +static struct platform_driver emac_arc_driver = {
> +       .probe = emac_arc_probe,
> +       .remove = emac_arc_remove,
> +       .driver = {
> +               .name = DRV_NAME,
> +               .of_match_table  = emac_arc_dt_ids,
> +       },
> +};
> +
> +module_platform_driver(emac_arc_driver);
> +
> +MODULE_AUTHOR("Romain Perier <romain.perier@gmail.com>");
> +MODULE_DESCRIPTION("ARC EMAC platform driver");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
> index bbc3157..b35c69e 100644
> --- a/drivers/net/ethernet/arc/emac_main.c
> +++ b/drivers/net/ethernet/arc/emac_main.c
> @@ -26,8 +26,6 @@
>
>  #include "emac.h"
>
> -#define DRV_NAME       "arc_emac"
> -#define DRV_VERSION    "1.0"
>
>  /**
>   * arc_emac_adjust_link - Adjust the PHY link duplex.
> @@ -120,8 +118,10 @@ static int arc_emac_set_settings(struct net_device *ndev,
>  static void arc_emac_get_drvinfo(struct net_device *ndev,
>                                  struct ethtool_drvinfo *info)
>  {
> -       strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
> -       strlcpy(info->version, DRV_VERSION, sizeof(info->version));
> +       struct arc_emac_priv *priv = netdev_priv(ndev);
> +
> +       strlcpy(info->driver, priv->drv_name, sizeof(info->driver));
> +       strlcpy(info->version, priv->drv_version, sizeof(info->version));
>  }
>
>  static const struct ethtool_ops arc_emac_ethtool_ops = {
> @@ -671,19 +671,16 @@ static const struct net_device_ops arc_emac_netdev_ops = {
>  #endif
>  };
>
> -static int arc_emac_probe(struct platform_device *pdev)
> +int arc_emac_probe(struct net_device *ndev, int interface)
>  {
> -       struct device *dev = &pdev->dev;
> +       struct device *dev = ndev->dev.parent;
>         struct resource res_regs;
>         struct device_node *phy_node;
>         struct arc_emac_priv *priv;
> -       struct net_device *ndev;
>         const char *mac_addr;
>         unsigned int id, clock_frequency, irq;
>         int err;
>
> -       if (!dev->of_node)
> -               return -ENODEV;
>
>         /* Get PHY from device tree */
>         phy_node = of_parse_phandle(dev->of_node, "phy", 0);
> @@ -706,12 +703,6 @@ static int arc_emac_probe(struct platform_device *pdev)
>                 return -ENODEV;
>         }
>
> -       ndev = alloc_etherdev(sizeof(struct arc_emac_priv));
> -       if (!ndev)
> -               return -ENOMEM;
> -
> -       dev_set_drvdata(dev, ndev);
> -       SET_NETDEV_DEV(ndev, dev);
>
>         ndev->netdev_ops = &arc_emac_netdev_ops;
>         ndev->ethtool_ops = &arc_emac_ethtool_ops;
> @@ -724,28 +715,25 @@ static int arc_emac_probe(struct platform_device *pdev)
>
>         priv->regs = devm_ioremap_resource(dev, &res_regs);
>         if (IS_ERR(priv->regs)) {
> -               err = PTR_ERR(priv->regs);
> -               goto out_netdev;
> +               return PTR_ERR(priv->regs);
>         }
>         dev_dbg(dev, "Registers base address is 0x%p\n", priv->regs);
>
> -       priv->clk = of_clk_get(dev->of_node, 0);
> -       if (IS_ERR(priv->clk)) {
> -               /* Get CPU clock frequency from device tree */
> -               if (of_property_read_u32(dev->of_node, "clock-frequency",
> -                                       &clock_frequency)) {
> -                       dev_err(dev, "failed to retrieve <clock-frequency> from device tree\n");
> -                       err = -EINVAL;
> -                       goto out_netdev;
> -               }
> -       } else {
> +       if (priv->clk) {
>                 err = clk_prepare_enable(priv->clk);
>                 if (err) {
>                         dev_err(dev, "failed to enable clock\n");
> -                       goto out_clkget;
> +                       return err;
>                 }
>
>                 clock_frequency = clk_get_rate(priv->clk);
> +       } else {
> +               /* Get CPU clock frequency from device tree */
> +               if (of_property_read_u32(dev->of_node, "clock-frequency",
> +                                        &clock_frequency)) {
> +                       dev_err(dev, "failed to retrieve <clock-frequency> from device tree\n");
> +                       return -EINVAL;
> +               }
>         }
>
>         id = arc_reg_get(priv, R_ID);
> @@ -806,7 +794,7 @@ static int arc_emac_probe(struct platform_device *pdev)
>         }
>
>         priv->phy_dev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0,
> -                                      PHY_INTERFACE_MODE_MII);
> +                                      interface);
>         if (!priv->phy_dev) {
>                 dev_err(dev, "of_phy_connect() failed\n");
>                 err = -ENODEV;
> @@ -833,20 +821,15 @@ out_netif_api:
>  out_mdio:
>         arc_mdio_remove(priv);
>  out_clken:
> -       if (!IS_ERR(priv->clk))
> +       if (priv->clk)
>                 clk_disable_unprepare(priv->clk);
> -out_clkget:
> -       if (!IS_ERR(priv->clk))
> -               clk_put(priv->clk);
> -out_netdev:
> -       free_netdev(ndev);
>         return err;
>  }
> +EXPORT_SYMBOL_GPL(arc_emac_probe);
>
> -static int arc_emac_remove(struct platform_device *pdev)
> +int arc_emac_remove(struct net_device *ndev)
>  {
> -       struct device *dev = &pdev->dev;
> -       struct net_device *ndev = dev_get_drvdata(dev);
> +       struct device *dev = ndev->dev.parent;
>         struct arc_emac_priv *priv = netdev_priv(ndev);
>
>         phy_disconnect(priv->phy_dev);
> @@ -857,31 +840,12 @@ static int arc_emac_remove(struct platform_device *pdev)
>
>         if (!IS_ERR(priv->clk)) {
>                 clk_disable_unprepare(priv->clk);
> -               clk_put(priv->clk);
>         }
>
> -       free_netdev(ndev);
>
>         return 0;
>  }
> -
> -static const struct of_device_id arc_emac_dt_ids[] = {
> -       { .compatible = "snps,arc-emac" },
> -       { /* Sentinel */ }
> -};
> -MODULE_DEVICE_TABLE(of, arc_emac_dt_ids);
> -
> -static struct platform_driver arc_emac_driver = {
> -       .probe = arc_emac_probe,
> -       .remove = arc_emac_remove,
> -       .driver = {
> -               .name = DRV_NAME,
> -               .owner = THIS_MODULE,
> -               .of_match_table  = arc_emac_dt_ids,
> -               },
> -};
> -
> -module_platform_driver(arc_emac_driver);
> +EXPORT_SYMBOL_GPL(arc_emac_remove);
>
>  MODULE_AUTHOR("Alexey Brodkin <abrodkin@synopsys.com>");
>  MODULE_DESCRIPTION("ARC EMAC driver");
> --
> 1.9.1
>

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

* Re: [PATCH v3 3/3] ethernet: arc: Add support for specific SoC glue layer device tree bindings
  2014-08-26  9:23 ` [PATCH v3 3/3] ethernet: arc: Add support for specific SoC glue layer device tree bindings Romain Perier
  2014-08-26  9:26   ` PERIER Romain
@ 2014-08-26  9:44   ` Arnd Bergmann
  1 sibling, 0 replies; 5+ messages in thread
From: Arnd Bergmann @ 2014-08-26  9:44 UTC (permalink / raw)
  To: Romain Perier
  Cc: davem, heiko, tklauser, b.galvani, eric.dumazet, yongjun_wei,
	f.fainelli, netdev

The code changes all look good in this version, but the Kconfig and changelog
are not yet perfect:

On Tuesday 26 August 2014 09:23:52 Romain Perier wrote:
> Some platforms have special bank registers which might be used to select
> the correct clock or the right mode for Media Indepent Interface controllers.
> Sometimes, it is also required to activate vcc regulators in the right order to supply
> the ethernet controller at the right time. This patch is an architecture refactoring
> of the arc-emac device driver. it adds a new software design which allows to add specific
> platform glue layer. Each platform has now its own module which performs custom initialization
> and remove for the target and then calls to the core driver.

Please restrict the changelog line width to something like 70 characters

> diff --git a/drivers/net/ethernet/arc/Kconfig b/drivers/net/ethernet/arc/Kconfig
> index 514c57f..e193826 100644
> --- a/drivers/net/ethernet/arc/Kconfig
> +++ b/drivers/net/ethernet/arc/Kconfig
> @@ -17,12 +17,16 @@ config NET_VENDOR_ARC
>  
>  if NET_VENDOR_ARC
>  
> -config ARC_EMAC
> -	tristate "ARC EMAC support"
> +config ARC_EMAC_CORE
> +	bool

This should be 'tristate', so you can build it as a loadable module
when ARC_EMAC is also a module. Kconfig will ensure it is set to 'y'
if any other built-in driver selects it, or to 'm' if it is selected
only by drivers that are also modules.

>  	select MII
>  	select PHYLIB
>  	depends on OF_IRQ
>  	depends on OF_NET
> +
> +config ARC_EMAC
> +	tristate "ARC EMAC support"
> +	select ARC_EMAC_CORE

The 'depends on' lines need to be moved below, otherwise you can still
enable ARC_EMAC if OF_IRQ and OF_NET are disabled.

	Arnd

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

end of thread, other threads:[~2014-08-26  9:44 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-26  9:23 [PATCH v3 1/3] ethernet: arc: remove use of 'struct platform_device' Romain Perier
2014-08-26  9:23 ` [PATCH v3 2/3] ethernet: arc: mdio refactoring for future specific SoC glue layer devicetree bindings addition Romain Perier
2014-08-26  9:23 ` [PATCH v3 3/3] ethernet: arc: Add support for specific SoC glue layer device tree bindings Romain Perier
2014-08-26  9:26   ` PERIER Romain
2014-08-26  9:44   ` Arnd Bergmann

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.