Commit 57d737c5 authored by David S. Miller's avatar David S. Miller

Merge branch 'davinci_emac'

Tony Lindgren says:

====================
Fixes for davinci_emac

Here's a repost of the fixes for davinci_emac with patches
updated for comments and acks collected.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f812116b de390083
...@@ -4,7 +4,8 @@ This file provides information, what the device node ...@@ -4,7 +4,8 @@ This file provides information, what the device node
for the davinci_emac interface contains. for the davinci_emac interface contains.
Required properties: Required properties:
- compatible: "ti,davinci-dm6467-emac" or "ti,am3517-emac" - compatible: "ti,davinci-dm6467-emac", "ti,am3517-emac" or
"ti,dm816-emac"
- reg: Offset and length of the register set for the device - reg: Offset and length of the register set for the device
- ti,davinci-ctrl-reg-offset: offset to control register - ti,davinci-ctrl-reg-offset: offset to control register
- ti,davinci-ctrl-mod-reg-offset: offset to control module register - ti,davinci-ctrl-mod-reg-offset: offset to control module register
......
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_mdio.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_net.h> #include <linux/of_net.h>
...@@ -343,9 +344,7 @@ struct emac_priv { ...@@ -343,9 +344,7 @@ struct emac_priv {
u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS]; u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS];
u32 rx_addr_type; u32 rx_addr_type;
const char *phy_id; const char *phy_id;
#ifdef CONFIG_OF
struct device_node *phy_node; struct device_node *phy_node;
#endif
struct phy_device *phydev; struct phy_device *phydev;
spinlock_t lock; spinlock_t lock;
/*platform specific members*/ /*platform specific members*/
...@@ -922,6 +921,16 @@ static void emac_int_disable(struct emac_priv *priv) ...@@ -922,6 +921,16 @@ static void emac_int_disable(struct emac_priv *priv)
if (priv->int_disable) if (priv->int_disable)
priv->int_disable(); priv->int_disable();
/* NOTE: Rx Threshold and Misc interrupts are not enabled */
/* ack rxen only then a new pulse will be generated */
emac_write(EMAC_DM646X_MACEOIVECTOR,
EMAC_DM646X_MAC_EOI_C0_RXEN);
/* ack txen- only then a new pulse will be generated */
emac_write(EMAC_DM646X_MACEOIVECTOR,
EMAC_DM646X_MAC_EOI_C0_TXEN);
local_irq_restore(flags); local_irq_restore(flags);
} else { } else {
...@@ -951,15 +960,6 @@ static void emac_int_enable(struct emac_priv *priv) ...@@ -951,15 +960,6 @@ static void emac_int_enable(struct emac_priv *priv)
* register */ * register */
/* NOTE: Rx Threshold and Misc interrupts are not enabled */ /* NOTE: Rx Threshold and Misc interrupts are not enabled */
/* ack rxen only then a new pulse will be generated */
emac_write(EMAC_DM646X_MACEOIVECTOR,
EMAC_DM646X_MAC_EOI_C0_RXEN);
/* ack txen- only then a new pulse will be generated */
emac_write(EMAC_DM646X_MACEOIVECTOR,
EMAC_DM646X_MAC_EOI_C0_TXEN);
} else { } else {
/* Set DM644x control registers for interrupt control */ /* Set DM644x control registers for interrupt control */
emac_ctrl_write(EMAC_CTRL_EWCTL, 0x1); emac_ctrl_write(EMAC_CTRL_EWCTL, 0x1);
...@@ -1537,7 +1537,13 @@ static int emac_dev_open(struct net_device *ndev) ...@@ -1537,7 +1537,13 @@ static int emac_dev_open(struct net_device *ndev)
int i = 0; int i = 0;
struct emac_priv *priv = netdev_priv(ndev); struct emac_priv *priv = netdev_priv(ndev);
pm_runtime_get(&priv->pdev->dev); ret = pm_runtime_get_sync(&priv->pdev->dev);
if (ret < 0) {
pm_runtime_put_noidle(&priv->pdev->dev);
dev_err(&priv->pdev->dev, "%s: failed to get_sync(%d)\n",
__func__, ret);
return ret;
}
netif_carrier_off(ndev); netif_carrier_off(ndev);
for (cnt = 0; cnt < ETH_ALEN; cnt++) for (cnt = 0; cnt < ETH_ALEN; cnt++)
...@@ -1596,8 +1602,20 @@ static int emac_dev_open(struct net_device *ndev) ...@@ -1596,8 +1602,20 @@ static int emac_dev_open(struct net_device *ndev)
cpdma_ctlr_start(priv->dma); cpdma_ctlr_start(priv->dma);
priv->phydev = NULL; priv->phydev = NULL;
if (priv->phy_node) {
priv->phydev = of_phy_connect(ndev, priv->phy_node,
&emac_adjust_link, 0, 0);
if (!priv->phydev) {
dev_err(emac_dev, "could not connect to phy %s\n",
priv->phy_node->full_name);
ret = -ENODEV;
goto err;
}
}
/* use the first phy on the bus if pdata did not give us a phy id */ /* use the first phy on the bus if pdata did not give us a phy id */
if (!priv->phy_id) { if (!priv->phydev && !priv->phy_id) {
struct device *phy; struct device *phy;
phy = bus_find_device(&mdio_bus_type, NULL, NULL, phy = bus_find_device(&mdio_bus_type, NULL, NULL,
...@@ -1606,7 +1624,7 @@ static int emac_dev_open(struct net_device *ndev) ...@@ -1606,7 +1624,7 @@ static int emac_dev_open(struct net_device *ndev)
priv->phy_id = dev_name(phy); priv->phy_id = dev_name(phy);
} }
if (priv->phy_id && *priv->phy_id) { if (!priv->phydev && priv->phy_id && *priv->phy_id) {
priv->phydev = phy_connect(ndev, priv->phy_id, priv->phydev = phy_connect(ndev, priv->phy_id,
&emac_adjust_link, &emac_adjust_link,
PHY_INTERFACE_MODE_MII); PHY_INTERFACE_MODE_MII);
...@@ -1627,7 +1645,9 @@ static int emac_dev_open(struct net_device *ndev) ...@@ -1627,7 +1645,9 @@ static int emac_dev_open(struct net_device *ndev)
"(mii_bus:phy_addr=%s, id=%x)\n", "(mii_bus:phy_addr=%s, id=%x)\n",
priv->phydev->drv->name, dev_name(&priv->phydev->dev), priv->phydev->drv->name, dev_name(&priv->phydev->dev),
priv->phydev->phy_id); priv->phydev->phy_id);
} else { }
if (!priv->phydev) {
/* No PHY , fix the link, speed and duplex settings */ /* No PHY , fix the link, speed and duplex settings */
dev_notice(emac_dev, "no phy, defaulting to 100/full\n"); dev_notice(emac_dev, "no phy, defaulting to 100/full\n");
priv->link = 1; priv->link = 1;
...@@ -1724,6 +1744,15 @@ static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev) ...@@ -1724,6 +1744,15 @@ static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev)
struct emac_priv *priv = netdev_priv(ndev); struct emac_priv *priv = netdev_priv(ndev);
u32 mac_control; u32 mac_control;
u32 stats_clear_mask; u32 stats_clear_mask;
int err;
err = pm_runtime_get_sync(&priv->pdev->dev);
if (err < 0) {
pm_runtime_put_noidle(&priv->pdev->dev);
dev_err(&priv->pdev->dev, "%s: failed to get_sync(%d)\n",
__func__, err);
return &ndev->stats;
}
/* update emac hardware stats and reset the registers*/ /* update emac hardware stats and reset the registers*/
...@@ -1766,6 +1795,8 @@ static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev) ...@@ -1766,6 +1795,8 @@ static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev)
ndev->stats.tx_fifo_errors += emac_read(EMAC_TXUNDERRUN); ndev->stats.tx_fifo_errors += emac_read(EMAC_TXUNDERRUN);
emac_write(EMAC_TXUNDERRUN, stats_clear_mask); emac_write(EMAC_TXUNDERRUN, stats_clear_mask);
pm_runtime_put(&priv->pdev->dev);
return &ndev->stats; return &ndev->stats;
} }
...@@ -1859,7 +1890,7 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv) ...@@ -1859,7 +1890,7 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv)
static int davinci_emac_probe(struct platform_device *pdev) static int davinci_emac_probe(struct platform_device *pdev)
{ {
int rc = 0; int rc = 0;
struct resource *res; struct resource *res, *res_ctrl;
struct net_device *ndev; struct net_device *ndev;
struct emac_priv *priv; struct emac_priv *priv;
unsigned long hw_ram_addr; unsigned long hw_ram_addr;
...@@ -1876,6 +1907,7 @@ static int davinci_emac_probe(struct platform_device *pdev) ...@@ -1876,6 +1907,7 @@ static int davinci_emac_probe(struct platform_device *pdev)
return -EBUSY; return -EBUSY;
} }
emac_bus_frequency = clk_get_rate(emac_clk); emac_bus_frequency = clk_get_rate(emac_clk);
devm_clk_put(&pdev->dev, emac_clk);
/* TODO: Probe PHY here if possible */ /* TODO: Probe PHY here if possible */
...@@ -1917,10 +1949,19 @@ static int davinci_emac_probe(struct platform_device *pdev) ...@@ -1917,10 +1949,19 @@ static int davinci_emac_probe(struct platform_device *pdev)
rc = PTR_ERR(priv->remap_addr); rc = PTR_ERR(priv->remap_addr);
goto no_pdata; goto no_pdata;
} }
priv->emac_base = priv->remap_addr + pdata->ctrl_reg_offset;
ndev->base_addr = (unsigned long)priv->remap_addr;
res_ctrl = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (res_ctrl) {
priv->ctrl_base =
devm_ioremap_resource(&pdev->dev, res_ctrl);
if (IS_ERR(priv->ctrl_base))
goto no_pdata;
} else {
priv->ctrl_base = priv->remap_addr + pdata->ctrl_mod_reg_offset; priv->ctrl_base = priv->remap_addr + pdata->ctrl_mod_reg_offset;
}
priv->emac_base = priv->remap_addr + pdata->ctrl_reg_offset;
ndev->base_addr = (unsigned long)priv->remap_addr;
hw_ram_addr = pdata->hw_ram_addr; hw_ram_addr = pdata->hw_ram_addr;
if (!hw_ram_addr) if (!hw_ram_addr)
...@@ -1980,12 +2021,22 @@ static int davinci_emac_probe(struct platform_device *pdev) ...@@ -1980,12 +2021,22 @@ static int davinci_emac_probe(struct platform_device *pdev)
ndev->ethtool_ops = &ethtool_ops; ndev->ethtool_ops = &ethtool_ops;
netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT); netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT);
pm_runtime_enable(&pdev->dev);
rc = pm_runtime_get_sync(&pdev->dev);
if (rc < 0) {
pm_runtime_put_noidle(&pdev->dev);
dev_err(&pdev->dev, "%s: failed to get_sync(%d)\n",
__func__, rc);
goto no_cpdma_chan;
}
/* register the network device */ /* register the network device */
SET_NETDEV_DEV(ndev, &pdev->dev); SET_NETDEV_DEV(ndev, &pdev->dev);
rc = register_netdev(ndev); rc = register_netdev(ndev);
if (rc) { if (rc) {
dev_err(&pdev->dev, "error in register_netdev\n"); dev_err(&pdev->dev, "error in register_netdev\n");
rc = -ENODEV; rc = -ENODEV;
pm_runtime_put(&pdev->dev);
goto no_cpdma_chan; goto no_cpdma_chan;
} }
...@@ -1995,9 +2046,7 @@ static int davinci_emac_probe(struct platform_device *pdev) ...@@ -1995,9 +2046,7 @@ static int davinci_emac_probe(struct platform_device *pdev)
"(regs: %p, irq: %d)\n", "(regs: %p, irq: %d)\n",
(void *)priv->emac_base_phys, ndev->irq); (void *)priv->emac_base_phys, ndev->irq);
} }
pm_runtime_put(&pdev->dev);
pm_runtime_enable(&pdev->dev);
pm_runtime_resume(&pdev->dev);
return 0; return 0;
...@@ -2071,9 +2120,14 @@ static const struct emac_platform_data am3517_emac_data = { ...@@ -2071,9 +2120,14 @@ static const struct emac_platform_data am3517_emac_data = {
.hw_ram_addr = 0x01e20000, .hw_ram_addr = 0x01e20000,
}; };
static const struct emac_platform_data dm816_emac_data = {
.version = EMAC_VERSION_2,
};
static const struct of_device_id davinci_emac_of_match[] = { static const struct of_device_id davinci_emac_of_match[] = {
{.compatible = "ti,davinci-dm6467-emac", }, {.compatible = "ti,davinci-dm6467-emac", },
{.compatible = "ti,am3517-emac", .data = &am3517_emac_data, }, {.compatible = "ti,am3517-emac", .data = &am3517_emac_data, },
{.compatible = "ti,dm816-emac", .data = &dm816_emac_data, },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, davinci_emac_of_match); MODULE_DEVICE_TABLE(of, davinci_emac_of_match);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment