Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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
+75 −21
Original line number Diff line number Diff line
@@ -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,10 +1949,19 @@ static int davinci_emac_probe(struct platform_device *pdev)
		rc = PTR_ERR(priv->remap_addr);
		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->emac_base = priv->remap_addr + pdata->ctrl_reg_offset;
	ndev->base_addr = (unsigned long)priv->remap_addr;

	hw_ram_addr = pdata->hw_ram_addr;
	if (!hw_ram_addr)
@@ -1980,12 +2021,22 @@ static int davinci_emac_probe(struct platform_device *pdev)
	ndev->ethtool_ops = &ethtool_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);