Received: by 2002:a25:7ec1:0:0:0:0:0 with SMTP id z184csp136675ybc; Mon, 18 Nov 2019 21:58:54 -0800 (PST) X-Google-Smtp-Source: APXvYqwSQZJOEEsDEPzGCuuLKLx66hAcHeazpbomyrg/5AWQCxvk3sQTAVd3vWnkgUb2J1mxFIgX X-Received: by 2002:a17:906:fad1:: with SMTP id lu17mr32581797ejb.24.1574143134805; Mon, 18 Nov 2019 21:58:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1574143134; cv=none; d=google.com; s=arc-20160816; b=rEbJmq1iAN9MbLYeeMDK3QlRDUimHiafkSRAl9dGSxM5ucWdQIL6/yQmXfnltE1Ls/ 53ELSBRXwgsood2yWlp84Y9H1YNmYi6AGI4H2blDBy0tsIGhPnLyQUeiEhBQwBKkjs6w 798pe6x6052lMFW4x0IU4RFikQJZgb2jSo0I0lTPgI8PdZ+liyFTsfl6gzcuumeBscQR yf0cQmwew35UyNzm/z/mjeqywKCy2csEWA8ArK55xGCUHU+SzfqJKrKTMtZdbBDR6RUM AvNG6Bvpl2zFjhO4R4IOJD1QG1IZv/FJ9Dq/eGAnyM0MBjRScjMo9pVr8F9C24Z3PgkH 9E0g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=oucdDR+GzWSlmlT8wrvV0mOORL994aermZWlr5YtMD4=; b=tvXhW66uy+HH47nx7Tip7fOkq6Z77FJsJuXXz9M9B/wTykYUgBoIlUlKre7a3U5mBO +Y1bkrNj/jTxfRjhvUOUzsuWUm52ai2Grfx85ll7XzBai5L2Ft9H6V3CvQQpamireQnD AzhCh8yEeaMbgBnyr9WxoybTwC+hSj81hQFili/W67OEytyZuZ2UOm11acU+vuP+/gpI aOdOg+iT6QXFN3Liyxj+OCIu5xXlumVI0RX3zXonSMi8n0JOIczjvq9qhUqb4zHDOoPF zPLaoG3KujuBfHhwkKZYulvH0TcIu6TIarXyAb0/hWkvgMdaCLz/xKhWO5Koim9HpnAz WcOg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=IFEJO2vu; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f11si13032899ejk.336.2019.11.18.21.58.29; Mon, 18 Nov 2019 21:58:54 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=IFEJO2vu; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731595AbfKSFxj (ORCPT + 99 others); Tue, 19 Nov 2019 00:53:39 -0500 Received: from mail.kernel.org ([198.145.29.99]:51540 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732025AbfKSFxg (ORCPT ); Tue, 19 Nov 2019 00:53:36 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 54AC321783; Tue, 19 Nov 2019 05:53:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1574142814; bh=S8BLw9qnAgSSUKEXrYw9zZJE/vcu51H7519p3nX+zS8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IFEJO2vu71pd7Grtt476dJEyJP2Dy77Hcp2uUWyWsNCAwPJwqtkqcMHd03KZlmQXJ 8RskhkSwJ0BVSCJ69KPaAmm4QnKagt/epd7ci+FPkpJ76H/Qj6wkkfuhBxxui0M2jl 7EXQ9F4wjIoqZmAATJ0EXA1kz2VmwejvuTmn/mWQ= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Florian Fainelli , "David S. Miller" , Sasha Levin Subject: [PATCH 4.14 172/239] net: phy: mdio-bcm-unimac: Allow configuring MDIO clock divider Date: Tue, 19 Nov 2019 06:19:32 +0100 Message-Id: <20191119051334.060293214@linuxfoundation.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191119051255.850204959@linuxfoundation.org> References: <20191119051255.850204959@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Florian Fainelli [ Upstream commit b78ac6ecd1b6b46f8767cbafa95a7b0b51b87ad8 ] Allow the configuration of the MDIO clock divider when the Device Tree contains 'clock-frequency' property (similar to I2C and SPI buses). Because the hardware may have lost its state during suspend/resume, re-apply the MDIO clock divider upon resumption. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- .../bindings/net/brcm,unimac-mdio.txt | 3 + drivers/net/phy/mdio-bcm-unimac.c | 83 ++++++++++++++++++- 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/net/brcm,unimac-mdio.txt b/Documentation/devicetree/bindings/net/brcm,unimac-mdio.txt index 4648948f7c3b8..e15589f477876 100644 --- a/Documentation/devicetree/bindings/net/brcm,unimac-mdio.txt +++ b/Documentation/devicetree/bindings/net/brcm,unimac-mdio.txt @@ -19,6 +19,9 @@ Optional properties: - interrupt-names: must be "mdio_done_error" when there is a share interrupt fed to this hardware block, or must be "mdio_done" for the first interrupt and "mdio_error" for the second when there are separate interrupts +- clocks: A reference to the clock supplying the MDIO bus controller +- clock-frequency: the MDIO bus clock that must be output by the MDIO bus + hardware, if absent, the default hardware values are used Child nodes of this MDIO bus controller node are standard Ethernet PHY device nodes as described in Documentation/devicetree/bindings/net/phy.txt diff --git a/drivers/net/phy/mdio-bcm-unimac.c b/drivers/net/phy/mdio-bcm-unimac.c index 08e0647b85e23..f9d98a6e67bc4 100644 --- a/drivers/net/phy/mdio-bcm-unimac.c +++ b/drivers/net/phy/mdio-bcm-unimac.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,8 @@ struct unimac_mdio_priv { void __iomem *base; int (*wait_func) (void *wait_func_data); void *wait_func_data; + struct clk *clk; + u32 clk_freq; }; static inline u32 unimac_mdio_readl(struct unimac_mdio_priv *priv, u32 offset) @@ -189,6 +192,35 @@ static int unimac_mdio_reset(struct mii_bus *bus) return 0; } +static void unimac_mdio_clk_set(struct unimac_mdio_priv *priv) +{ + unsigned long rate; + u32 reg, div; + + /* Keep the hardware default values */ + if (!priv->clk_freq) + return; + + if (!priv->clk) + rate = 250000000; + else + rate = clk_get_rate(priv->clk); + + div = (rate / (2 * priv->clk_freq)) - 1; + if (div & ~MDIO_CLK_DIV_MASK) { + pr_warn("Incorrect MDIO clock frequency, ignoring\n"); + return; + } + + /* The MDIO clock is the reference clock (typicaly 250Mhz) divided by + * 2 x (MDIO_CLK_DIV + 1) + */ + reg = unimac_mdio_readl(priv, MDIO_CFG); + reg &= ~(MDIO_CLK_DIV_MASK << MDIO_CLK_DIV_SHIFT); + reg |= div << MDIO_CLK_DIV_SHIFT; + unimac_mdio_writel(priv, reg, MDIO_CFG); +} + static int unimac_mdio_probe(struct platform_device *pdev) { struct unimac_mdio_pdata *pdata = pdev->dev.platform_data; @@ -215,9 +247,26 @@ static int unimac_mdio_probe(struct platform_device *pdev) return -ENOMEM; } + priv->clk = devm_clk_get(&pdev->dev, NULL); + if (PTR_ERR(priv->clk) == -EPROBE_DEFER) + return PTR_ERR(priv->clk); + else + priv->clk = NULL; + + ret = clk_prepare_enable(priv->clk); + if (ret) + return ret; + + if (of_property_read_u32(np, "clock-frequency", &priv->clk_freq)) + priv->clk_freq = 0; + + unimac_mdio_clk_set(priv); + priv->mii_bus = mdiobus_alloc(); - if (!priv->mii_bus) - return -ENOMEM; + if (!priv->mii_bus) { + ret = -ENOMEM; + goto out_clk_disable; + } bus = priv->mii_bus; bus->priv = priv; @@ -251,6 +300,8 @@ static int unimac_mdio_probe(struct platform_device *pdev) out_mdio_free: mdiobus_free(bus); +out_clk_disable: + clk_disable_unprepare(priv->clk); return ret; } @@ -260,10 +311,37 @@ static int unimac_mdio_remove(struct platform_device *pdev) mdiobus_unregister(priv->mii_bus); mdiobus_free(priv->mii_bus); + clk_disable_unprepare(priv->clk); + + return 0; +} + +static int unimac_mdio_suspend(struct device *d) +{ + struct unimac_mdio_priv *priv = dev_get_drvdata(d); + + clk_disable_unprepare(priv->clk); + + return 0; +} + +static int unimac_mdio_resume(struct device *d) +{ + struct unimac_mdio_priv *priv = dev_get_drvdata(d); + int ret; + + ret = clk_prepare_enable(priv->clk); + if (ret) + return ret; + + unimac_mdio_clk_set(priv); return 0; } +static SIMPLE_DEV_PM_OPS(unimac_mdio_pm_ops, + unimac_mdio_suspend, unimac_mdio_resume); + static const struct of_device_id unimac_mdio_ids[] = { { .compatible = "brcm,genet-mdio-v5", }, { .compatible = "brcm,genet-mdio-v4", }, @@ -279,6 +357,7 @@ static struct platform_driver unimac_mdio_driver = { .driver = { .name = UNIMAC_MDIO_DRV_NAME, .of_match_table = unimac_mdio_ids, + .pm = &unimac_mdio_pm_ops, }, .probe = unimac_mdio_probe, .remove = unimac_mdio_remove, -- 2.20.1