From patchwork Tue Jul 26 00:12:39 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iyappan Subramanian X-Patchwork-Id: 9247291 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3FEC0607FD for ; Tue, 26 Jul 2016 00:26:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2D94722380 for ; Tue, 26 Jul 2016 00:26:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 215132787C; Tue, 26 Jul 2016 00:26:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9657022380 for ; Tue, 26 Jul 2016 00:26:35 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bRq1m-0005VJ-WB; Tue, 26 Jul 2016 00:15:19 +0000 Received: from mail-pa0-x22f.google.com ([2607:f8b0:400e:c03::22f]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1bRq0V-0004HP-Qe for linux-arm-kernel@lists.infradead.org; Tue, 26 Jul 2016 00:14:05 +0000 Received: by mail-pa0-x22f.google.com with SMTP id fi15so65901219pac.1 for ; Mon, 25 Jul 2016 17:12:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=apm.com; s=apm; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=CHWA/TPVpHFe53rxNt9dNftkvXYDtofeA9e56o12Bwk=; b=DsMPQN6WsUFMZGPr+YOeetKB/TrDAAVKZY9636XkB+ScHwf/iEdJjdhwBQ8ofKzxSx gBs8leb1QmnQpoaX5ve5SVv0Iy8ZSvl7+Oenfbn6drnUno7yf/2OlBSN9p3oBy5hoXIC +Ylrhpso8YlszZ8gE0iQYZF25fz5OSP4ujAYw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=CHWA/TPVpHFe53rxNt9dNftkvXYDtofeA9e56o12Bwk=; b=MOWKqZOrp7B1Ipwl3+hq19DD2F2SIeEMadVQGh1A7eO35UriEaPRs/y1tqiv1QRR4+ jry+TYoicpYiU0JQB6Ktfhph74NGsdnIT2C4Ncg5uLJAvnHQ/aHymK+JfR9NCCTGfNGS 15/uCVv6B22j3nDTwBo08IF6PcvI144iSVY/JYFsbsfGTGvNmj6z7mDhcXqsSEJyhbmQ vi58Y4IZa/PM+Gf/QigJ04Mk2dlz6Il9mQ4UXuWuL9hMc61AqPFvLAtVzelh8aEj/JFJ e3JrVmMGgIzBYP7b6HznOvvkx8NIttFtJf5tcJslndNrBAIOf6qVy08eANXFm21VqGQp DaAw== X-Gm-Message-State: AEkoouu48yun0HB4sqGuZHCnBPNEm8dQYtMcgmUfoMhZeeaGRdWgPBNRqoWlGhQz6GZ+jKHR X-Received: by 10.66.62.168 with SMTP id z8mr33764161par.152.1469491961737; Mon, 25 Jul 2016 17:12:41 -0700 (PDT) Received: from isubrama-dev.amcc.com ([206.80.4.98]) by smtp.gmail.com with ESMTPSA id x9sm3739538pfk.79.2016.07.25.17.12.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 25 Jul 2016 17:12:41 -0700 (PDT) From: Iyappan Subramanian To: davem@davemloft.net, netdev@vger.kernel.org, devicetree@vger.kernel.org Subject: [PATCH net-next v7 04/12] drivers: net: xgene: Fix module unload crash - clkrst sequence Date: Mon, 25 Jul 2016 17:12:39 -0700 Message-Id: <1469491967-28627-5-git-send-email-isubramanian@apm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1469491967-28627-1-git-send-email-isubramanian@apm.com> References: <1469491967-28627-1-git-send-email-isubramanian@apm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160725_171400_267423_CE9AED2B X-CRM114-Status: GOOD ( 14.30 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: patches@apm.com, linux@armlinux.org.uk, linux-arm-kernel@lists.infradead.org, Iyappan Subramanian MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This patch fixes clock reset sequence. - Added clock reset sequence for ACPI - Added delay in clock reset sequence to make sure pulse is generated - Added clk_unprepare_disable() in port shutdown to make sure clock increment/decrement counts are matching - Removed MII_MGMT_CONFIG programming, since it is not required - Fixed programming XGENET_CONFIG_REG to enable SGMII mode Signed-off-by: Iyappan Subramanian Tested-by: Fushen Chen Tested-by: Toan Le --- drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 34 +++++++++++------ drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c | 45 ++++++++++++++++++++--- drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h | 1 + drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c | 24 +++++++++++- 4 files changed, 86 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c index 4f98749..91a67a0 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c @@ -675,24 +675,33 @@ bool xgene_ring_mgr_init(struct xgene_enet_pdata *p) static int xgene_enet_reset(struct xgene_enet_pdata *pdata) { - u32 val; + struct device *dev = &pdata->pdev->dev; if (!xgene_ring_mgr_init(pdata)) return -ENODEV; - if (!IS_ERR(pdata->clk)) { + if (dev->of_node) { clk_prepare_enable(pdata->clk); + udelay(5); clk_disable_unprepare(pdata->clk); + udelay(5); clk_prepare_enable(pdata->clk); - xgene_enet_ecc_init(pdata); + udelay(5); + } else { +#ifdef CONFIG_ACPI + if (acpi_has_method(ACPI_HANDLE(&pdata->pdev->dev), "_RST")) { + acpi_evaluate_object(ACPI_HANDLE(&pdata->pdev->dev), + "_RST", NULL, NULL); + } else if (acpi_has_method(ACPI_HANDLE(&pdata->pdev->dev), + "_INI")) { + acpi_evaluate_object(ACPI_HANDLE(&pdata->pdev->dev), + "_INI", NULL, NULL); + } +#endif } - xgene_enet_config_ring_if_assoc(pdata); - /* Enable auto-incr for scanning */ - xgene_enet_rd_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, &val); - val |= SCAN_AUTO_INCR; - MGMT_CLOCK_SEL_SET(&val, 1); - xgene_enet_wr_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, val); + xgene_enet_ecc_init(pdata); + xgene_enet_config_ring_if_assoc(pdata); return 0; } @@ -717,6 +726,7 @@ static void xgene_enet_clear(struct xgene_enet_pdata *pdata, static void xgene_gport_shutdown(struct xgene_enet_pdata *pdata) { + struct device *dev = &pdata->pdev->dev; struct xgene_enet_desc_ring *ring; u32 pb, val; int i; @@ -739,8 +749,10 @@ static void xgene_gport_shutdown(struct xgene_enet_pdata *pdata) } xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIWQRESET_ADDR, pb); - if (!IS_ERR(pdata->clk)) - clk_disable_unprepare(pdata->clk); + if (dev->of_node) { + if (!IS_ERR(pdata->clk)) + clk_disable_unprepare(pdata->clk); + } } static int xgene_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c index f1477d2..03a70c5 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c @@ -28,6 +28,12 @@ static void xgene_enet_wr_csr(struct xgene_enet_pdata *p, u32 offset, u32 val) iowrite32(val, p->eth_csr_addr + offset); } +static void xgene_enet_wr_clkrst_csr(struct xgene_enet_pdata *p, u32 offset, + u32 val) +{ + iowrite32(val, p->base_addr + offset); +} + static void xgene_enet_wr_ring_if(struct xgene_enet_pdata *p, u32 offset, u32 val) { @@ -434,17 +440,38 @@ static void xgene_sgmac_tx_disable(struct xgene_enet_pdata *p) static int xgene_enet_reset(struct xgene_enet_pdata *p) { + struct device *dev = &p->pdev->dev; + if (!xgene_ring_mgr_init(p)) return -ENODEV; - if (!IS_ERR(p->clk)) { - clk_prepare_enable(p->clk); - clk_disable_unprepare(p->clk); - clk_prepare_enable(p->clk); + if (p->enet_id == XGENE_ENET2) + xgene_enet_wr_clkrst_csr(p, XGENET_CONFIG_REG_ADDR, SGMII_EN); + + if (dev->of_node) { + if (!IS_ERR(p->clk)) { + clk_prepare_enable(p->clk); + udelay(5); + clk_disable_unprepare(p->clk); + udelay(5); + clk_prepare_enable(p->clk); + udelay(5); + } + } else { +#ifdef CONFIG_ACPI + if (acpi_has_method(ACPI_HANDLE(&p->pdev->dev), "_RST")) + acpi_evaluate_object(ACPI_HANDLE(&p->pdev->dev), + "_RST", NULL, NULL); + else if (acpi_has_method(ACPI_HANDLE(&p->pdev->dev), "_INI")) + acpi_evaluate_object(ACPI_HANDLE(&p->pdev->dev), + "_INI", NULL, NULL); +#endif } - xgene_enet_ecc_init(p); - xgene_enet_config_ring_if_assoc(p); + if (!p->port_id) { + xgene_enet_ecc_init(p); + xgene_enet_config_ring_if_assoc(p); + } return 0; } @@ -492,6 +519,7 @@ static void xgene_enet_clear(struct xgene_enet_pdata *pdata, static void xgene_enet_shutdown(struct xgene_enet_pdata *p) { + struct device *dev = &p->pdev->dev; struct xgene_enet_desc_ring *ring; u32 pb, val; int i; @@ -513,6 +541,11 @@ static void xgene_enet_shutdown(struct xgene_enet_pdata *p) pb |= BIT(val); } xgene_enet_wr_ring_if(p, ENET_CFGSSQMIWQRESET_ADDR, pb); + + if (dev->of_node) { + if (!IS_ERR(p->clk)) + clk_disable_unprepare(p->clk); + } } static void xgene_enet_link_state(struct work_struct *work) diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h index 32f140a..3d0ba37 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.h @@ -35,6 +35,7 @@ #define LINK_UP BIT(15) #define MPA_IDLE_WITH_QMI_EMPTY BIT(12) #define SG_RX_DV_GATE_REG_0_ADDR 0x05fc +#define SGMII_EN 0x1 enum xgene_phy_speed { PHY_SPEED_10, diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c index d0b4419..9c6ad0d 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c @@ -258,13 +258,29 @@ static void xgene_xgmac_tx_disable(struct xgene_enet_pdata *pdata) static int xgene_enet_reset(struct xgene_enet_pdata *pdata) { + struct device *dev = &pdata->pdev->dev; + if (!xgene_ring_mgr_init(pdata)) return -ENODEV; - if (!IS_ERR(pdata->clk)) { + if (dev->of_node) { clk_prepare_enable(pdata->clk); + udelay(5); clk_disable_unprepare(pdata->clk); + udelay(5); clk_prepare_enable(pdata->clk); + udelay(5); + } else { +#ifdef CONFIG_ACPI + if (acpi_has_method(ACPI_HANDLE(&pdata->pdev->dev), "_RST")) { + acpi_evaluate_object(ACPI_HANDLE(&pdata->pdev->dev), + "_RST", NULL, NULL); + } else if (acpi_has_method(ACPI_HANDLE(&pdata->pdev->dev), + "_INI")) { + acpi_evaluate_object(ACPI_HANDLE(&pdata->pdev->dev), + "_INI", NULL, NULL); + } +#endif } xgene_enet_ecc_init(pdata); @@ -292,6 +308,7 @@ static void xgene_enet_xgcle_bypass(struct xgene_enet_pdata *pdata, static void xgene_enet_shutdown(struct xgene_enet_pdata *pdata) { + struct device *dev = &pdata->pdev->dev; struct xgene_enet_desc_ring *ring; u32 pb, val; int i; @@ -313,6 +330,11 @@ static void xgene_enet_shutdown(struct xgene_enet_pdata *pdata) pb |= BIT(val); } xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIWQRESET_ADDR, pb); + + if (dev->of_node) { + if (!IS_ERR(pdata->clk)) + clk_disable_unprepare(pdata->clk); + } } static void xgene_enet_clear(struct xgene_enet_pdata *pdata,