[<prev] [next>] [day] [month] [year] [list]
Message-Id: <1336133919-26525-13-git-send-email-blogic@openwrt.org>
Date: Fri, 4 May 2012 14:18:38 +0200
From: John Crispin <blogic@...nwrt.org>
To: Ralf Baechle <ralf@...ux-mips.org>
Cc: linux-mips@...ux-mips.org, John Crispin <blogic@...nwrt.org>,
netdev@...r.kernel.org
Subject: [PATCH 13/14] NET: MIPS: lantiq: implement OF support inside the etop driver
This patch makes it possible to load the driver for the ETOP ethernet on
Lantiq SoC from a devicetree.
Additionally we convert the driver to using the new clkdev clock in favour of
the old ltq_pmu_*() api.
Signed-off-by: John Crispin <blogic@...nwrt.org>
Cc: netdev@...r.kernel.org
---
This patch is part of a series moving the mips/lantiq target to OF and clkdev
support. The patch, once Acked, should go upstream via Ralf's MIPS tree.
drivers/net/ethernet/lantiq_etop.c | 63 +++++++++++++++++++++++++++++------
1 files changed, 52 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c
index 5dc9cbd..c0443d4 100644
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -29,19 +29,22 @@
#include <linux/tcp.h>
#include <linux/skbuff.h>
#include <linux/mm.h>
-#include <linux/platform_device.h>
#include <linux/ethtool.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_net.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
#include <asm/checksum.h>
#include <lantiq_soc.h>
#include <xway_dma.h>
-#include <lantiq_platform.h>
#define LTQ_ETOP_MDIO 0x11804
#define MDIO_REQUEST 0x80000000
@@ -73,6 +76,7 @@
#define ETOP_CGEN 0x800
/* use 2 static channels for TX/RX */
+#define LTQ_DMA_CH0_INT INT_NUM_IM2_IRL0
#define LTQ_ETOP_TX_CHANNEL 1
#define LTQ_ETOP_RX_CHANNEL 6
#define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL)
@@ -99,12 +103,17 @@ struct ltq_etop_chan {
struct ltq_etop_priv {
struct net_device *netdev;
struct platform_device *pdev;
- struct ltq_eth_data *pldata;
struct resource *res;
struct mii_bus *mii_bus;
struct phy_device *phydev;
+ struct clk *clk;
+ const void *mac;
+ int mii_mode;
+ int tx_irq;
+ int rx_irq;
+
struct ltq_etop_chan ch[MAX_DMA_CHAN];
int tx_free[MAX_DMA_CHAN >> 1];
@@ -239,7 +248,7 @@ ltq_etop_hw_exit(struct net_device *dev)
struct ltq_etop_priv *priv = netdev_priv(dev);
int i;
- ltq_pmu_disable(PMU_PPE);
+ clk_disable(priv->clk);
for (i = 0; i < MAX_DMA_CHAN; i++)
if (IS_TX(i) || IS_RX(i))
ltq_etop_free_channel(dev, &priv->ch[i]);
@@ -251,9 +260,9 @@ ltq_etop_hw_init(struct net_device *dev)
struct ltq_etop_priv *priv = netdev_priv(dev);
int i;
- ltq_pmu_enable(PMU_PPE);
+ clk_enable(priv->clk);
- switch (priv->pldata->mii_mode) {
+ switch (priv->mii_mode) {
case PHY_INTERFACE_MODE_RMII:
ltq_etop_w32_mask(ETOP_MII_MASK,
ETOP_MII_REVERSE, LTQ_ETOP_CFG);
@@ -266,7 +275,7 @@ ltq_etop_hw_init(struct net_device *dev)
default:
netdev_err(dev, "unknown mii mode %d\n",
- priv->pldata->mii_mode);
+ priv->mii_mode);
return -ENOTSUPP;
}
@@ -395,7 +404,7 @@ ltq_etop_mdio_probe(struct net_device *dev)
}
phydev = phy_connect(dev, dev_name(&phydev->dev), <q_etop_mdio_link,
- 0, priv->pldata->mii_mode);
+ 0, priv->mii_mode);
if (IS_ERR(phydev)) {
netdev_err(dev, "Could not attach to PHY\n");
@@ -643,7 +652,7 @@ ltq_etop_init(struct net_device *dev)
goto err_hw;
ltq_etop_change_mtu(dev, 1500);
- memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
+ memcpy(&mac.sa_data, &priv->mac, ETH_ALEN);
if (!is_valid_ether_addr(mac.sa_data)) {
pr_warn("etop: invalid MAC, using random\n");
random_ether_addr(mac.sa_data);
@@ -707,9 +716,12 @@ static const struct net_device_ops ltq_eth_netdev_ops = {
static int __init
ltq_etop_probe(struct platform_device *pdev)
{
+ struct device_node *node = pdev->dev.of_node;
struct net_device *dev;
struct ltq_etop_priv *priv;
struct resource *res;
+ struct clk *clk;
+ struct resource irqres[2];
int err;
int i;
@@ -737,6 +749,20 @@ ltq_etop_probe(struct platform_device *pdev)
goto err_out;
}
+ err = of_irq_to_resource_table(node, irqres, 2);
+ if (err != 2) {
+ dev_err(&pdev->dev, "not enough irqs defined\n");
+ err = -EINVAL;
+ goto err_out;
+ }
+
+ clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "Failed to get clock\n");
+ err = PTR_ERR(clk);
+ goto err_out;
+ }
+
dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
if (!dev) {
err = -ENOMEM;
@@ -748,9 +774,15 @@ ltq_etop_probe(struct platform_device *pdev)
priv = netdev_priv(dev);
priv->res = res;
priv->pdev = pdev;
- priv->pldata = dev_get_platdata(&pdev->dev);
priv->netdev = dev;
spin_lock_init(&priv->lock);
+ priv->tx_irq = irqres[0].start;
+ priv->rx_irq = irqres[1].start;
+ priv->mii_mode = of_get_phy_mode(node);
+ priv->mac = of_get_mac_address(node);
+ priv->clk = clk;
+ if (priv->mii_mode < 0)
+ priv->mii_mode = PHY_INTERFACE_MODE_MII;
for (i = 0; i < MAX_DMA_CHAN; i++) {
if (IS_TX(i))
@@ -779,21 +811,30 @@ static int __devexit
ltq_etop_remove(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
+ struct ltq_etop_priv *priv = netdev_priv(dev);
if (dev) {
netif_tx_stop_all_queues(dev);
ltq_etop_hw_exit(dev);
ltq_etop_mdio_cleanup(dev);
+ clk_put(priv->clk);
unregister_netdev(dev);
}
return 0;
}
+static const struct of_device_id ltq_etop_match[] = {
+ { .compatible = "lantiq,etop-xway" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ltq_etop_match);
+
static struct platform_driver ltq_mii_driver = {
.remove = __devexit_p(ltq_etop_remove),
.driver = {
- .name = "ltq_etop",
+ .name = "etop-xway",
.owner = THIS_MODULE,
+ .of_match_table = ltq_etop_match,
},
};
--
1.7.9.1
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists