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

Commit 96f6360c authored by Jean-Christophe PLAGNIOL-VILLARD's avatar Jean-Christophe PLAGNIOL-VILLARD Committed by David S. Miller
Browse files

net: at91_ether: add dt support



Signed-off-by: default avatarJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Tested-by: default avatarJoachim Eastwood <manabian@gmail.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: netdev@vger.kernel.org
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 47407545
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
* Cadence EMAC Ethernet controller

Required properties:
- compatible: Should be "cdns,[<chip>-]{emac}"
  Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC.
  or the generic form: "cdns,emac".
- reg: Address and length of the register set for the device
- interrupts: Should contain macb interrupt
- phy-mode: String, operation mode of the PHY interface.
  Supported values are: "mii", "rmii".

Optional properties:
- local-mac-address: 6 bytes, mac address

Examples:

	macb0: ethernet@fffc4000 {
		compatible = "cdns,at91rm9200-emac";
		reg = <0xfffc4000 0x4000>;
		interrupts = <21>;
		phy-mode = "rmii";
		local-mac-address = [3a 0e 03 04 05 06];
	};
+66 −7
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@
#include <linux/gfp.h>
#include <linux/phy.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_net.h>

#include "macb.h"

@@ -443,6 +446,50 @@ static const struct net_device_ops at91ether_netdev_ops = {
#endif
};

#if defined(CONFIG_OF)
static const struct of_device_id at91ether_dt_ids[] = {
	{ .compatible = "cdns,at91rm9200-emac" },
	{ .compatible = "cdns,emac" },
	{ /* sentinel */ }
};

MODULE_DEVICE_TABLE(of, at91ether_dt_ids);

static int at91ether_get_phy_mode_dt(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;

	if (np)
		return of_get_phy_mode(np);

	return -ENODEV;
}

static int at91ether_get_hwaddr_dt(struct macb *bp)
{
	struct device_node *np = bp->pdev->dev.of_node;

	if (np) {
		const char *mac = of_get_mac_address(np);
		if (mac) {
			memcpy(bp->dev->dev_addr, mac, ETH_ALEN);
			return 0;
		}
	}

	return -ENODEV;
}
#else
static int at91ether_get_phy_mode_dt(struct platform_device *pdev)
{
	return -ENODEV;
}
static int at91ether_get_hwaddr_dt(struct macb *bp)
{
	return -ENODEV;
}
#endif

/*
 * Detect MAC & PHY and perform ethernet interface initialization
 */
@@ -466,6 +513,7 @@ static int __init at91ether_probe(struct platform_device *pdev)
	lp = netdev_priv(dev);
	lp->pdev = pdev;
	lp->dev = dev;
	if (board_data)
		lp->board_data = *board_data;
	spin_lock_init(&lp->lock);

@@ -496,18 +544,28 @@ static int __init at91ether_probe(struct platform_device *pdev)
	platform_set_drvdata(pdev, dev);
	SET_NETDEV_DEV(dev, &pdev->dev);

	res = at91ether_get_hwaddr_dt(lp);
	if (res < 0)
		get_mac_address(dev);		/* Get ethernet address and store it in dev->dev_addr */

	update_mac_address(dev);	/* Program ethernet address into MAC */

	res = at91ether_get_phy_mode_dt(pdev);
	if (res < 0) {
		if (board_data && board_data->is_rmii)
			lp->phy_interface = PHY_INTERFACE_MODE_RMII;
		else
			lp->phy_interface = PHY_INTERFACE_MODE_MII;
	} else {
		lp->phy_interface = res;
	}

	macb_writel(lp, NCR, 0);

	if (board_data->is_rmii) {
	if (lp->phy_interface == PHY_INTERFACE_MODE_RMII)
		macb_writel(lp, NCFGR, MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG) | MACB_BIT(RM9200_RMII));
		lp->phy_interface = PHY_INTERFACE_MODE_RMII;
	} else {
	else
		macb_writel(lp, NCFGR, MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG));
		lp->phy_interface = PHY_INTERFACE_MODE_MII;
	}

	/* Register the network interface */
	res = register_netdev(dev);
@@ -602,6 +660,7 @@ static struct platform_driver at91ether_driver = {
	.driver		= {
		.name	= DRV_NAME,
		.owner	= THIS_MODULE,
		.of_match_table	= of_match_ptr(at91ether_dt_ids),
	},
};