From patchwork Mon Jun 22 09:37:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 11617817 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1ABA2618 for ; Mon, 22 Jun 2020 13:56:40 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E72CC20706 for ; Mon, 22 Jun 2020 13:56:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="TBxOK86E"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=bgdev-pl.20150623.gappssmtp.com header.i=@bgdev-pl.20150623.gappssmtp.com header.b="p3puFYEO" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E72CC20706 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=rTFfl9TSqzEPgBpglZkIJZIUz1Q/BJ5OPSsxUXEXbGY=; b=TBxOK86E66ceC51L+cK1eVWWn 36Lud8FfQZlOFt2MnkojER6EcegTVerBhIBqgKU9oGm0coE1t47mJnOc7B3BmWeGojMg0FbTu7DKq oIFSatXpMGsRX1cU8T8v7NB3Ts6xKEQhxxZXpnXAA0v48MLdjhP+FE3yh0YRibhazRtDNQK2Mm2Yk bEpE1m9H0/KKJU1oZAMEdPr5LJ6q4QasFjlkyFaGNqI4jnWe6dT2wq/UFuP7oa+ZHaIV2gGLpZuK5 zk4Ix6aZ9JICCTDbT3PYYcDrajkzX2/N98yZW6N7rx+Qjw4ljEn4EgLSDpi/m2sBLmvYDcyXiAeNa iENcE7zcA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jnMwA-0002GD-OY; Mon, 22 Jun 2020 13:56:38 +0000 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jnIxW-0007hb-Ot for linux-mediatek@lists.infradead.org; Mon, 22 Jun 2020 09:41:47 +0000 Received: by mail-wm1-x341.google.com with SMTP id u26so13127134wmn.1 for ; Mon, 22 Jun 2020 02:41:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0paM6XhitgV7f9qC2QMsgtm0qUC+Vh9Zw/7wnTkRdCU=; b=p3puFYEON7LkHbRRFDYqexUJADfzkEU/dUHjBAt/PbcDJGO0LiqnjjeqsIrnr/DVi8 TrFkDpUdHsOTJT23y3iLd0/FPbAVUhoTCnRBnGU2vTS0/89DVGkpzmy+t4hbbzqoDU3B KNlg5bNbRUucNBZgy88A9ZU09qNs5k/J6vh5JqNU5yWXSVkkc9yOsVgS02mQpY90/8V6 0oOVcA0uD5HC67mpqZzgj7Sw1oNu0MzvwMK7PgFS2M7LqNfuY/VGRHUtM65hVZ7AfhGx 9iE+ygyaLVwY/ZH++VpS+UD/5Poz5Tu6HHyjGXcqFdVGwfKkqG/ZHgm0AIs5WEiNvL2j Bv5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0paM6XhitgV7f9qC2QMsgtm0qUC+Vh9Zw/7wnTkRdCU=; b=N73WHcTq1fDM/HsC709FOVf/MO2UAYXyyzeE/s8yr6XlHOU5cnPECjqp+yLRiQ5cdW 09kis8eBZrxJOr//EcSTfipHZGpFmAWOFkZxzSB7f5BCVWwmEaDopuDCup6bvpinJHZb 6Me32K6gIuOg/iAM6gnqOEof10bMD3z8yyGraAvFYGo3NB/CTrH0hXjkXpPKrNDPWExI y6aQ5mM2W+AcoJJ19XbUvuDBn3IMn28ANehIn/HrywyBOl3L74sgTwX/261LxulwW8Zj yCmW9k+PW4p3TAx1BP2jfsFhexofaeceZsNMRtP5EAOR+pvadgTp+HqTGUHhMic0ooYs CGcQ== X-Gm-Message-State: AOAM533LKHjhFRZkuXe29DDclSsw3tXUJsYGcd+zbu5ij+pbzv4QtGeL oaIbGE2S8TC0e64EA/mJadKoSw== X-Google-Smtp-Source: ABdhPJzv5Re1aj4/hOY+M8/oLHAxe0wxNqcRaQ+JBsEotMr3fSKVkarmVoP6v3N5vfsL/r8R8lxAzQ== X-Received: by 2002:a1c:a3c5:: with SMTP id m188mr17122520wme.152.1592818905480; Mon, 22 Jun 2020 02:41:45 -0700 (PDT) Received: from localhost.localdomain (lfbn-nic-1-65-232.w2-15.abo.wanadoo.fr. [2.15.156.232]) by smtp.gmail.com with ESMTPSA id j24sm14392652wrd.43.2020.06.22.02.41.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Jun 2020 02:41:44 -0700 (PDT) From: Bartosz Golaszewski To: Andrew Lunn , Florian Fainelli , Heiner Kallweit , Russell King , "David S . Miller" , Jakub Kicinski , Rob Herring , Matthias Brugger , Microchip Linux Driver Support , Vladimir Oltean , Claudiu Manoil , Alexandre Belloni , Vivien Didelot , Tom Lendacky , Yisen Zhuang , Salil Mehta , Jassi Brar , Ilias Apalodimas , Iyappan Subramanian , Keyur Chudgar , Quan Nguyen , Frank Rowand , Philipp Zabel , Liam Girdwood , Mark Brown Subject: [PATCH 13/15] net: phy: mdio: add support for PHY supply regulator Date: Mon, 22 Jun 2020 11:37:42 +0200 Message-Id: <20200622093744.13685-14-brgl@bgdev.pl> X-Mailer: git-send-email 2.26.1 In-Reply-To: <20200622093744.13685-1-brgl@bgdev.pl> References: <20200622093744.13685-1-brgl@bgdev.pl> MIME-Version: 1.0 X-Spam-Note: CRM114 invocation failed X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2a00:1450:4864:20:0:0:0:341 listed in] [list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Stephane Le Provost , Bartosz Golaszewski , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Fabien Parent , linux-mediatek@lists.infradead.org, Andrew Perepech , Pedro Tsai , linux-arm-kernel@lists.infradead.org Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org From: Bartosz Golaszewski Currently many MAC drivers control the regulator supplying the PHY but this is conceptually wrong. The regulator should be defined as a property of the PHY node on the MDIO bus and controlled by the MDIO sub-system. Add support for an optional PHY regulator which will be enabled before optional deasserting of the reset signal. Signed-off-by: Bartosz Golaszewski --- drivers/net/phy/mdio_bus.c | 21 ++++++++++++++++++++ drivers/net/phy/mdio_device.c | 36 +++++++++++++++++++++++++++++++++++ include/linux/mdio.h | 3 +++ 3 files changed, 60 insertions(+) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 53e2fb0be7b9..19f0b9664fe3 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,22 @@ static int mdiobus_register_reset(struct mdio_device *mdiodev) return 0; } +static int mdiobus_register_regulator(struct mdio_device *mdiodev) +{ + struct regulator *phy_supply; + + phy_supply = regulator_get_optional(&mdiodev->dev, "phy"); + if (IS_ERR(phy_supply)) { + if (PTR_ERR(phy_supply) == -EPROBE_DEFER) + return -EPROBE_DEFER; + phy_supply = NULL; + } + + mdiodev->phy_supply = phy_supply; + + return 0; +} + int mdiobus_register_device(struct mdio_device *mdiodev) { int err; @@ -83,6 +100,10 @@ int mdiobus_register_device(struct mdio_device *mdiodev) if (err) return err; + err = mdiobus_register_regulator(mdiodev); + if (err) + return err; + /* Assert the reset signal */ mdio_device_reset(mdiodev, 1); } diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c index be615504b829..0f698d7a770b 100644 --- a/drivers/net/phy/mdio_device.c +++ b/drivers/net/phy/mdio_device.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -136,6 +137,32 @@ void mdio_device_reset(struct mdio_device *mdiodev, int value) } EXPORT_SYMBOL(mdio_device_reset); +int mdio_device_power_on(struct mdio_device *mdiodev) +{ + int ret = 0; + + if (mdiodev->phy_supply) + /* TODO We may need a delay here just like reset_assert_delay + * but since no user currently needs it, I'm not adding it just + * yet. + */ + ret = regulator_enable(mdiodev->phy_supply); + + return ret; +} +EXPORT_SYMBOL(mdio_device_power_on); + +int mdio_device_power_off(struct mdio_device *mdiodev) +{ + int ret = 0; + + if (mdiodev->phy_supply) + ret = regulator_disable(mdiodev->phy_supply); + + return ret; +} +EXPORT_SYMBOL(mdio_device_power_off); + /** * mdio_probe - probe an MDIO device * @dev: device to probe @@ -150,6 +177,11 @@ static int mdio_probe(struct device *dev) struct mdio_driver *mdiodrv = to_mdio_driver(drv); int err = 0; + /* Enable the power supply */ + err = mdio_device_power_on(mdiodev); + if (err) + return err; + /* Deassert the reset signal */ mdio_device_reset(mdiodev, 0); @@ -158,6 +190,8 @@ static int mdio_probe(struct device *dev) if (err) { /* Assert the reset signal */ mdio_device_reset(mdiodev, 1); + /* Disable the power supply */ + mdio_device_power_off(mdiodev); } } @@ -175,6 +209,8 @@ static int mdio_remove(struct device *dev) /* Assert the reset signal */ mdio_device_reset(mdiodev, 1); + /* Disable the power supply */ + mdio_device_power_off(mdiodev); return 0; } diff --git a/include/linux/mdio.h b/include/linux/mdio.h index 9ac5e7ff6156..0ae07365a6ca 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h @@ -46,6 +46,7 @@ struct mdio_device { int flags; struct gpio_desc *reset_gpio; struct reset_control *reset_ctrl; + struct regulator *phy_supply; unsigned int reset_assert_delay; unsigned int reset_deassert_delay; }; @@ -92,6 +93,8 @@ struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr); int mdio_device_register(struct mdio_device *mdiodev); void mdio_device_remove(struct mdio_device *mdiodev); void mdio_device_reset(struct mdio_device *mdiodev, int value); +int mdio_device_power_on(struct mdio_device *mdiodev); +int mdio_device_power_off(struct mdio_device *mdiodev); int mdio_driver_register(struct mdio_driver *drv); void mdio_driver_unregister(struct mdio_driver *drv); int mdio_device_bus_match(struct device *dev, struct device_driver *drv);