Commit 3264f599 authored by Calvin Johnson's avatar Calvin Johnson Committed by David S. Miller

net: dpaa2-mac: Add ACPI support for DPAA2 MAC driver

Modify dpaa2_mac_get_node() to get the dpmac fwnode from either
DT or ACPI.

Modify dpaa2_mac_get_if_mode() to get interface mode from dpmac_node
which is a fwnode.

Modify dpaa2_pcs_create() to create pcs from dpmac_node fwnode.

Modify dpaa2_mac_connect() to support ACPI along with DT.
Signed-off-by: default avatarCalvin Johnson <calvin.johnson@oss.nxp.com>
Signed-off-by: default avatarIoana Ciornei <ioana.ciornei@nxp.com>
Acked-by: Rafael J. Wysocki <rafael@kernel.org> # from the ACPI side
Acked-by: default avatarGrant Likely <grant.likely@arm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 423e6e89
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/* Copyright 2019 NXP */ /* Copyright 2019 NXP */
#include <linux/acpi.h>
#include <linux/property.h>
#include "dpaa2-eth.h" #include "dpaa2-eth.h"
#include "dpaa2-mac.h" #include "dpaa2-mac.h"
...@@ -34,39 +37,51 @@ static int phy_mode(enum dpmac_eth_if eth_if, phy_interface_t *if_mode) ...@@ -34,39 +37,51 @@ static int phy_mode(enum dpmac_eth_if eth_if, phy_interface_t *if_mode)
return 0; return 0;
} }
/* Caller must call of_node_put on the returned value */ static struct fwnode_handle *dpaa2_mac_get_node(struct device *dev,
static struct device_node *dpaa2_mac_get_node(u16 dpmac_id) u16 dpmac_id)
{ {
struct device_node *dpmacs, *dpmac = NULL; struct fwnode_handle *fwnode, *parent, *child = NULL;
u32 id; struct device_node *dpmacs = NULL;
int err; int err;
u32 id;
dpmacs = of_find_node_by_name(NULL, "dpmacs"); fwnode = dev_fwnode(dev->parent);
if (!dpmacs) if (is_of_node(fwnode)) {
return NULL; dpmacs = of_find_node_by_name(NULL, "dpmacs");
if (!dpmacs)
return NULL;
parent = of_fwnode_handle(dpmacs);
} else if (is_acpi_node(fwnode)) {
parent = fwnode;
}
while ((dpmac = of_get_next_child(dpmacs, dpmac)) != NULL) { fwnode_for_each_child_node(parent, child) {
err = of_property_read_u32(dpmac, "reg", &id); err = -EINVAL;
if (is_acpi_device_node(child))
err = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), &id);
else if (is_of_node(child))
err = of_property_read_u32(to_of_node(child), "reg", &id);
if (err) if (err)
continue; continue;
if (id == dpmac_id)
break;
}
if (id == dpmac_id) {
of_node_put(dpmacs);
return child;
}
}
of_node_put(dpmacs); of_node_put(dpmacs);
return NULL;
return dpmac;
} }
static int dpaa2_mac_get_if_mode(struct device_node *node, static int dpaa2_mac_get_if_mode(struct fwnode_handle *dpmac_node,
struct dpmac_attr attr) struct dpmac_attr attr)
{ {
phy_interface_t if_mode; phy_interface_t if_mode;
int err; int err;
err = of_get_phy_mode(node, &if_mode); err = fwnode_get_phy_mode(dpmac_node);
if (!err) if (err > 0)
return if_mode; return err;
err = phy_mode(attr.eth_if, &if_mode); err = phy_mode(attr.eth_if, &if_mode);
if (!err) if (!err)
...@@ -235,26 +250,27 @@ static const struct phylink_mac_ops dpaa2_mac_phylink_ops = { ...@@ -235,26 +250,27 @@ static const struct phylink_mac_ops dpaa2_mac_phylink_ops = {
}; };
static int dpaa2_pcs_create(struct dpaa2_mac *mac, static int dpaa2_pcs_create(struct dpaa2_mac *mac,
struct device_node *dpmac_node, int id) struct fwnode_handle *dpmac_node,
int id)
{ {
struct mdio_device *mdiodev; struct mdio_device *mdiodev;
struct device_node *node; struct fwnode_handle *node;
node = of_parse_phandle(dpmac_node, "pcs-handle", 0); node = fwnode_find_reference(dpmac_node, "pcs-handle", 0);
if (!node) { if (IS_ERR(node)) {
/* do not error out on old DTS files */ /* do not error out on old DTS files */
netdev_warn(mac->net_dev, "pcs-handle node not found\n"); netdev_warn(mac->net_dev, "pcs-handle node not found\n");
return 0; return 0;
} }
if (!of_device_is_available(node)) { if (!fwnode_device_is_available(node)) {
netdev_err(mac->net_dev, "pcs-handle node not available\n"); netdev_err(mac->net_dev, "pcs-handle node not available\n");
of_node_put(node); fwnode_handle_put(node);
return -ENODEV; return -ENODEV;
} }
mdiodev = of_mdio_find_device(node); mdiodev = fwnode_mdio_find_device(node);
of_node_put(node); fwnode_handle_put(node);
if (!mdiodev) if (!mdiodev)
return -EPROBE_DEFER; return -EPROBE_DEFER;
...@@ -283,13 +299,13 @@ static void dpaa2_pcs_destroy(struct dpaa2_mac *mac) ...@@ -283,13 +299,13 @@ static void dpaa2_pcs_destroy(struct dpaa2_mac *mac)
int dpaa2_mac_connect(struct dpaa2_mac *mac) int dpaa2_mac_connect(struct dpaa2_mac *mac)
{ {
struct net_device *net_dev = mac->net_dev; struct net_device *net_dev = mac->net_dev;
struct device_node *dpmac_node; struct fwnode_handle *dpmac_node;
struct phylink *phylink; struct phylink *phylink;
int err; int err;
mac->if_link_type = mac->attr.link_type; mac->if_link_type = mac->attr.link_type;
dpmac_node = mac->of_node; dpmac_node = mac->fw_node;
if (!dpmac_node) { if (!dpmac_node) {
netdev_err(net_dev, "No dpmac@%d node found.\n", mac->attr.id); netdev_err(net_dev, "No dpmac@%d node found.\n", mac->attr.id);
return -ENODEV; return -ENODEV;
...@@ -304,7 +320,7 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac) ...@@ -304,7 +320,7 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
* error out if the interface mode requests them and there is no PHY * error out if the interface mode requests them and there is no PHY
* to act upon them * to act upon them
*/ */
if (of_phy_is_fixed_link(dpmac_node) && if (of_phy_is_fixed_link(to_of_node(dpmac_node)) &&
(mac->if_mode == PHY_INTERFACE_MODE_RGMII_ID || (mac->if_mode == PHY_INTERFACE_MODE_RGMII_ID ||
mac->if_mode == PHY_INTERFACE_MODE_RGMII_RXID || mac->if_mode == PHY_INTERFACE_MODE_RGMII_RXID ||
mac->if_mode == PHY_INTERFACE_MODE_RGMII_TXID)) { mac->if_mode == PHY_INTERFACE_MODE_RGMII_TXID)) {
...@@ -324,7 +340,7 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac) ...@@ -324,7 +340,7 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
mac->phylink_config.type = PHYLINK_NETDEV; mac->phylink_config.type = PHYLINK_NETDEV;
phylink = phylink_create(&mac->phylink_config, phylink = phylink_create(&mac->phylink_config,
of_fwnode_handle(dpmac_node), mac->if_mode, dpmac_node, mac->if_mode,
&dpaa2_mac_phylink_ops); &dpaa2_mac_phylink_ops);
if (IS_ERR(phylink)) { if (IS_ERR(phylink)) {
err = PTR_ERR(phylink); err = PTR_ERR(phylink);
...@@ -335,9 +351,9 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac) ...@@ -335,9 +351,9 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
if (mac->pcs) if (mac->pcs)
phylink_set_pcs(mac->phylink, &mac->pcs->pcs); phylink_set_pcs(mac->phylink, &mac->pcs->pcs);
err = phylink_of_phy_connect(mac->phylink, dpmac_node, 0); err = phylink_fwnode_phy_connect(mac->phylink, dpmac_node, 0);
if (err) { if (err) {
netdev_err(net_dev, "phylink_of_phy_connect() = %d\n", err); netdev_err(net_dev, "phylink_fwnode_phy_connect() = %d\n", err);
goto err_phylink_destroy; goto err_phylink_destroy;
} }
...@@ -384,8 +400,8 @@ int dpaa2_mac_open(struct dpaa2_mac *mac) ...@@ -384,8 +400,8 @@ int dpaa2_mac_open(struct dpaa2_mac *mac)
/* Find the device node representing the MAC device and link the device /* Find the device node representing the MAC device and link the device
* behind the associated netdev to it. * behind the associated netdev to it.
*/ */
mac->of_node = dpaa2_mac_get_node(mac->attr.id); mac->fw_node = dpaa2_mac_get_node(&mac->mc_dev->dev, mac->attr.id);
net_dev->dev.of_node = mac->of_node; net_dev->dev.of_node = to_of_node(mac->fw_node);
return 0; return 0;
...@@ -399,8 +415,8 @@ void dpaa2_mac_close(struct dpaa2_mac *mac) ...@@ -399,8 +415,8 @@ void dpaa2_mac_close(struct dpaa2_mac *mac)
struct fsl_mc_device *dpmac_dev = mac->mc_dev; struct fsl_mc_device *dpmac_dev = mac->mc_dev;
dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle); dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle);
if (mac->of_node) if (mac->fw_node)
of_node_put(mac->of_node); fwnode_handle_put(mac->fw_node);
} }
static char dpaa2_mac_ethtool_stats[][ETH_GSTRING_LEN] = { static char dpaa2_mac_ethtool_stats[][ETH_GSTRING_LEN] = {
......
...@@ -24,7 +24,7 @@ struct dpaa2_mac { ...@@ -24,7 +24,7 @@ struct dpaa2_mac {
phy_interface_t if_mode; phy_interface_t if_mode;
enum dpmac_link_type if_link_type; enum dpmac_link_type if_link_type;
struct lynx_pcs *pcs; struct lynx_pcs *pcs;
struct device_node *of_node; struct fwnode_handle *fw_node;
}; };
bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev, bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev,
......
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