diff options
author | David S. Miller <davem@davemloft.net> | 2016-06-04 21:32:46 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-06-04 21:32:46 -0400 |
commit | b1c6a3a46b8b49ea6344264c1a24f1e51196761e (patch) | |
tree | c9a6fc9e1528bae3958702c0a97d7a6ed756cc9e | |
parent | 169fbdc6f54ae6b557e404419b5dba919064404b (diff) | |
parent | 63434888aaf1b2e73780f3ada9dcf09bf0f206e1 (diff) | |
download | linux-b1c6a3a46b8b49ea6344264c1a24f1e51196761e.tar.bz2 |
Merge branch 'hns-acpi'
Kejian Yan says:
====================
net: hns: add support of ACPI
This series adds HNS support of acpi. The routine will call some ACPI
helper functions, like acpi_dev_found() and acpi_evaluate_dsm(), which
are not included in other cases. In order to make system compile
successfully in other cases except ACPI, it needs to add relative stub
functions to linux/acpi.h. And we use device property functions instead
of serial helper functions to suport both DT and ACPI cases. And then
add the supports of ACPI for HNS.
change log:
v3->v4:
mii-id gets from dev-name instead of address
v2->v3:
1. add Review-by: Andy Shevchenko
2. fix the potential memory leak
v1 -> v2:
1. use acpi_dev_found() instead of acpi_match_device_ids() to check if
it is a acpi node.
2. use is_of_node() instead of IS_ENABLED() to check if it is a DT node.
3. split the patch("add support of acpi for hns-mdio") into two patches:
3.1 Move to use fwnode_handle
3.2 Add ACPI
4. add the patch which subject is dsaf misc operation method
5. fix the comments by Andy Shevchenko
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
18 files changed, 706 insertions, 262 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c b/drivers/net/ethernet/hisilicon/hns/hnae.c index 3bfe36f9405b..5d3047cc8380 100644 --- a/drivers/net/ethernet/hisilicon/hns/hnae.c +++ b/drivers/net/ethernet/hisilicon/hns/hnae.c @@ -96,16 +96,22 @@ static int __ae_match(struct device *dev, const void *data) { struct hnae_ae_dev *hdev = cls_to_ae_dev(dev); - return hdev->dev->of_node == data; + if (dev_of_node(hdev->dev)) + return (data == &hdev->dev->of_node->fwnode); + else if (is_acpi_node(hdev->dev->fwnode)) + return (data == hdev->dev->fwnode); + + dev_err(dev, "__ae_match cannot read cfg data from OF or acpi\n"); + return 0; } -static struct hnae_ae_dev *find_ae(const struct device_node *ae_node) +static struct hnae_ae_dev *find_ae(const struct fwnode_handle *fwnode) { struct device *dev; - WARN_ON(!ae_node); + WARN_ON(!fwnode); - dev = class_find_device(hnae_class, NULL, ae_node, __ae_match); + dev = class_find_device(hnae_class, NULL, fwnode, __ae_match); return dev ? cls_to_ae_dev(dev) : NULL; } @@ -312,7 +318,7 @@ EXPORT_SYMBOL(hnae_reinit_handle); * return handle ptr or ERR_PTR */ struct hnae_handle *hnae_get_handle(struct device *owner_dev, - const struct device_node *ae_node, + const struct fwnode_handle *fwnode, u32 port_id, struct hnae_buf_ops *bops) { @@ -321,7 +327,7 @@ struct hnae_handle *hnae_get_handle(struct device *owner_dev, int i, j; int ret; - dev = find_ae(ae_node); + dev = find_ae(fwnode); if (!dev) return ERR_PTR(-ENODEV); diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h b/drivers/net/ethernet/hisilicon/hns/hnae.h index e8d36aaea223..529cb1341270 100644 --- a/drivers/net/ethernet/hisilicon/hns/hnae.h +++ b/drivers/net/ethernet/hisilicon/hns/hnae.h @@ -27,6 +27,7 @@ * "cb" means control block */ +#include <linux/acpi.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/module.h> @@ -512,7 +513,7 @@ struct hnae_ae_dev { struct hnae_handle { struct device *owner_dev; /* the device which make use of this handle */ struct hnae_ae_dev *dev; /* the device who provides this handle */ - struct device_node *phy_node; + struct phy_device *phy_dev; phy_interface_t phy_if; u32 if_support; int q_num; @@ -528,7 +529,7 @@ struct hnae_handle { #define ring_to_dev(ring) ((ring)->q->dev->dev) struct hnae_handle *hnae_get_handle(struct device *owner_dev, - const struct device_node *ae_node, + const struct fwnode_handle *fwnode, u32 port_id, struct hnae_buf_ops *bops); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c index 7a757e88c89a..d37b778b4a1b 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c @@ -131,7 +131,7 @@ struct hnae_handle *hns_ae_get_handle(struct hnae_ae_dev *dev, vf_cb->mac_cb = dsaf_dev->mac_cb[port_id]; ae_handle->phy_if = vf_cb->mac_cb->phy_if; - ae_handle->phy_node = vf_cb->mac_cb->phy_node; + ae_handle->phy_dev = vf_cb->mac_cb->phy_dev; ae_handle->if_support = vf_cb->mac_cb->if_support; ae_handle->port_type = vf_cb->mac_cb->mac_type; ae_handle->dport_id = port_id; @@ -637,13 +637,15 @@ static int hns_ae_config_loopback(struct hnae_handle *handle, int ret; struct hnae_vf_cb *vf_cb = hns_ae_get_vf_cb(handle); struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle); + struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev; switch (loop) { case MAC_INTERNALLOOP_PHY: ret = 0; break; case MAC_INTERNALLOOP_SERDES: - ret = hns_mac_config_sds_loopback(vf_cb->mac_cb, en); + ret = dsaf_dev->misc_op->cfg_serdes_loopback(vf_cb->mac_cb, + !!en); break; case MAC_INTERNALLOOP_MAC: ret = hns_mac_config_mac_loopback(vf_cb->mac_cb, loop, en); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c index 44abb08de155..1235c7f2564b 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c @@ -110,7 +110,7 @@ static void hns_gmac_free(void *mac_drv) u32 mac_id = drv->mac_id; - hns_dsaf_ge_srst_by_port(dsaf_dev, mac_id, 0); + dsaf_dev->misc_op->ge_srst(dsaf_dev, mac_id, 0); } static void hns_gmac_set_tx_auto_pause_frames(void *mac_drv, u16 newval) @@ -317,9 +317,9 @@ static void hns_gmac_init(void *mac_drv) port = drv->mac_id; - hns_dsaf_ge_srst_by_port(dsaf_dev, port, 0); + dsaf_dev->misc_op->ge_srst(dsaf_dev, port, 0); mdelay(10); - hns_dsaf_ge_srst_by_port(dsaf_dev, port, 1); + dsaf_dev->misc_op->ge_srst(dsaf_dev, port, 1); mdelay(10); hns_gmac_disable(mac_drv, MAC_COMM_MODE_RX_AND_TX); hns_gmac_tx_loop_pkt_dis(mac_drv); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c index 611581fccf2a..c526558e6367 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c @@ -7,6 +7,7 @@ * (at your option) any later version. */ +#include <linux/acpi.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/kernel.h> @@ -15,7 +16,8 @@ #include <linux/netdevice.h> #include <linux/of.h> #include <linux/of_address.h> -#include <linux/phy_fixed.h> +#include <linux/of_mdio.h> +#include <linux/phy.h> #include <linux/platform_device.h> #include "hns_dsaf_main.h" @@ -94,7 +96,7 @@ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status) else *link_status = 0; - ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt); + ret = mac_cb->dsaf_dev->misc_op->get_sfp_prsnt(mac_cb, &sfp_prsnt); if (!ret) *link_status = *link_status && sfp_prsnt; @@ -511,7 +513,7 @@ void hns_mac_stop(struct hns_mac_cb *mac_cb) mac_ctrl_drv->mac_en_flg = 0; mac_cb->link = 0; - cpld_led_reset(mac_cb); + mac_cb->dsaf_dev->misc_op->cpld_reset_led(mac_cb); } /** @@ -637,6 +639,115 @@ free_mac_drv: return ret; } +static int +hns_mac_phy_parse_addr(struct device *dev, struct fwnode_handle *fwnode) +{ + u32 addr; + int ret; + + ret = fwnode_property_read_u32(fwnode, "phy-addr", &addr); + if (ret) { + dev_err(dev, "has invalid PHY address ret:%d\n", ret); + return ret; + } + + if (addr >= PHY_MAX_ADDR) { + dev_err(dev, "PHY address %i is too large\n", addr); + return -EINVAL; + } + + return addr; +} + +static int hns_mac_phydev_match(struct device *dev, void *fwnode) +{ + return dev->fwnode == fwnode; +} + +static struct +platform_device *hns_mac_find_platform_device(struct fwnode_handle *fwnode) +{ + struct device *dev; + + dev = bus_find_device(&platform_bus_type, NULL, + fwnode, hns_mac_phydev_match); + return dev ? to_platform_device(dev) : NULL; +} + +static int +hns_mac_register_phydev(struct mii_bus *mdio, struct hns_mac_cb *mac_cb, + u32 addr) +{ + struct phy_device *phy; + const char *phy_type; + bool is_c45; + int rc; + + rc = fwnode_property_read_string(mac_cb->fw_port, + "phy-mode", &phy_type); + if (rc < 0) + return rc; + + if (!strcmp(phy_type, phy_modes(PHY_INTERFACE_MODE_XGMII))) + is_c45 = 1; + else if (!strcmp(phy_type, phy_modes(PHY_INTERFACE_MODE_SGMII))) + is_c45 = 0; + else + return -ENODATA; + + phy = get_phy_device(mdio, addr, is_c45); + if (!phy || IS_ERR(phy)) + return -EIO; + + if (mdio->irq) + phy->irq = mdio->irq[addr]; + + /* All data is now stored in the phy struct; + * register it + */ + rc = phy_device_register(phy); + if (rc) { + phy_device_free(phy); + return -ENODEV; + } + + mac_cb->phy_dev = phy; + + dev_dbg(&mdio->dev, "registered phy at address %i\n", addr); + + return 0; +} + +static void hns_mac_register_phy(struct hns_mac_cb *mac_cb) +{ + struct acpi_reference_args args; + struct platform_device *pdev; + struct mii_bus *mii_bus; + int rc; + int addr; + + /* Loop over the child nodes and register a phy_device for each one */ + if (!to_acpi_device_node(mac_cb->fw_port)) + return; + + rc = acpi_node_get_property_reference( + mac_cb->fw_port, "mdio-node", 0, &args); + if (rc) + return; + + addr = hns_mac_phy_parse_addr(mac_cb->dev, mac_cb->fw_port); + if (addr < 0) + return; + + /* dev address in adev */ + pdev = hns_mac_find_platform_device(acpi_fwnode_handle(args.adev)); + mii_bus = platform_get_drvdata(pdev); + rc = hns_mac_register_phydev(mii_bus, mac_cb, addr); + if (!rc) + dev_dbg(mac_cb->dev, "mac%d register phy addr:%d\n", + mac_cb->mac_id, addr); +} + /** *hns_mac_get_info - get mac information from device node *@mac_cb: mac device @@ -645,7 +756,7 @@ free_mac_drv: */ static int hns_mac_get_info(struct hns_mac_cb *mac_cb) { - struct device_node *np = mac_cb->dev->of_node; + struct device_node *np; struct regmap *syscon; struct of_phandle_args cpld_args; u32 ret; @@ -672,63 +783,85 @@ static int hns_mac_get_info(struct hns_mac_cb *mac_cb) * from dsaf node */ if (!mac_cb->fw_port) { - mac_cb->phy_node = of_parse_phandle(np, "phy-handle", - mac_cb->mac_id); - if (mac_cb->phy_node) + np = of_parse_phandle(mac_cb->dev->of_node, "phy-handle", + mac_cb->mac_id); + mac_cb->phy_dev = of_phy_find_device(np); + if (mac_cb->phy_dev) { + /* refcount is held by of_phy_find_device() + * if the phy_dev is found + */ + put_device(&mac_cb->phy_dev->mdio.dev); + dev_dbg(mac_cb->dev, "mac%d phy_node: %s\n", - mac_cb->mac_id, mac_cb->phy_node->name); - return 0; - } - if (!is_of_node(mac_cb->fw_port)) - return -EINVAL; - /* parse property from port subnode in dsaf */ - mac_cb->phy_node = of_parse_phandle(to_of_node(mac_cb->fw_port), - "phy-handle", 0); - if (mac_cb->phy_node) - dev_dbg(mac_cb->dev, "mac%d phy_node: %s\n", - mac_cb->mac_id, mac_cb->phy_node->name); - syscon = syscon_node_to_regmap( - of_parse_phandle(to_of_node(mac_cb->fw_port), - "serdes-syscon", 0)); - if (IS_ERR_OR_NULL(syscon)) { - dev_err(mac_cb->dev, "serdes-syscon is needed!\n"); - return -EINVAL; - } - mac_cb->serdes_ctrl = syscon; + mac_cb->mac_id, np->name); + } - ret = fwnode_property_read_u32(mac_cb->fw_port, - "port-rst-offset", - &mac_cb->port_rst_off); - if (ret) { - dev_dbg(mac_cb->dev, - "mac%d port-rst-offset not found, use default value.\n", - mac_cb->mac_id); + return 0; } - ret = fwnode_property_read_u32(mac_cb->fw_port, - "port-mode-offset", - &mac_cb->port_mode_off); - if (ret) { - dev_dbg(mac_cb->dev, - "mac%d port-mode-offset not found, use default value.\n", - mac_cb->mac_id); - } + if (is_of_node(mac_cb->fw_port)) { + /* parse property from port subnode in dsaf */ + np = of_parse_phandle(to_of_node(mac_cb->fw_port), + "phy-handle", 0); + mac_cb->phy_dev = of_phy_find_device(np); + if (mac_cb->phy_dev) { + /* refcount is held by of_phy_find_device() + * if the phy_dev is found + */ + put_device(&mac_cb->phy_dev->mdio.dev); + dev_dbg(mac_cb->dev, "mac%d phy_node: %s\n", + mac_cb->mac_id, np->name); + } - ret = of_parse_phandle_with_fixed_args(to_of_node(mac_cb->fw_port), - "cpld-syscon", 1, 0, &cpld_args); - if (ret) { - dev_dbg(mac_cb->dev, "mac%d no cpld-syscon found.\n", - mac_cb->mac_id); - mac_cb->cpld_ctrl = NULL; - } else { - syscon = syscon_node_to_regmap(cpld_args.np); + syscon = syscon_node_to_regmap( + of_parse_phandle(to_of_node(mac_cb->fw_port), + "serdes-syscon", 0)); if (IS_ERR_OR_NULL(syscon)) { - dev_dbg(mac_cb->dev, "no cpld-syscon found!\n"); + dev_err(mac_cb->dev, "serdes-syscon is needed!\n"); + return -EINVAL; + } + mac_cb->serdes_ctrl = syscon; + + ret = fwnode_property_read_u32(mac_cb->fw_port, + "port-rst-offset", + &mac_cb->port_rst_off); + if (ret) { + dev_dbg(mac_cb->dev, + "mac%d port-rst-offset not found, use default value.\n", + mac_cb->mac_id); + } + + ret = fwnode_property_read_u32(mac_cb->fw_port, + "port-mode-offset", + &mac_cb->port_mode_off); + if (ret) { + dev_dbg(mac_cb->dev, + "mac%d port-mode-offset not found, use default value.\n", + mac_cb->mac_id); + } + + ret = of_parse_phandle_with_fixed_args( + to_of_node(mac_cb->fw_port), "cpld-syscon", 1, 0, + &cpld_args); + if (ret) { + dev_dbg(mac_cb->dev, "mac%d no cpld-syscon found.\n", + mac_cb->mac_id); mac_cb->cpld_ctrl = NULL; } else { - mac_cb->cpld_ctrl = syscon; - mac_cb->cpld_ctrl_reg = cpld_args.args[0]; + syscon = syscon_node_to_regmap(cpld_args.np); + if (IS_ERR_OR_NULL(syscon)) { + dev_dbg(mac_cb->dev, "no cpld-syscon found!\n"); + mac_cb->cpld_ctrl = NULL; + } else { + mac_cb->cpld_ctrl = syscon; + mac_cb->cpld_ctrl_reg = cpld_args.args[0]; + } } + } else if (is_acpi_node(mac_cb->fw_port)) { + hns_mac_register_phy(mac_cb); + } else { + dev_err(mac_cb->dev, "mac%d cannot find phy node\n", + mac_cb->mac_id); } return 0; @@ -790,7 +923,7 @@ int hns_mac_get_cfg(struct dsaf_device *dsaf_dev, struct hns_mac_cb *mac_cb) else mac_cb->mac_type = HNAE_PORT_DEBUG; - mac_cb->phy_if = hns_mac_get_phy_if(mac_cb); + mac_cb->phy_if = dsaf_dev->misc_op->get_phy_if(mac_cb); ret = hns_mac_get_mode(mac_cb->phy_if); if (ret < 0) { @@ -805,7 +938,7 @@ int hns_mac_get_cfg(struct dsaf_device *dsaf_dev, struct hns_mac_cb *mac_cb) if (ret) return ret; - cpld_led_reset(mac_cb); + mac_cb->dsaf_dev->misc_op->cpld_reset_led(mac_cb); mac_cb->vaddr = hns_mac_get_vaddr(dsaf_dev, mac_cb, mac_mode_idx); return 0; @@ -892,7 +1025,7 @@ void hns_mac_uninit(struct dsaf_device *dsaf_dev) int max_port_num = hns_mac_get_max_port_num(dsaf_dev); for (i = 0; i < max_port_num; i++) { - cpld_led_reset(dsaf_dev->mac_cb[i]); + dsaf_dev->misc_op->cpld_reset_led(dsaf_dev->mac_cb[i]); dsaf_dev->mac_cb[i] = NULL; } } @@ -975,7 +1108,7 @@ void hns_set_led_opt(struct hns_mac_cb *mac_cb) nic_data = 0; mac_cb->txpkt_for_led = mac_cb->hw_stats.tx_good_pkts; mac_cb->rxpkt_for_led = mac_cb->hw_stats.rx_good_pkts; - hns_cpld_set_led(mac_cb, (int)mac_cb->link, + mac_cb->dsaf_dev->misc_op->cpld_set_led(mac_cb, (int)mac_cb->link, mac_cb->speed, nic_data); } @@ -985,5 +1118,5 @@ int hns_cpld_led_set_id(struct hns_mac_cb *mac_cb, if (!mac_cb || !mac_cb->cpld_ctrl) return 0; - return cpld_set_led_id(mac_cb, status); + return mac_cb->dsaf_dev->misc_op->cpld_set_led_id(mac_cb, status); } diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h index 97ce9a750aaf..05a6e8f7a419 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h @@ -338,7 +338,7 @@ struct hns_mac_cb { phy_interface_t phy_if; enum hnae_loop loop_mode; - struct device_node *phy_node; + struct phy_device *phy_dev; struct mac_hw_stats hw_stats; }; @@ -448,8 +448,6 @@ int hns_mac_set_pauseparam(struct hns_mac_cb *mac_cb, u32 rx_en, u32 tx_en); int hns_mac_set_mtu(struct hns_mac_cb *mac_cb, u32 new_mtu); int hns_mac_get_port_info(struct hns_mac_cb *mac_cb, u8 *auto_neg, u16 *speed, u8 *duplex); -phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb); -int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, u8 en); int hns_mac_config_mac_loopback(struct hns_mac_cb *mac_cb, enum hnae_loop loop, int en); void hns_mac_update_stats(struct hns_mac_cb *mac_cb); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c index 1c2ddb25e776..ac03c4a53e08 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c @@ -7,6 +7,7 @@ * (at your option) any later version. */ +#include <linux/acpi.h> #include <linux/device.h> #include <linux/init.h> #include <linux/interrupt.h> @@ -24,6 +25,7 @@ #include "hns_dsaf_main.h" #include "hns_dsaf_ppe.h" #include "hns_dsaf_rcb.h" +#include "hns_dsaf_misc.h" const char *g_dsaf_mode_match[DSAF_MODE_MAX] = { [DSAF_MODE_DISABLE_2PORT_64VM] = "2port-64vf", @@ -32,6 +34,13 @@ const char *g_dsaf_mode_match[DSAF_MODE_MAX] = { [DSAF_MODE_DISABLE_SP] = "single-port", }; +static const struct acpi_device_id hns_dsaf_acpi_match[] = { + { "HISI00B1", 0 }, + { "HISI00B2", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, hns_dsaf_acpi_match); + int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) { int ret, i; @@ -45,12 +54,24 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) struct device_node *np = dsaf_dev->dev->of_node; struct platform_device *pdev = to_platform_device(dsaf_dev->dev); - if (of_device_is_compatible(np, "hisilicon,hns-dsaf-v1")) - dsaf_dev->dsaf_ver = AE_VERSION_1; - else - dsaf_dev->dsaf_ver = AE_VERSION_2; + if (dev_of_node(dsaf_dev->dev)) { + if (of_device_is_compatible(np, "hisilicon,hns-dsaf-v1")) + dsaf_dev->dsaf_ver = AE_VERSION_1; + else + dsaf_dev->dsaf_ver = AE_VERSION_2; + } else if (is_acpi_node(dsaf_dev->dev->fwnode)) { + if (acpi_dev_found(hns_dsaf_acpi_match[0].id)) + dsaf_dev->dsaf_ver = AE_VERSION_1; + else if (acpi_dev_found(hns_dsaf_acpi_match[1].id)) + dsaf_dev->dsaf_ver = AE_VERSION_2; + else + return -ENXIO; + } else { + dev_err(dsaf_dev->dev, "cannot get cfg data from of or acpi\n"); + return -ENXIO; + } - ret = of_property_read_string(np, "mode", &mode_str); + ret = device_property_read_string(dsaf_dev->dev, "mode", &mode_str); if (ret) { dev_err(dsaf_dev->dev, "get dsaf mode fail, ret=%d!\n", ret); return ret; @@ -80,32 +101,40 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) else dsaf_dev->dsaf_tc_mode = HRD_DSAF_4TC_MODE; - syscon = syscon_node_to_regmap( - of_parse_phandle(np, "subctrl-syscon", 0)); - if (IS_ERR_OR_NULL(syscon)) { - res = platform_get_resource(pdev, IORESOURCE_MEM, res_idx++); - if (!res) { - dev_err(dsaf_dev->dev, "subctrl info is needed!\n"); - return -ENOMEM; - } - dsaf_dev->sc_base = devm_ioremap_resource(&pdev->dev, res); - if (!dsaf_dev->sc_base) { - dev_err(dsaf_dev->dev, "subctrl can not map!\n"); - return -ENOMEM; - } + if (dev_of_node(dsaf_dev->dev)) { + syscon = syscon_node_to_regmap( + of_parse_phandle(np, "subctrl-syscon", 0)); + if (IS_ERR_OR_NULL(syscon)) { + res = platform_get_resource(pdev, IORESOURCE_MEM, + res_idx++); + if (!res) { + dev_err(dsaf_dev->dev, "subctrl info is needed!\n"); + return -ENOMEM; + } - res = platform_get_resource(pdev, IORESOURCE_MEM, res_idx++); - if (!res) { - dev_err(dsaf_dev->dev, "serdes-ctrl info is needed!\n"); - return -ENOMEM; - } - dsaf_dev->sds_base = devm_ioremap_resource(&pdev->dev, res); - if (!dsaf_dev->sds_base) { - dev_err(dsaf_dev->dev, "serdes-ctrl can not map!\n"); - return -ENOMEM; + dsaf_dev->sc_base = devm_ioremap_resource(&pdev->dev, + res); + if (!dsaf_dev->sc_base) { + dev_err(dsaf_dev->dev, "subctrl can not map!\n"); + return -ENOMEM; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, + res_idx++); + if (!res) { + dev_err(dsaf_dev->dev, "serdes-ctrl info is needed!\n"); + return -ENOMEM; + } + + dsaf_dev->sds_base = devm_ioremap_resource(&pdev->dev, + res); + if (!dsaf_dev->sds_base) { + dev_err(dsaf_dev->dev, "serdes-ctrl can not map!\n"); + return -ENOMEM; + } + } else { + dsaf_dev->sub_ctrl = syscon; } - } else { - dsaf_dev->sub_ctrl = syscon; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ppe-base"); @@ -142,7 +171,7 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) } } - ret = of_property_read_u32(np, "desc-num", &desc_num); + ret = device_property_read_u32(dsaf_dev->dev, "desc-num", &desc_num); if (ret < 0 || desc_num < HNS_DSAF_MIN_DESC_CNT || desc_num > HNS_DSAF_MAX_DESC_CNT) { dev_err(dsaf_dev->dev, "get desc-num(%d) fail, ret=%d!\n", @@ -151,14 +180,15 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) } dsaf_dev->desc_num = desc_num; - ret = of_property_read_u32(np, "reset-field-offset", &reset_offset); + ret = device_property_read_u32(dsaf_dev->dev, "reset-field-offset", + &reset_offset); if (ret < 0) { dev_dbg(dsaf_dev->dev, "get reset-field-offset fail, ret=%d!\r\n", ret); } dsaf_dev->reset_offset = reset_offset; - ret = of_property_read_u32(np, "buf-size", &buf_size); + ret = device_property_read_u32(dsaf_dev->dev, "buf-size", &buf_size); if (ret < 0) { dev_err(dsaf_dev->dev, "get buf-size fail, ret=%d!\r\n", ret); @@ -173,6 +203,10 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) goto unmap_base_addr; } + dsaf_dev->misc_op = hns_misc_op_get(dsaf_dev); + if (!dsaf_dev->misc_op) + return -ENOMEM; + if (!dma_set_mask_and_coherent(dsaf_dev->dev, DMA_BIT_MASK(64ULL))) dev_dbg(dsaf_dev->dev, "set mask to 64bit\n"); else @@ -1295,9 +1329,9 @@ static int hns_dsaf_init_hw(struct dsaf_device *dsaf_dev) dev_dbg(dsaf_dev->dev, "hns_dsaf_init_hw begin %s !\n", dsaf_dev->ae_dev.name); - hns_dsaf_rst(dsaf_dev, 0); + dsaf_dev->misc_op->dsaf_reset(dsaf_dev, 0); mdelay(10); - hns_dsaf_rst(dsaf_dev, 1); + dsaf_dev->misc_op->dsaf_reset(dsaf_dev, 1); hns_dsaf_comm_init(dsaf_dev); @@ -1325,7 +1359,7 @@ static int hns_dsaf_init_hw(struct dsaf_device *dsaf_dev) static void hns_dsaf_remove_hw(struct dsaf_device *dsaf_dev) { /*reset*/ - hns_dsaf_rst(dsaf_dev, 0); + dsaf_dev->misc_op->dsaf_reset(dsaf_dev, 0); } /** @@ -2680,6 +2714,7 @@ static struct platform_driver g_dsaf_driver = { .driver = { .name = DSAF_DRV_NAME, .of_match_table = g_dsaf_match, + .acpi_match_table = hns_dsaf_acpi_match, }, }; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h index f0502ba0a677..2e55b3cc4515 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h @@ -268,6 +268,27 @@ struct dsaf_int_stat { }; +struct dsaf_misc_op { + void (*cpld_set_led)(struct hns_mac_cb *mac_cb, int link_status, + u16 speed, int data); + void (*cpld_reset_led)(struct hns_mac_cb *mac_cb); + int (*cpld_set_led_id)(struct hns_mac_cb *mac_cb, + enum hnae_led_state status); + /* reset seris function, it will be reset if the dereseet is 0 */ + void (*dsaf_reset)(struct dsaf_device *dsaf_dev, bool dereset); + void (*xge_srst)(struct dsaf_device *dsaf_dev, u32 port, bool dereset); + void (*xge_core_srst)(struct dsaf_device *dsaf_dev, u32 port, + bool dereset); + void (*ge_srst)(struct dsaf_device *dsaf_dev, u32 port, bool dereset); + void (*ppe_srst)(struct dsaf_device *dsaf_dev, u32 port, bool dereset); + void (*ppe_comm_srst)(struct dsaf_device *dsaf_dev, bool dereset); + + phy_interface_t (*get_phy_if)(struct hns_mac_cb *mac_cb); + int (*get_sfp_prsnt)(struct hns_mac_cb *mac_cb, int *sfp_prsnt); + + int (*cfg_serdes_loopback)(struct hns_mac_cb *mac_cb, bool en); +}; + /* Dsaf device struct define ,and mac -> dsaf */ struct dsaf_device { struct device *dev; @@ -292,6 +313,7 @@ struct dsaf_device { struct ppe_common_cb *ppe_common[DSAF_COMM_DEV_NUM]; struct rcb_common_cb *rcb_common[DSAF_COMM_DEV_NUM]; struct hns_mac_cb *mac_cb[DSAF_MAX_PORT_NUM]; + struct dsaf_misc_op *misc_op; struct dsaf_hw_stats hw_stats[DSAF_NODE_NUM]; struct dsaf_int_stat int_stat; @@ -388,22 +410,11 @@ int hns_dsaf_get_mac_entry_by_index( u16 entry_index, struct dsaf_drv_mac_multi_dest_entry *mac_entry); -void hns_dsaf_rst(struct dsaf_device *dsaf_dev, u32 val); - -void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val); - -void hns_ppe_com_srst(struct ppe_common_cb *ppe_common, u32 val); - void hns_dsaf_fix_mac_mode(struct hns_mac_cb *mac_cb); int hns_dsaf_ae_init(struct dsaf_device *dsaf_dev); void hns_dsaf_ae_uninit(struct dsaf_device *dsaf_dev); -void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val); -void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val); -void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev, - u32 port, u32 val); - void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 inode_num); int hns_dsaf_get_sset_count(int stringset); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c index a837bb9e3839..96cb628a7c5f 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c @@ -12,6 +12,27 @@ #include "hns_dsaf_ppe.h" #include "hns_dsaf_reg.h" +enum _dsm_op_index { + HNS_OP_RESET_FUNC = 0x1, + HNS_OP_SERDES_LP_FUNC = 0x2, + HNS_OP_LED_SET_FUNC = 0x3, + HNS_OP_GET_PORT_TYPE_FUNC = 0x4, + HNS_OP_GET_SFP_STAT_FUNC = 0x5, +}; + +enum _dsm_rst_type { + HNS_DSAF_RESET_FUNC = 0x1, + HNS_PPE_RESET_FUNC = 0x2, + HNS_XGE_CORE_RESET_FUNC = 0x3, + HNS_XGE_RESET_FUNC = 0x4, + HNS_GE_RESET_FUNC = 0x5, +}; + +const u8 hns_dsaf_acpi_dsm_uuid[] = { + 0x1A, 0xAA, 0x85, 0x1A, 0x93, 0xE2, 0x5E, 0x41, + 0x8E, 0x28, 0x8D, 0x69, 0x0A, 0x0F, 0x82, 0x0A +}; + static void dsaf_write_sub(struct dsaf_device *dsaf_dev, u32 reg, u32 val) { if (dsaf_dev->sub_ctrl) @@ -32,8 +53,8 @@ static u32 dsaf_read_sub(struct dsaf_device *dsaf_dev, u32 reg) return ret; } -void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status, - u16 speed, int data) +static void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status, + u16 speed, int data) { int speed_reg = 0; u8 value; @@ -71,7 +92,7 @@ void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status, } } -void cpld_led_reset(struct hns_mac_cb *mac_cb) +static void cpld_led_reset(struct hns_mac_cb *mac_cb) { if (!mac_cb || !mac_cb->cpld_ctrl) return; @@ -81,8 +102,8 @@ void cpld_led_reset(struct hns_mac_cb *mac_cb) mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE; } -int cpld_set_led_id(struct hns_mac_cb *mac_cb, - enum hnae_led_state status) +static int cpld_set_led_id(struct hns_mac_cb *mac_cb, + enum hnae_led_state status) { switch (status) { case HNAE_LED_ACTIVE: @@ -109,12 +130,40 @@ int cpld_set_led_id(struct hns_mac_cb *mac_cb, #define RESET_REQ_OR_DREQ 1 -void hns_dsaf_rst(struct dsaf_device *dsaf_dev, u32 val) +static void hns_dsaf_acpi_srst_by_port(struct dsaf_device *dsaf_dev, u8 op_type, + u32 port_type, u32 port, u32 val) +{ + union acpi_object *obj; + union acpi_object obj_args[3], argv4; + + obj_args[0].integer.type = ACPI_TYPE_INTEGER; + obj_args[0].integer.value = port_type; + obj_args[1].integer.type = ACPI_TYPE_INTEGER; + obj_args[1].integer.value = port; + obj_args[2].integer.type = ACPI_TYPE_INTEGER; + obj_args[2].integer.value = val; + + argv4.type = ACPI_TYPE_PACKAGE; + argv4.package.count = 3; + argv4.package.elements = obj_args; + + obj = acpi_evaluate_dsm(ACPI_HANDLE(dsaf_dev->dev), + hns_dsaf_acpi_dsm_uuid, 0, op_type, &argv4); + if (!obj) { + dev_warn(dsaf_dev->dev, "reset port_type%d port%d fail!", + port_type, port); + return; + } + + ACPI_FREE(obj); +} + +static void hns_dsaf_rst(struct dsaf_device *dsaf_dev, bool dereset) { u32 xbar_reg_addr; u32 nt_reg_addr; - if (!val) { + if (!dereset) { xbar_reg_addr = DSAF_SUB_SC_XBAR_RESET_REQ_REG; nt_reg_addr = DSAF_SUB_SC_NT_RESET_REQ_REG; } else { @@ -126,7 +175,15 @@ void hns_dsaf_rst(struct dsaf_device *dsaf_dev, u32 val) dsaf_write_sub(dsaf_dev, nt_reg_addr, RESET_REQ_OR_DREQ); } -void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val) +static void hns_dsaf_rst_acpi(struct dsaf_device *dsaf_dev, bool dereset) +{ + hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC, + HNS_DSAF_RESET_FUNC, + 0, dereset); +} + +static void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, + bool dereset) { u32 reg_val = 0; u32 reg_addr; @@ -137,7 +194,7 @@ void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val) reg_val |= RESET_REQ_OR_DREQ; reg_val |= 0x2082082 << dsaf_dev->mac_cb[port]->port_rst_off; - if (val == 0) + if (!dereset) reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG; else reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG; @@ -145,8 +202,15 @@ void hns_dsaf_xge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val) dsaf_write_sub(dsaf_dev, reg_addr, reg_val); } -void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev, - u32 port, u32 val) +static void hns_dsaf_xge_srst_by_port_acpi(struct dsaf_device *dsaf_dev, + u32 port, bool dereset) +{ + hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC, + HNS_XGE_RESET_FUNC, port, dereset); +} + +static void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev, + u32 port, bool dereset) { u32 reg_val = 0; u32 reg_addr; @@ -157,7 +221,7 @@ void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev, reg_val |= XGMAC_TRX_CORE_SRST_M << dsaf_dev->mac_cb[port]->port_rst_off; - if (val == 0) + if (!dereset) reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG; else reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG; @@ -165,7 +229,16 @@ void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev, dsaf_write_sub(dsaf_dev, reg_addr, reg_val); } -void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val) +static void +hns_dsaf_xge_core_srst_by_port_acpi(struct dsaf_device *dsaf_dev, + u32 port, bool dereset) +{ + hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC, + HNS_XGE_CORE_RESET_FUNC, port, dereset); +} + +static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, + bool dereset) { u32 reg_val_1; u32 reg_val_2; @@ -183,7 +256,7 @@ void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val) else reg_val_2 = 0x2082082 << port_rst_off; - if (val == 0) { + if (!dereset) { dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG, reg_val_1); @@ -200,7 +273,7 @@ void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val) reg_val_1 = 0x15540 << dsaf_dev->reset_offset; reg_val_2 = 0x100 << dsaf_dev->reset_offset; - if (val == 0) { + if (!dereset) { dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG, reg_val_1); @@ -216,14 +289,22 @@ void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val) } } -void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val) +static void hns_dsaf_ge_srst_by_port_acpi(struct dsaf_device *dsaf_dev, + u32 port, bool dereset) +{ + hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC, + HNS_GE_RESET_FUNC, port, dereset); +} + +static void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, + bool dereset) { u32 reg_val = 0; u32 reg_addr; reg_val |= RESET_REQ_OR_DREQ << dsaf_dev->mac_cb[port]->port_rst_off; - if (val == 0) + if (!dereset) reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG; else reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG; @@ -231,15 +312,24 @@ void hns_ppe_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, u32 val) dsaf_write_sub(dsaf_dev, reg_addr, reg_val); } -void hns_ppe_com_srst(struct ppe_common_cb *ppe_common, u32 val) +static void +hns_ppe_srst_by_port_acpi(struct dsaf_device *dsaf_dev, u32 port, bool dereset) +{ + hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC, + HNS_PPE_RESET_FUNC, port, dereset); +} + +static void hns_ppe_com_srst(struct dsaf_device *dsaf_dev, bool dereset) { - struct dsaf_device *dsaf_dev = ppe_common->dsaf_dev; u32 reg_val; u32 reg_addr; + if (!(dev_of_node(dsaf_dev->dev))) + return; + if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) { reg_val = RESET_REQ_OR_DREQ; - if (val == 0) + if (!dereset) reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_REQ_REG; else reg_addr = DSAF_SUB_SC_RCB_PPE_COM_RESET_DREQ_REG; @@ -247,7 +337,7 @@ void hns_ppe_com_srst(struct ppe_common_cb *ppe_common, u32 val) } else { reg_val = 0x100 << dsaf_dev->reset_offset; - if (val == 0) + if (!dereset) reg_addr = DSAF_SUB_SC_PPE_RESET_REQ_REG; else reg_addr = DSAF_SUB_SC_PPE_RESET_DREQ_REG; @@ -261,7 +351,7 @@ void hns_ppe_com_srst(struct ppe_common_cb *ppe_common, u32 val) * @mac_cb: mac control block * retuen phy interface */ -phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb) +static phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb) { u32 mode; u32 reg; @@ -293,6 +383,36 @@ phy_interface_t hns_mac_get_phy_if(struct hns_mac_cb *mac_cb) return phy_if; } +static phy_interface_t hns_mac_get_phy_if_acpi(struct hns_mac_cb *mac_cb) +{ + phy_interface_t phy_if = PHY_INTERFACE_MODE_NA; + union acpi_object *obj; + union acpi_object obj_args, argv4; + + obj_args.integer.type = ACPI_TYPE_INTEGER; + obj_args.integer.value = mac_cb->mac_id; + + argv4.type = ACPI_TYPE_PACKAGE, + argv4.package.count = 1, + argv4.package.elements = &obj_args, + + obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dev), + hns_dsaf_acpi_dsm_uuid, 0, + HNS_OP_GET_PORT_TYPE_FUNC, &argv4); + + if (!obj || obj->type != ACPI_TYPE_INTEGER) + return phy_if; + + phy_if = obj->integer.value ? + PHY_INTERFACE_MODE_XGMII : PHY_INTERFACE_MODE_SGMII; + + dev_dbg(mac_cb->dev, "mac_id=%d, phy_if=%d\n", mac_cb->mac_id, phy_if); + + ACPI_FREE(obj); + + return phy_if; +} + int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt) { if (!mac_cb->cpld_ctrl) @@ -309,7 +429,7 @@ int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt) * @mac_cb: mac control block * retuen 0 == success */ -int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, u8 en) +static int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, bool en) { /* port 0-3 hilink4 base is serdes_vaddr + 0x00280000 * port 4-7 hilink3 base is serdes_vaddr + 0x00200000 @@ -332,7 +452,7 @@ int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, u8 en) int sfp_prsnt; int ret = hns_mac_get_sfp_prsnt(mac_cb, &sfp_prsnt); - if (!mac_cb->phy_node) { + if (!mac_cb->phy_dev) { if (ret) pr_info("please confirm sfp is present or not\n"); else @@ -343,11 +463,89 @@ int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, u8 en) if (mac_cb->serdes_ctrl) { u32 origin = dsaf_read_syscon(mac_cb->serdes_ctrl, reg_offset); - dsaf_set_field(origin, 1ull << 10, 10, !!en); + dsaf_set_field(origin, 1ull << 10, 10, en); dsaf_write_syscon(mac_cb->serdes_ctrl, reg_offset, origin); } else { - dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, !!en); + dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, en); + } + + return 0; +} + +static int +hns_mac_config_sds_loopback_acpi(struct hns_mac_cb *mac_cb, bool en) +{ + union acpi_object *obj; + union acpi_object obj_args[3], argv4; + + obj_args[0].integer.type = ACPI_TYPE_INTEGER; + obj_args[0].integer.value = mac_cb->mac_id; + obj_args[1].integer.type = ACPI_TYPE_INTEGER; + obj_args[1].integer.value = !!en; + + argv4.type = ACPI_TYPE_PACKAGE; + argv4.package.count = 2; + argv4.package.elements = obj_args; + + obj = acpi_evaluate_dsm(ACPI_HANDLE(mac_cb->dsaf_dev->dev), + hns_dsaf_acpi_dsm_uuid, 0, + HNS_OP_SERDES_LP_FUNC, &argv4); + if (!obj) { + dev_warn(mac_cb->dsaf_dev->dev, "set port%d serdes lp fail!", + mac_cb->mac_id); + + return -ENOTSUPP; } + ACPI_FREE(obj); + return 0; } + +struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev) +{ + struct dsaf_misc_op *misc_op; + + misc_op = devm_kzalloc(dsaf_dev->dev, sizeof(*misc_op), GFP_KERNEL); + if (!misc_op) + return NULL; + + if (dev_of_node(dsaf_dev->dev)) { + misc_op->cpld_set_led = hns_cpld_set_led; + misc_op->cpld_reset_led = cpld_led_reset; + misc_op->cpld_set_led_id = cpld_set_led_id; + + misc_op->dsaf_reset = hns_dsaf_rst; + misc_op->xge_srst = hns_dsaf_xge_srst_by_port; + misc_op->xge_core_srst = hns_dsaf_xge_core_srst_by_port; + misc_op->ge_srst = hns_dsaf_ge_srst_by_port; + misc_op->ppe_srst = hns_ppe_srst_by_port; + misc_op->ppe_comm_srst = hns_ppe_com_srst; + + misc_op->get_phy_if = hns_mac_get_phy_if; + misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt; + + misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback; + } else if (is_acpi_node(dsaf_dev->dev->fwnode)) { + misc_op->cpld_set_led = hns_cpld_set_led; + misc_op->cpld_reset_led = cpld_led_reset; + misc_op->cpld_set_led_id = cpld_set_led_id; + + misc_op->dsaf_reset = hns_dsaf_rst_acpi; + misc_op->xge_srst = hns_dsaf_xge_srst_by_port_acpi; + misc_op->xge_core_srst = hns_dsaf_xge_core_srst_by_port_acpi; + misc_op->ge_srst = hns_dsaf_ge_srst_by_port_acpi; + misc_op->ppe_srst = hns_ppe_srst_by_port_acpi; + misc_op->ppe_comm_srst = hns_ppe_com_srst; + + misc_op->get_phy_if = hns_mac_get_phy_if_acpi; + misc_op->get_sfp_prsnt = hns_mac_get_sfp_prsnt; + + misc_op->cfg_serdes_loopback = hns_mac_config_sds_loopback_acpi; + } else { + devm_kfree(dsaf_dev->dev, (void *)misc_op); + misc_op = NULL; + } + + return (void *)misc_op; +} diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.h index 419f07aa9734..f06bb03d47a6 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.h @@ -33,11 +33,6 @@ #define DSAF_LED_DATA_B 4 #define DSAF_LED_ANCHOR_B 5 -void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status, - u16 speed, int data); -void cpld_led_reset(struct hns_mac_cb *mac_cb); -int cpld_set_led_id(struct hns_mac_cb *mac_cb, - enum hnae_led_state status); -int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt); +struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev); #endif diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c index 8cd151a5245e..ff8b6a468b24 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c @@ -112,7 +112,6 @@ void hns_ppe_common_free_cfg(struct dsaf_device *dsaf_dev, u32 comm_index) static void __iomem *hns_ppe_get_iobase(struct ppe_common_cb *ppe_common, int ppe_idx) { - return ppe_common->dsaf_dev->ppe_base + ppe_idx * PPE_REG_OFFSET; } @@ -200,11 +199,12 @@ static void hns_ppe_set_port_mode(struct hns_ppe_cb *ppe_cb, static int hns_ppe_common_init_hw(struct ppe_common_cb *ppe_common) { enum ppe_qid_mode qid_mode; - enum dsaf_mode dsaf_mode = ppe_common->dsaf_dev->dsaf_mode; + struct dsaf_device *dsaf_dev = ppe_common->dsaf_dev; + enum dsaf_mode dsaf_mode = dsaf_dev->dsaf_mode; - hns_ppe_com_srst(ppe_common, 0); + dsaf_dev->misc_op->ppe_comm_srst(dsaf_dev, 0); mdelay(100); - hns_ppe_com_srst(ppe_common, 1); + dsaf_dev->misc_op->ppe_comm_srst(dsaf_dev, 1); mdelay(100); if (ppe_common->ppe_mode == PPE_COMMON_MODE_SERVICE) { @@ -288,9 +288,9 @@ static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb) /* get default RSS key */ netdev_rss_key_fill(ppe_cb->rss_key, HNS_PPEV2_RSS_KEY_SIZE); - hns_ppe_srst_by_port(dsaf_dev, port, 0); + dsaf_dev->misc_op->ppe_srst(dsaf_dev, port, 0); mdelay(10); - hns_ppe_srst_by_port(dsaf_dev, port, 1); + dsaf_dev->misc_op->ppe_srst(dsaf_dev, port, 1); /* clr and msk except irq*/ hns_ppe_exc_irq_en(ppe_cb, 0); @@ -328,10 +328,11 @@ static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb) static void hns_ppe_uninit_hw(struct hns_ppe_cb *ppe_cb) { u32 port; + struct dsaf_device *dsaf_dev = ppe_cb->ppe_common_cb->dsaf_dev; if (ppe_cb->ppe_common_cb) { port = ppe_cb->index; - hns_ppe_srst_by_port(ppe_cb->ppe_common_cb->dsaf_dev, port, 0); + dsaf_dev->misc_op->ppe_srst(dsaf_dev, port, 0); } } diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c index 4ef6d23d998e..3ce24097fcf4 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c @@ -458,7 +458,6 @@ void hns_rcb_get_cfg(struct rcb_common_cb *rcb_common) u32 i; u32 ring_num = rcb_common->ring_num; int base_irq_idx = hns_rcb_get_base_irq_idx(rcb_common); - struct device_node *np = rcb_common->dsaf_dev->dev->of_node; struct platform_device *pdev = to_platform_device(rcb_common->dsaf_dev->dev); bool is_ver1 = AE_IS_VER1(rcb_common->dsaf_dev->dsaf_ver); @@ -473,10 +472,10 @@ void hns_rcb_get_cfg(struct rcb_common_cb *rcb_common) ring_pair_cb->port_id_in_comm = hns_rcb_get_port_in_comm(rcb_common, i); ring_pair_cb->virq[HNS_RCB_IRQ_IDX_TX] = - is_ver1 ? irq_of_parse_and_map(np, base_irq_idx + i * 2) : + is_ver1 ? platform_get_irq(pdev, base_irq_idx + i * 2) : platform_get_irq(pdev, base_irq_idx + i * 3 + 1); ring_pair_cb->virq[HNS_RCB_IRQ_IDX_RX] = - is_ver1 ? irq_of_parse_and_map(np, base_irq_idx + i * 2 + 1) : + is_ver1 ? platform_get_irq(pdev, base_irq_idx + i * 2 + 1) : platform_get_irq(pdev, base_irq_idx + i * 3); ring_pair_cb->q.phy_base = RCB_COMM_BASE_TO_RING_BASE(rcb_common->phy_base, i); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c index fd90f3737963..8f4f0e8da984 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c @@ -119,7 +119,7 @@ static void hns_xgmac_enable(void *mac_drv, enum mac_commom_mode mode) = (struct dsaf_device *)dev_get_drvdata(drv->dev); u32 port = drv->mac_id; - hns_dsaf_xge_core_srst_by_port(dsaf_dev, port, 1); + dsaf_dev->misc_op->xge_core_srst(dsaf_dev, port, 1); mdelay(10); /*enable XGE rX/tX */ @@ -157,7 +157,7 @@ static void hns_xgmac_disable(void *mac_drv, enum mac_commom_mode mode) } mdelay(10); - hns_dsaf_xge_core_srst_by_port(dsaf_dev, port, 0); + dsaf_dev->misc_op->xge_core_srst(dsaf_dev, port, 0); } /** @@ -198,9 +198,9 @@ static void hns_xgmac_init(void *mac_drv) = (struct dsaf_device *)dev_get_drvdata(drv->dev); u32 port = drv->mac_id; - hns_dsaf_xge_srst_by_port(dsaf_dev, port, 0); + dsaf_dev->misc_op->xge_srst(dsaf_dev, port, 0); mdelay(100); - hns_dsaf_xge_srst_by_port(dsaf_dev, port, 1); + dsaf_dev->misc_op->xge_srst(dsaf_dev, port, 1); mdelay(100); hns_xgmac_exc_irq_en(drv, 0); @@ -425,7 +425,7 @@ static void hns_xgmac_free(void *mac_drv) u32 mac_id = drv->mac_id; - hns_dsaf_xge_srst_by_port(dsaf_dev, mac_id, 0); + dsaf_dev->misc_op->xge_srst(dsaf_dev, mac_id, 0); } /** diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c index e621636e69b9..ad742a6f5879 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -132,6 +132,13 @@ static void fill_v2_desc(struct hnae_ring *ring, void *priv, ring_ptr_move_fw(ring, next_to_use); } +static const struct acpi_device_id hns_enet_acpi_match[] = { + { "HISI00C1", 0 }, + { "HISI00C2", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, hns_enet_acpi_match); + static void fill_desc(struct hnae_ring *ring, void *priv, int size, dma_addr_t dma, int frag_end, int buf_num, enum hns_desc_type type, int mtu) @@ -996,19 +1003,22 @@ static void hns_nic_adjust_link(struct net_device *ndev) int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h) { struct hns_nic_priv *priv = netdev_priv(ndev); - struct phy_device *phy_dev = NULL; + struct phy_device *phy_dev = h->phy_dev; + int ret; - if (!h->phy_node) + if (!h->phy_dev) return 0; - if (h->phy_if != PHY_INTERFACE_MODE_XGMII) - phy_dev = of_phy_connect(ndev, h->phy_node, - hns_nic_adjust_link, 0, h->phy_if); - else - phy_dev = of_phy_attach(ndev, h->phy_node, 0, h->phy_if); + if (h->phy_if != PHY_INTERFACE_MODE_XGMII) { + phy_dev->dev_flags = 0; - if (unlikely(!phy_dev) || IS_ERR(phy_dev)) - return !phy_dev ? -ENODEV : PTR_ERR(phy_dev); + ret = phy_connect_direct(ndev, phy_dev, hns_nic_adjust_link, + h->phy_if); + } else { + ret = phy_attach_direct(ndev, phy_dev, 0, h->phy_if); + } + if (unlikely(ret)) + return -ENODEV; phy_dev->supported &= h->if_support; phy_dev->advertising = phy_dev->supported; @@ -1067,13 +1077,8 @@ void hns_nic_update_stats(struct net_device *netdev) static void hns_init_mac_addr(struct net_device *ndev) { struct hns_nic_priv *priv = netdev_priv(ndev); - struct device_node *node = priv->dev->of_node; - const void *mac_addr_temp; - mac_addr_temp = of_get_mac_address(node); - if (mac_addr_temp && is_valid_ether_addr(mac_addr_temp)) { - memcpy(ndev->dev_addr, mac_addr_temp, ndev->addr_len); - } else { + if (!device_get_mac_address(priv->dev, ndev->dev_addr, ETH_ALEN)) { eth_hw_addr_random(ndev); dev_warn(priv->dev, "No valid mac, use random mac %pM", ndev->dev_addr); @@ -1812,7 +1817,7 @@ static int hns_nic_try_get_ae(struct net_device *ndev) int ret; h = hnae_get_handle(&priv->netdev->dev, - priv->ae_node, priv->port_id, NULL); + priv->fwnode, priv->port_id, NULL); if (IS_ERR_OR_NULL(h)) { ret = -ENODEV; dev_dbg(priv->dev, "has not handle, register notifier!\n"); @@ -1872,7 +1877,6 @@ static int hns_nic_dev_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct net_device *ndev; struct hns_nic_priv *priv; - struct device_node *node = dev->of_node; u32 port_id; int ret; @@ -1886,22 +1890,49 @@ static int hns_nic_dev_probe(struct platform_device *pdev) priv->dev = dev; priv->netdev = ndev; - if (of_device_is_compatible(node, "hisilicon,hns-nic-v1")) - priv->enet_ver = AE_VERSION_1; - else - priv->enet_ver = AE_VERSION_2; + if (dev_of_node(dev)) { + struct device_node *ae_node; + + if (of_device_is_compatible(dev->of_node, + "hisilicon,hns-nic-v1")) + priv->enet_ver = AE_VERSION_1; + else + priv->enet_ver = AE_VERSION_2; - priv->ae_node = (void *)of_parse_phandle(node, "ae-handle", 0); - if (IS_ERR_OR_NULL(priv->ae_node)) { - ret = PTR_ERR(priv->ae_node); - dev_err(dev, "not find ae-handle\n"); - goto out_read_prop_fail; + ae_node = of_parse_phandle(dev->of_node, "ae-handle", 0); + if (IS_ERR_OR_NULL(ae_node)) { + ret = PTR_ERR(ae_node); + dev_err(dev, "not find ae-handle\n"); + goto out_read_prop_fail; + } + priv->fwnode = &ae_node->fwnode; + } else if (is_acpi_node(dev->fwnode)) { + struct acpi_reference_args args; + + if (acpi_dev_found(hns_enet_acpi_match[0].id)) + priv->enet_ver = AE_VERSION_1; + else if (acpi_dev_found(hns_enet_acpi_match[1].id)) + priv->enet_ver = AE_VERSION_2; + else + return -ENXIO; + + /* try to find port-idx-in-ae first */ + ret = acpi_node_get_property_reference(dev->fwnode, + "ae-handle", 0, &args); + if (ret) { + dev_err(dev, "not find ae-handle\n"); + goto out_read_prop_fail; + } + priv->fwnode = acpi_fwnode_handle(args.adev); + } else { + dev_err(dev, "cannot read cfg data from OF or acpi\n"); + return -ENXIO; } - /* try to find port-idx-in-ae first */ - ret = of_property_read_u32(node, "port-idx-in-ae", &port_id); + + ret = device_property_read_u32(dev, "port-idx-in-ae", &port_id); if (ret) { /* only for old code compatible */ - ret = of_property_read_u32(node, "port-id", &port_id); + ret = device_property_read_u32(dev, "port-id", &port_id); if (ret) goto out_read_prop_fail; /* for old dts, we need to caculate the port offset */ @@ -2014,6 +2045,7 @@ static struct platform_driver hns_nic_dev_driver = { .driver = { .name = "hns-nic", .of_match_table = hns_enet_of_match, + .acpi_match_table = ACPI_PTR(hns_enet_acpi_match), }, .probe = hns_nic_dev_probe, .remove = hns_nic_dev_remove, diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.h b/drivers/net/ethernet/hisilicon/hns/hns_enet.h index 337efa582bac..44bb3015eed3 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.h @@ -54,7 +54,7 @@ struct hns_nic_ops { }; struct hns_nic_priv { - const struct device_node *ae_node; + const struct fwnode_handle *fwnode; u32 enet_ver; u32 port_id; int phy_mode; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c index 67a648c7d3a9..a809f52f6c16 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c @@ -596,7 +596,7 @@ static void hns_nic_self_test(struct net_device *ndev, st_param[1][0] = MAC_INTERNALLOOP_SERDES; st_param[1][1] = 1; /*serdes must exist*/ st_param[2][0] = MAC_INTERNALLOOP_PHY; /* only supporte phy node*/ - st_param[2][1] = ((!!(priv->ae_handle->phy_node)) && + st_param[2][1] = ((!!(priv->ae_handle->phy_dev)) && (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII)); if (eth_test->flags == ETH_TEST_FL_OFFLINE) { diff --git a/drivers/net/ethernet/hisilicon/hns_mdio.c b/drivers/net/ethernet/hisilicon/hns_mdio.c index 765ddb3dcd1a..761a32fceceb 100644 --- a/drivers/net/ethernet/hisilicon/hns_mdio.c +++ b/drivers/net/ethernet/hisilicon/hns_mdio.c @@ -7,6 +7,7 @@ * (at your option) any later version. */ +#include <linux/acpi.h> #include <linux/errno.h> #include <linux/etherdevice.h> #include <linux/init.h> @@ -354,67 +355,64 @@ static int hns_mdio_reset(struct mii_bus *bus) struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv; int ret; - if (!mdio_dev->subctrl_vbase) { - dev_err(&bus->dev, "mdio sys ctl reg has not maped\n"); - return -ENODEV; - } - - /*1. reset req, and read reset st check*/ - ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_RESET_REQ, 0x1, - MDIO_SC_RESET_ST, 0x1, - MDIO_CHECK_SET_ST); - if (ret) { - dev_err(&bus->dev, "MDIO reset fail\n"); - return ret; - } + if (dev_of_node(bus->parent)) { + if (!mdio_dev->subctrl_vbase) { + dev_err(&bus->dev, "mdio sys ctl reg has not maped\n"); + return -ENODEV; + } - /*2. dis clk, and read clk st check*/ - ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_CLK_DIS, - 0x1, MDIO_SC_CLK_ST, 0x1, - MDIO_CHECK_CLR_ST); - if (ret) { - dev_err(&bus->dev, "MDIO dis clk fail\n"); - return ret; - } + /* 1. reset req, and read reset st check */ + ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_RESET_REQ, 0x1, + MDIO_SC_RESET_ST, 0x1, + MDIO_CHECK_SET_ST); + if (ret) { + dev_err(&bus->dev, "MDIO reset fail\n"); + return ret; + } - /*3. reset dreq, and read reset st check*/ - ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_RESET_DREQ, 0x1, - MDIO_SC_RESET_ST, 0x1, - MDIO_CHECK_CLR_ST); - if (ret) { - dev_err(&bus->dev, "MDIO dis clk fail\n"); - return ret; - } + /* 2. dis clk, and read clk st check */ + ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_CLK_DIS, + 0x1, MDIO_SC_CLK_ST, 0x1, + MDIO_CHECK_CLR_ST); + if (ret) { + dev_err(&bus->dev, "MDIO dis clk fail\n"); + return ret; + } - /*4. en clk, and read clk st check*/ - ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_CLK_EN, - 0x1, MDIO_SC_CLK_ST, 0x1, - MDIO_CHECK_SET_ST); - if (ret) - dev_err(&bus->dev, "MDIO en clk fail\n"); + /* 3. reset dreq, and read reset st check */ + ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_RESET_DREQ, 0x1, + MDIO_SC_RESET_ST, 0x1, + MDIO_CHECK_CLR_ST); + if (ret) { + dev_err(&bus->dev, "MDIO dis clk fail\n"); + return ret; + } + /* 4. en clk, and read clk st check */ + ret = mdio_sc_cfg_reg_write(mdio_dev, MDIO_SC_CLK_EN, + 0x1, MDIO_SC_CLK_ST, 0x1, + MDIO_CHECK_SET_ST); + if (ret) + dev_err(&bus->dev, "MDIO en clk fail\n"); + } else if (is_acpi_node(bus->parent->fwnode)) { + acpi_status s; + + s = acpi_evaluate_object(ACPI_HANDLE(bus->parent), + "_RST", NULL, NULL); + if (ACPI_FAILURE(s)) { + dev_err(&bus->dev, "Reset failed, return:%#x\n", s); + ret = -EBUSY; + } else { + ret = 0; + } + } else { + dev_err(&bus->dev, "Can not get cfg data from DT or ACPI\n"); + ret = -ENXIO; + } return ret; } /** - * hns_mdio_bus_name - get mdio bus name - * @name: mdio bus name - * @np: mdio device node pointer - */ -static void hns_mdio_bus_name(char *name, struct device_node *np) -{ - const u32 *addr; - u64 taddr = OF_BAD_ADDR; - - addr = of_get_address(np, 0, NULL, NULL); - if (addr) - taddr = of_translate_address(np, addr); - - snprintf(name, MII_BUS_ID_SIZE, "%s@%llx", np->name, - (unsigned long long)taddr); -} - -/** * hns_mdio_probe - probe mdio device * @pdev: mdio platform device * @@ -422,17 +420,16 @@ static void hns_mdio_bus_name(char *name, struct device_node *np) */ static int hns_mdio_probe(struct platform_device *pdev) { - struct device_node *np; struct hns_mdio_device *mdio_dev; struct mii_bus *new_bus; struct resource *res; - int ret; + int ret = -ENODEV; if (!pdev) { dev_err(NULL, "pdev is NULL!\r\n"); return -ENODEV; } - np = pdev->dev.of_node; + mdio_dev = devm_kzalloc(&pdev->dev, sizeof(*mdio_dev), GFP_KERNEL); if (!mdio_dev) return -ENOMEM; @@ -448,7 +445,7 @@ static int hns_mdio_probe(struct platform_device *pdev) new_bus->write = hns_mdio_write; new_bus->reset = hns_mdio_reset; new_bus->priv = mdio_dev; - hns_mdio_bus_name(new_bus->id, np); + new_bus->parent = &pdev->dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mdio_dev->vbase = devm_ioremap_resource(&pdev->dev, res); @@ -457,16 +454,32 @@ static int hns_mdio_probe(struct platform_device *pdev) return ret; } - mdio_dev->subctrl_vbase = - syscon_node_to_regmap(of_parse_phandle(np, "subctrl-vbase", 0)); - if (IS_ERR(mdio_dev->subctrl_vbase)) { - dev_warn(&pdev->dev, "no syscon hisilicon,peri-c-subctrl\n"); - mdio_dev->subctrl_vbase = NULL; - } - new_bus->parent = &pdev->dev; platform_set_drvdata(pdev, new_bus); + snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%s", "Mii", + dev_name(&pdev->dev)); + if (dev_of_node(&pdev->dev)) { + mdio_dev->subctrl_vbase = syscon_node_to_regmap( + of_parse_phandle(pdev->dev.of_node, + "subctrl-vbase", 0)); + if (IS_ERR(mdio_dev->subctrl_vbase)) { + dev_warn(&pdev->dev, "no syscon hisilicon,peri-c-subctrl\n"); + mdio_dev->subctrl_vbase = NULL; + } + ret = of_mdiobus_register(new_bus, pdev->dev.of_node); + } else if (is_acpi_node(pdev->dev.fwnode)) { + /* Clear all the IRQ properties */ + memset(new_bus->irq, PHY_POLL, 4 * PHY_MAX_ADDR); + + /* Mask out all PHYs from auto probing. */ + new_bus->phy_mask = ~0; + + /* Register the MDIO bus */ + ret = mdiobus_register(new_bus); + } else { + dev_err(&pdev->dev, "Can not get cfg data from DT or ACPI\n"); + ret = -ENXIO; + } - ret = of_mdiobus_register(new_bus, np); if (ret) { dev_err(&pdev->dev, "Cannot register as MDIO bus!\n"); platform_set_drvdata(pdev, NULL); @@ -499,12 +512,19 @@ static const struct of_device_id hns_mdio_match[] = { {} }; +static const struct acpi_device_id hns_mdio_acpi_match[] = { + { "HISI0141", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, hns_mdio_acpi_match); + static struct platform_driver hns_mdio_driver = { .probe = hns_mdio_probe, .remove = hns_mdio_remove, .driver = { .name = MDIO_DRV_NAME, .of_match_table = hns_mdio_match, + .acpi_match_table = ACPI_PTR(hns_mdio_acpi_match), }, }; diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 288fac5294f5..4d4bb4955682 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -543,6 +543,11 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *); struct fwnode_handle; +static inline bool acpi_dev_found(const char *hid) +{ + return false; +} + static inline bool is_acpi_node(struct fwnode_handle *fwnode) { return false; @@ -654,6 +659,14 @@ static inline bool acpi_driver_match_device(struct device *dev, return false; } +static inline union acpi_object *acpi_evaluate_dsm(acpi_handle handle, + const u8 *uuid, + int rev, int func, + union acpi_object *argv4) +{ + return NULL; +} + static inline int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) { |