Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp1958084pxb; Wed, 10 Feb 2021 23:59:00 -0800 (PST) X-Google-Smtp-Source: ABdhPJxKlgS0f8KP5dD7/ctnDA03siaT84FoylQWuF/xEhi0SG8vvm0+8thLqj16LAhjdA7Ln8gW X-Received: by 2002:a17:906:40d2:: with SMTP id a18mr7369872ejk.82.1613030339832; Wed, 10 Feb 2021 23:58:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613030339; cv=none; d=google.com; s=arc-20160816; b=0lMhSHf26PGWq4NzL5VJG/isu3DAdtL0tAhE/hPJLXVrTiFPRk2IplDyH0AanSMN2K /Bex9fE8nim9O5F5f2XXmEsGuo4zJ8NZkQC2+hBcwUiuCYd+0v3kCLEH2F8okR/TiXZS yvqr6KLVCQ9GFIKG7OsQefPmLcBmB107/5YKxDzhq/fWLGkEAMAbF0uHvAx+JIyKWqLV 5/m7WHGmEFFPR9vGgYAs9KRPkq87td07ZJ0tgIRNO5+2NnYQDo/zySy/PDvk0khWRz7+ S95QPGQgu0/VsUkaMtnvUlgQQZduwJHdv6vlU/9ch8WCaCuL8KDuOBpY7aOsdJuoE8/h Jwiw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=oyfqCI632+mvcyehpJ9shc2ihi7ISSd+yQD5qpx00eU=; b=I32qf3RG2ZDEJAFKTaeK1fp6EZio4qgpVArkYSKaH58oxo4IDt35xj5IYTUwfOk3kU p0xAT7xJLjJigs+8ed3dNiSWi55J3RcIFfkcDcRUs+DwMnk+/CJEZxTrQtJOoL2Q3q6+ g7cnvoovWTCFB9LvgsltvvAGisLTefkv6zPeN/AHBGdIP9ew3BVR5Wegvx3tIhez2vYo uxPQ+AejTUfNCysyLiROunHDK70LKK1Vq5LJ9spMG7lwwGEEyKfevDpD3RZcFrTEjEAD imrCZZulPD40pmlB//BoZT1vauoLwvMxSuod/x14xZQ97a9OVSYBHTq/Jin8RCletIoc +5vQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@walle.cc header.s=mail2016061301 header.b="uUGd29/e"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id dp16si3576846ejc.49.2021.02.10.23.58.36; Wed, 10 Feb 2021 23:58:59 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@walle.cc header.s=mail2016061301 header.b="uUGd29/e"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229889AbhBKHxc (ORCPT + 99 others); Thu, 11 Feb 2021 02:53:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39784 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229674AbhBKHvr (ORCPT ); Thu, 11 Feb 2021 02:51:47 -0500 Received: from ssl.serverraum.org (ssl.serverraum.org [IPv6:2a01:4f8:151:8464::1:2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EE644C061788; Wed, 10 Feb 2021 23:51:48 -0800 (PST) Received: from mwalle01.fritz.box (unknown [IPv6:2a02:810c:c200:2e91:fa59:71ff:fe9b:b851]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by ssl.serverraum.org (Postfix) with ESMTPSA id B22A823E87; Thu, 11 Feb 2021 08:48:01 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=walle.cc; s=mail2016061301; t=1613029681; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oyfqCI632+mvcyehpJ9shc2ihi7ISSd+yQD5qpx00eU=; b=uUGd29/euwafDHJxphledWYl1OUpILh4g7hgyrmt7tJi5g0vsPqCqlIPtbNbsQvohLVwU5 g2i+B7xGeUAV/5aKbKa35GNLk+TMj5Uk/dNzVMhWxtLVoIf6YaOGioK8YaJ3yt0QoeKJQb LP9F1LrfEWG2cihbVyuYcoDk26wTWTE= From: Michael Walle To: netdev@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Andrew Lunn , Heiner Kallweit , Russell King , "David S . Miller" , Jakub Kicinski , Michael Walle Subject: [PATCH net-next v4 7/9] net: phy: icplus: fix paged register access Date: Thu, 11 Feb 2021 08:47:48 +0100 Message-Id: <20210211074750.28674-8-michael@walle.cc> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210211074750.28674-1-michael@walle.cc> References: <20210211074750.28674-1-michael@walle.cc> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Registers >= 16 are paged. Be sure to set the page. It seems this was working for now, because the default is correct for the registers used in the driver at the moment. But this will also assume, nobody will change the page select register before linux is started. The page select register is _not_ reset with a soft reset of the PHY. To ease the function reuse between the non-paged register space of the IP101A and the IP101G, add noop read_page()/write_page() callbacks so the IP101G functions can also be used for the IP101A. Signed-off-by: Michael Walle --- Changes since v3: - added return code check on phy_select_page() - initialize err, found by kernel test robot Changes since v2: - none Changes since v1: - introduce a noop read/write_page() for the IP101A - also use phy_*_paged() for the interrupt status register Andrew, I've dropped your Reviewed-by because of this. drivers/net/phy/icplus.c | 67 ++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index bc2b58061507..f98edd66cdd2 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c @@ -49,6 +49,8 @@ MODULE_LICENSE("GPL"); #define IP101G_DIGITAL_IO_SPEC_CTRL 0x1d #define IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32 BIT(2) +#define IP101G_DEFAULT_PAGE 16 + #define IP175C_PHY_ID 0x02430d80 #define IP1001_PHY_ID 0x02430d90 #define IP101A_PHY_ID 0x02430c54 @@ -211,23 +213,27 @@ static int ip101a_g_probe(struct phy_device *phydev) static int ip101a_g_config_intr_pin(struct phy_device *phydev) { struct ip101a_g_phy_priv *priv = phydev->priv; - int err; + int oldpage, err = 0; + + oldpage = phy_select_page(phydev, IP101G_DEFAULT_PAGE); + if (oldpage < 0) + return oldpage; /* configure the RXER/INTR_32 pin of the 32-pin IP101GR if needed: */ switch (priv->sel_intr32) { case IP101GR_SEL_INTR32_RXER: - err = phy_modify(phydev, IP101G_DIGITAL_IO_SPEC_CTRL, - IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32, 0); + err = __phy_modify(phydev, IP101G_DIGITAL_IO_SPEC_CTRL, + IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32, 0); if (err < 0) - return err; + goto out; break; case IP101GR_SEL_INTR32_INTR: - err = phy_modify(phydev, IP101G_DIGITAL_IO_SPEC_CTRL, - IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32, - IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32); + err = __phy_modify(phydev, IP101G_DIGITAL_IO_SPEC_CTRL, + IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32, + IP101G_DIGITAL_IO_SPEC_CTRL_SEL_INTR32); if (err < 0) - return err; + goto out; break; default: @@ -241,7 +247,8 @@ static int ip101a_g_config_intr_pin(struct phy_device *phydev) break; } - return 0; +out: + return phy_restore_page(phydev, oldpage, err); } static int ip101a_config_init(struct phy_device *phydev) @@ -263,8 +270,10 @@ static int ip101g_config_init(struct phy_device *phydev) static int ip101a_g_ack_interrupt(struct phy_device *phydev) { - int err = phy_read(phydev, IP101A_G_IRQ_CONF_STATUS); + int err; + err = phy_read_paged(phydev, IP101G_DEFAULT_PAGE, + IP101A_G_IRQ_CONF_STATUS); if (err < 0) return err; @@ -283,10 +292,12 @@ static int ip101a_g_config_intr(struct phy_device *phydev) /* INTR pin used: Speed/link/duplex will cause an interrupt */ val = IP101A_G_IRQ_PIN_USED; - err = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, val); + err = phy_write_paged(phydev, IP101G_DEFAULT_PAGE, + IP101A_G_IRQ_CONF_STATUS, val); } else { val = IP101A_G_IRQ_ALL_MASK; - err = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, val); + err = phy_write_paged(phydev, IP101G_DEFAULT_PAGE, + IP101A_G_IRQ_CONF_STATUS, val); if (err) return err; @@ -300,7 +311,8 @@ static irqreturn_t ip101a_g_handle_interrupt(struct phy_device *phydev) { int irq_status; - irq_status = phy_read(phydev, IP101A_G_IRQ_CONF_STATUS); + irq_status = phy_read_paged(phydev, IP101G_DEFAULT_PAGE, + IP101A_G_IRQ_CONF_STATUS); if (irq_status < 0) { phy_error(phydev); return IRQ_NONE; @@ -316,6 +328,31 @@ static irqreturn_t ip101a_g_handle_interrupt(struct phy_device *phydev) return IRQ_HANDLED; } +/* The IP101A doesn't really have a page register. We just pretend to have one + * so we can use the paged versions of the callbacks of the IP101G. + */ +static int ip101a_read_page(struct phy_device *phydev) +{ + return IP101G_DEFAULT_PAGE; +} + +static int ip101a_write_page(struct phy_device *phydev, int page) +{ + WARN_ONCE(page != IP101G_DEFAULT_PAGE, "wrong page selected\n"); + + return 0; +} + +static int ip101g_read_page(struct phy_device *phydev) +{ + return __phy_read(phydev, IP101G_PAGE_CONTROL); +} + +static int ip101g_write_page(struct phy_device *phydev, int page) +{ + return __phy_write(phydev, IP101G_PAGE_CONTROL, page); +} + static int ip101a_g_has_page_register(struct phy_device *phydev) { int oldval, val, ret; @@ -390,6 +427,8 @@ static struct phy_driver icplus_driver[] = { .name = "ICPlus IP101A", .match_phy_device = ip101a_match_phy_device, .probe = ip101a_g_probe, + .read_page = ip101a_read_page, + .write_page = ip101a_write_page, .config_intr = ip101a_g_config_intr, .handle_interrupt = ip101a_g_handle_interrupt, .config_init = ip101a_config_init, @@ -400,6 +439,8 @@ static struct phy_driver icplus_driver[] = { .name = "ICPlus IP101G", .match_phy_device = ip101g_match_phy_device, .probe = ip101a_g_probe, + .read_page = ip101g_read_page, + .write_page = ip101g_write_page, .config_intr = ip101a_g_config_intr, .handle_interrupt = ip101a_g_handle_interrupt, .config_init = ip101g_config_init, -- 2.20.1