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: Calvin Johnson <calvin.johnson@oss.nxp.com> Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com> Acked-by: Rafael J. Wysocki <rafael@kernel.org> # from the ACPI side Acked-by: Grant Likely <grant.likely@arm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
423e6e8946
commit
3264f599c1
@ -1,6 +1,9 @@
|
||||
// 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;
|
||||
|
||||
while ((dpmac = of_get_next_child(dpmacs, dpmac)) != NULL) {
|
||||
err = of_property_read_u32(dpmac, "reg", &id);
|
||||
if (err)
|
||||
continue;
|
||||
if (id == dpmac_id)
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
of_node_put(dpmacs);
|
||||
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;
|
||||
|
||||
return dpmac;
|
||||
if (id == dpmac_id) {
|
||||
of_node_put(dpmacs);
|
||||
return child;
|
||||
}
|
||||
}
|
||||
of_node_put(dpmacs);
|
||||
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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user