From patchwork Fri Mar 7 11:34:52 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Hesselbarth X-Patchwork-Id: 3789921 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C038A9F35F for ; Fri, 7 Mar 2014 11:36:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B7639201ED for ; Fri, 7 Mar 2014 11:36:09 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A4EE1201C8 for ; Fri, 7 Mar 2014 11:36:08 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WLt4L-0000xC-QH; Fri, 07 Mar 2014 11:36:01 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WLt4J-00064C-Gc; Fri, 07 Mar 2014 11:35:59 +0000 Received: from mail-bk0-x22e.google.com ([2a00:1450:4008:c01::22e]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WLt4C-000624-6b for linux-arm-kernel@lists.infradead.org; Fri, 07 Mar 2014 11:35:56 +0000 Received: by mail-bk0-f46.google.com with SMTP id v15so907283bkz.19 for ; Fri, 07 Mar 2014 03:35:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xk3RiEHx6QxakTRxqhUrgRzsFRvDlQhU7KxabGE4aqc=; b=vsrdIMJt45gPmPKN8A3glPnDWcTI5KyUAw9ZWoFIr0I8/zYCMt8vFNQzhQQrdvLmJb 7aIBFeFV7BcAWN3UR/X7vsm5m5h0wTRsnhLCeVk1q0RmAlcFKMONkQ1sn9HHlxjqIVFQ jD+gH+6SIlrPQ3wgOtkay2BTyS+Rjngwqjg+bpG9MeOmHV2VZYomTUaBimigY4clCs9i kLlepioean+NPZbWG3HxabZGXZPUuxqXOU3gLkCgI4cnup6T6TYMQOluNuLICI2pouE2 OhTSA1Ck1z9O3xrKaEwJLkW4eO56miGd1bmooYAoa91OS16Z4Abi4yf03vuRsGs+qvC6 My5Q== X-Received: by 10.205.36.200 with SMTP id tb8mr399365bkb.105.1394192102536; Fri, 07 Mar 2014 03:35:02 -0800 (PST) Received: from topkick.lan (dslc-082-083-251-183.pools.arcor-ip.net. [82.83.251.183]) by mx.google.com with ESMTPSA id tg13sm2102176bkb.10.2014.03.07.03.35.00 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 07 Mar 2014 03:35:01 -0800 (PST) From: Sebastian Hesselbarth To: Sebastian Hesselbarth Subject: [PATCH] net: phy: Add sysfs attribute to prevent PHY suspend Date: Fri, 7 Mar 2014 12:34:52 +0100 Message-Id: <1394192092-27461-1-git-send-email-sebastian.hesselbarth@gmail.com> In-Reply-To: <1393174719-20806-1-git-send-email-sebastian.hesselbarth@gmail.com> References: <1393174719-20806-1-git-send-email-sebastian.hesselbarth@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140307_063552_429979_133E3A77 X-CRM114-Status: GOOD ( 18.09 ) X-Spam-Score: -2.0 (--) Cc: Andrew Lunn , Florian Fainelli , linux-doc@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Rob Landley , David Miller , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP commit 1211ce53077164e0d34641d0ca5fb4d4a7574498 ("net: phy: resume/suspend PHYs on attach/detach") introduced a feature to suspend PHYs when entering halted state. Unfortunately, not all bootloaders properly power-up PHYs on reset and fail to access ethernet because the PHY is still powered down. Therefore, this adds code and documentation for a sysfs attribute to allow/deny PHYs to be suspended on a per-PHY basis. Disabling that attribute prevents PHYs from being suspended when entering halted state. Signed-off-by: Sebastian Hesselbarth Reported-by: Andrew Lunn Reviewed-by: Florian Fainelli --- David, I know I am late, but I still consider this as a fix for v3.14, therefore this is based on v3.14-rc1. If you are already done with taking fixes for v3.14, I can, of course, rebase this upon net-next. Cc: David Miller Cc: Rob Landley Cc: Andrew Lunn Cc: Florian Fainelli Cc: netdev@vger.kernel.org Cc: linux-doc@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org --- Documentation/ABI/testing/sysfs-bus-mdio | 10 ++++++++++ drivers/net/phy/mdio_bus.c | 26 ++++++++++++++++++++++++++ drivers/net/phy/phy_device.c | 5 +++++ include/linux/phy.h | 2 ++ 4 files changed, 43 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-mdio b/Documentation/ABI/testing/sysfs-bus-mdio index 6349749ebc29..e85a3d350cb1 100644 --- a/Documentation/ABI/testing/sysfs-bus-mdio +++ b/Documentation/ABI/testing/sysfs-bus-mdio @@ -7,3 +7,13 @@ Description: by the device during bus enumeration, encoded in hexadecimal. This ID is used to match the device with the appropriate driver. + +What: /sys/bus/mdio_bus/devices/.../phy_allow_suspend +Date: March 2014 +KernelVersion: 3.14 +Contact: netdev@vger.kernel.org +Description: + This attribute contains a boolean parameter to allow (1) or + deny (0) MDIO bus attached PHYs to be suspended. Some + bootloaders fail to properly resume a suspended PHY, so this + can be used to prevent the PHY from being suspended. diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 71e49000fbf3..811d35185596 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -432,8 +432,34 @@ phy_id_show(struct device *dev, struct device_attribute *attr, char *buf) } static DEVICE_ATTR_RO(phy_id); +static ssize_t phy_allow_suspend_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct phy_device *phydev = to_phy_device(dev); + + return sprintf(buf, "%d\n", phydev->allow_suspend); +} + +static ssize_t phy_allow_suspend_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct phy_device *phydev = to_phy_device(dev); + bool val; + int ret; + + ret = strtobool(buf, &val); + if (ret < 0) + return ret; + + phydev->allow_suspend = val; + + return count; +} +static DEVICE_ATTR_RW(phy_allow_suspend); + static struct attribute *mdio_dev_attrs[] = { &dev_attr_phy_id.attr, + &dev_attr_phy_allow_suspend.attr, NULL, }; ATTRIBUTE_GROUPS(mdio_dev); diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 4b03e63639b7..1c83d34d848b 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -173,6 +173,7 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, dev->phy_id = phy_id; if (c45_ids) dev->c45_ids = *c45_ids; + dev->allow_suspend = true; dev->bus = bus; dev->dev.parent = bus->parent; dev->dev.bus = &mdio_bus_type; @@ -685,6 +686,10 @@ int phy_suspend(struct phy_device *phydev) struct phy_driver *phydrv = to_phy_driver(phydev->dev.driver); struct ethtool_wolinfo wol; + /* Do not suspend PHYs, if user disabled it */ + if (!phydev->allow_suspend) + return -ENOSYS; + /* If the device has WOL enabled, we cannot suspend the PHY */ wol.cmd = ETHTOOL_GWOL; phy_ethtool_get_wol(phydev, &wol); diff --git a/include/linux/phy.h b/include/linux/phy.h index 565188ca328f..c472e750c023 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -272,6 +272,7 @@ struct phy_c45_device_ids { * c45_ids: 802.3-c45 Device Identifers if is_c45. * is_c45: Set to true if this phy uses clause 45 addressing. * is_internal: Set to true if this phy is internal to a MAC. + * allow_suspend: Set to false to prevent PHY suspend. * state: state of the PHY for management purposes * dev_flags: Device-specific flags used by the PHY driver. * addr: Bus address of PHY @@ -308,6 +309,7 @@ struct phy_device { struct phy_c45_device_ids c45_ids; bool is_c45; bool is_internal; + bool allow_suspend; enum phy_state state;