From patchwork Mon May 30 02:10:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: yankejian X-Patchwork-Id: 627587 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3rJ0J36HP0z9t44 for ; Mon, 30 May 2016 12:02:43 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1161117AbcE3CBc (ORCPT ); Sun, 29 May 2016 22:01:32 -0400 Received: from szxga01-in.huawei.com ([58.251.152.64]:16100 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753214AbcE3B6e (ORCPT ); Sun, 29 May 2016 21:58:34 -0400 Received: from 172.24.1.136 (EHLO szxeml434-hub.china.huawei.com) ([172.24.1.136]) by szxrg01-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id DLJ22706; Mon, 30 May 2016 09:58:30 +0800 (CST) Received: from linux-ioko.site (10.71.200.31) by szxeml434-hub.china.huawei.com (10.82.67.225) with Microsoft SMTP Server id 14.3.235.1; Mon, 30 May 2016 09:57:31 +0800 From: Kejian Yan To: , , CC: , , , , , , , , , , Subject: [patch v2 net-next 04/13] net: hisilicon: add support of acpi for hns-mdio Date: Mon, 30 May 2016 10:10:13 +0800 Message-ID: <1464574222-69608-5-git-send-email-yankejian@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1464574222-69608-1-git-send-email-yankejian@huawei.com> References: <1464574222-69608-1-git-send-email-yankejian@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.71.200.31] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090206.574B9E48.0015, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: e1bcfcc28dce214ac92c790f2344e77d Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org hns-mdio needs to register itself to mii-bus. The info of the device can be read by both DT and ACPI. HNS tries to call Linux PHY driver to help access PHY-devices, the HNS hardware topology is as below. The MDIO controller may control several PHY-devices, and each PHY-device connects to a MAC device. The MDIO will be registered to mdiobus, then PHY-devices will register when each mac find PHY device. cpu | | ------------------------------------------- | | | | | | | dsaf | MDIO | MDIO | --------------------------- | | | | | | | | | | | | | | MAC MAC MAC MAC | | | | | | | ---- |-------- |-------- | | -------- || || || || PHY PHY PHY PHY And the driver can handle reset sequence by _RST method in DSDT in ACPI case. Signed-off-by: Kejian Yan Signed-off-by: Yisen Zhuang --- change log: v2: 1. use dev_of_node instead of IS_ENABLED macro 2. Add ACPI bits v1: first submit Link: https://lkml.org/lkml/2016/5/13/93 --- drivers/net/ethernet/hisilicon/hns_mdio.c | 107 +++++++++++++++++++----------- 1 file changed, 69 insertions(+), 38 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns_mdio.c b/drivers/net/ethernet/hisilicon/hns_mdio.c index 381cf0a..f78286c 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 #include #include #include @@ -354,48 +355,60 @@ static int hns_mdio_reset(struct mii_bus *bus) struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv; int ret; - if (!dev_of_node(bus->parent)) - return -ENOTSUPP; + 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; + } - 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; + } - /*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; - } + /* 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; + } - /*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; - } + /* 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; + } - /*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; } - - /*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"); - return ret; } @@ -453,7 +466,6 @@ static int hns_mdio_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, new_bus); - hns_mdio_bus_name(new_bus->id, res->start); if (dev_of_node(&pdev->dev)) { mdio_dev->subctrl_vbase = syscon_node_to_regmap( @@ -464,6 +476,18 @@ static int hns_mdio_probe(struct platform_device *pdev) 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; } if (ret) { @@ -499,12 +523,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), }, };