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)
/* Copyright 2019 NXP */
#include <linux/acpi.h>
#include <linux/property.h>
#include "dpaa2-eth.h"
#include "dpaa2-mac.h"
......@@ -34,39 +37,51 @@ static int phy_mode(enum dpmac_eth_if eth_if, phy_interface_t *if_mode)
return 0;
}
/* Caller must call of_node_put on the returned value */
static struct device_node *dpaa2_mac_get_node(u16 dpmac_id)
static struct fwnode_handle *dpaa2_mac_get_node(struct device *dev,
u16 dpmac_id)
{
struct device_node *dpmacs, *dpmac = NULL;
u32 id;
struct fwnode_handle *fwnode, *parent, *child = NULL;
struct device_node *dpmacs = NULL;
int err;
u32 id;
dpmacs = of_find_node_by_name(NULL, "dpmacs");
if (!dpmacs)
return NULL;
fwnode = dev_fwnode(dev->parent);
if (is_of_node(fwnode)) {
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) {
err = of_property_read_u32(dpmac, "reg", &id);
fwnode_for_each_child_node(parent, child) {
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)
continue;
if (id == dpmac_id)
break;
}
if (id == dpmac_id) {
of_node_put(dpmacs);
return child;
}
}
of_node_put(dpmacs);
return dpmac;
return NULL;
}
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)
{
phy_interface_t if_mode;
int err;
err = of_get_phy_mode(node, &if_mode);
if (!err)
return if_mode;
err = fwnode_get_phy_mode(dpmac_node);
if (err > 0)
return err;
err = phy_mode(attr.eth_if, &if_mode);
if (!err)
......@@ -235,26 +250,27 @@ static const struct phylink_mac_ops dpaa2_mac_phylink_ops = {
};
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 device_node *node;
struct fwnode_handle *node;
node = of_parse_phandle(dpmac_node, "pcs-handle", 0);
if (!node) {
node = fwnode_find_reference(dpmac_node, "pcs-handle", 0);
if (IS_ERR(node)) {
/* do not error out on old DTS files */
netdev_warn(mac->net_dev, "pcs-handle node not found\n");
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");
of_node_put(node);
fwnode_handle_put(node);
return -ENODEV;
}
mdiodev = of_mdio_find_device(node);
of_node_put(node);
mdiodev = fwnode_mdio_find_device(node);
fwnode_handle_put(node);
if (!mdiodev)
return -EPROBE_DEFER;
......@@ -283,13 +299,13 @@ static void dpaa2_pcs_destroy(struct dpaa2_mac *mac)
int dpaa2_mac_connect(struct dpaa2_mac *mac)
{
struct net_device *net_dev = mac->net_dev;
struct device_node *dpmac_node;
struct fwnode_handle *dpmac_node;
struct phylink *phylink;
int err;
mac->if_link_type = mac->attr.link_type;
dpmac_node = mac->of_node;
dpmac_node = mac->fw_node;
if (!dpmac_node) {
netdev_err(net_dev, "No dpmac@%d node found.\n", mac->attr.id);
return -ENODEV;
......@@ -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
* 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_RXID ||
mac->if_mode == PHY_INTERFACE_MODE_RGMII_TXID)) {
......@@ -324,7 +340,7 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
mac->phylink_config.type = PHYLINK_NETDEV;
phylink = phylink_create(&mac->phylink_config,
of_fwnode_handle(dpmac_node), mac->if_mode,
dpmac_node, mac->if_mode,
&dpaa2_mac_phylink_ops);
if (IS_ERR(phylink)) {
err = PTR_ERR(phylink);
......@@ -335,9 +351,9 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
if (mac->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) {
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;
}
......@@ -384,8 +400,8 @@ int dpaa2_mac_open(struct dpaa2_mac *mac)
/* Find the device node representing the MAC device and link the device
* behind the associated netdev to it.
*/
mac->of_node = dpaa2_mac_get_node(mac->attr.id);
net_dev->dev.of_node = mac->of_node;
mac->fw_node = dpaa2_mac_get_node(&mac->mc_dev->dev, mac->attr.id);
net_dev->dev.of_node = to_of_node(mac->fw_node);
return 0;
......@@ -399,8 +415,8 @@ void dpaa2_mac_close(struct dpaa2_mac *mac)
struct fsl_mc_device *dpmac_dev = mac->mc_dev;
dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle);
if (mac->of_node)
of_node_put(mac->of_node);
if (mac->fw_node)
fwnode_handle_put(mac->fw_node);
}
static char dpaa2_mac_ethtool_stats[][ETH_GSTRING_LEN] = {
......
......@@ -24,7 +24,7 @@ struct dpaa2_mac {
phy_interface_t if_mode;
enum dpmac_link_type if_link_type;
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,
......
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