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: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
57d737c5e2
|
@ -4,7 +4,8 @@ This file provides information, what the device node
|
|||
for the davinci_emac interface contains.
|
||||
|
||||
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
|
||||
- ti,davinci-ctrl-reg-offset: offset to control register
|
||||
- ti,davinci-ctrl-mod-reg-offset: offset to control module register
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_mdio.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_net.h>
|
||||
|
||||
|
@ -343,9 +344,7 @@ struct emac_priv {
|
|||
u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS];
|
||||
u32 rx_addr_type;
|
||||
const char *phy_id;
|
||||
#ifdef CONFIG_OF
|
||||
struct device_node *phy_node;
|
||||
#endif
|
||||
struct phy_device *phydev;
|
||||
spinlock_t lock;
|
||||
/*platform specific members*/
|
||||
|
@ -922,6 +921,16 @@ static void emac_int_disable(struct emac_priv *priv)
|
|||
if (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);
|
||||
|
||||
} else {
|
||||
|
@ -951,15 +960,6 @@ static void emac_int_enable(struct emac_priv *priv)
|
|||
* register */
|
||||
|
||||
/* 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 {
|
||||
/* Set DM644x control registers for interrupt control */
|
||||
emac_ctrl_write(EMAC_CTRL_EWCTL, 0x1);
|
||||
|
@ -1537,7 +1537,13 @@ static int emac_dev_open(struct net_device *ndev)
|
|||
int i = 0;
|
||||
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);
|
||||
for (cnt = 0; cnt < ETH_ALEN; cnt++)
|
||||
|
@ -1596,8 +1602,20 @@ static int emac_dev_open(struct net_device *ndev)
|
|||
cpdma_ctlr_start(priv->dma);
|
||||
|
||||
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 */
|
||||
if (!priv->phy_id) {
|
||||
if (!priv->phydev && !priv->phy_id) {
|
||||
struct device *phy;
|
||||
|
||||
phy = bus_find_device(&mdio_bus_type, NULL, NULL,
|
||||
|
@ -1606,7 +1624,7 @@ static int emac_dev_open(struct net_device *ndev)
|
|||
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,
|
||||
&emac_adjust_link,
|
||||
PHY_INTERFACE_MODE_MII);
|
||||
|
@ -1627,7 +1645,9 @@ static int emac_dev_open(struct net_device *ndev)
|
|||
"(mii_bus:phy_addr=%s, id=%x)\n",
|
||||
priv->phydev->drv->name, dev_name(&priv->phydev->dev),
|
||||
priv->phydev->phy_id);
|
||||
} else {
|
||||
}
|
||||
|
||||
if (!priv->phydev) {
|
||||
/* No PHY , fix the link, speed and duplex settings */
|
||||
dev_notice(emac_dev, "no phy, defaulting to 100/full\n");
|
||||
priv->link = 1;
|
||||
|
@ -1724,6 +1744,15 @@ static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev)
|
|||
struct emac_priv *priv = netdev_priv(ndev);
|
||||
u32 mac_control;
|
||||
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*/
|
||||
|
||||
|
@ -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);
|
||||
emac_write(EMAC_TXUNDERRUN, stats_clear_mask);
|
||||
|
||||
pm_runtime_put(&priv->pdev->dev);
|
||||
|
||||
return &ndev->stats;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
int rc = 0;
|
||||
struct resource *res;
|
||||
struct resource *res, *res_ctrl;
|
||||
struct net_device *ndev;
|
||||
struct emac_priv *priv;
|
||||
unsigned long hw_ram_addr;
|
||||
|
@ -1876,6 +1907,7 @@ static int davinci_emac_probe(struct platform_device *pdev)
|
|||
return -EBUSY;
|
||||
}
|
||||
emac_bus_frequency = clk_get_rate(emac_clk);
|
||||
devm_clk_put(&pdev->dev, emac_clk);
|
||||
|
||||
/* TODO: Probe PHY here if possible */
|
||||
|
||||
|
@ -1917,11 +1949,20 @@ static int davinci_emac_probe(struct platform_device *pdev)
|
|||
rc = PTR_ERR(priv->remap_addr);
|
||||
goto no_pdata;
|
||||
}
|
||||
|
||||
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->emac_base = priv->remap_addr + pdata->ctrl_reg_offset;
|
||||
ndev->base_addr = (unsigned long)priv->remap_addr;
|
||||
|
||||
priv->ctrl_base = priv->remap_addr + pdata->ctrl_mod_reg_offset;
|
||||
|
||||
hw_ram_addr = pdata->hw_ram_addr;
|
||||
if (!hw_ram_addr)
|
||||
hw_ram_addr = (u32 __force)res->start + pdata->ctrl_ram_offset;
|
||||
|
@ -1980,12 +2021,22 @@ static int davinci_emac_probe(struct platform_device *pdev)
|
|||
ndev->ethtool_ops = ðtool_ops;
|
||||
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 */
|
||||
SET_NETDEV_DEV(ndev, &pdev->dev);
|
||||
rc = register_netdev(ndev);
|
||||
if (rc) {
|
||||
dev_err(&pdev->dev, "error in register_netdev\n");
|
||||
rc = -ENODEV;
|
||||
pm_runtime_put(&pdev->dev);
|
||||
goto no_cpdma_chan;
|
||||
}
|
||||
|
||||
|
@ -1995,9 +2046,7 @@ static int davinci_emac_probe(struct platform_device *pdev)
|
|||
"(regs: %p, irq: %d)\n",
|
||||
(void *)priv->emac_base_phys, ndev->irq);
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_resume(&pdev->dev);
|
||||
pm_runtime_put(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -2071,9 +2120,14 @@ static const struct emac_platform_data am3517_emac_data = {
|
|||
.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[] = {
|
||||
{.compatible = "ti,davinci-dm6467-emac", },
|
||||
{.compatible = "ti,am3517-emac", .data = &am3517_emac_data, },
|
||||
{.compatible = "ti,dm816-emac", .data = &dm816_emac_data, },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, davinci_emac_of_match);
|
||||
|
|
Загрузка…
Ссылка в новой задаче