From patchwork Tue Oct 29 09:33:31 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leigh Brown X-Patchwork-Id: 3106951 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 4ABA7BF924 for ; Tue, 29 Oct 2013 09:34:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id ED9CF20219 for ; Tue, 29 Oct 2013 09:34:35 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C0CB9201BC for ; Tue, 29 Oct 2013 09:34:33 +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 1Vb5h0-0008HI-Lg; Tue, 29 Oct 2013 09:34:30 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vb5gy-0003gn-8N; Tue, 29 Oct 2013 09:34:28 +0000 Received: from doppler.thel33t.co.uk ([193.110.88.198]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vb5gu-0003dm-3Z for linux-arm-kernel@lists.infradead.org; Tue, 29 Oct 2013 09:34:25 +0000 Received: from dish.dyn.solinno.co.uk. (82-68-130-54.dsl.in-addr.zen.co.uk [82.68.130.54]) by doppler.thel33t.co.uk (Postfix) with ESMTPSA id 01917840B5; Tue, 29 Oct 2013 09:38:39 +0000 (GMT) From: Leigh Brown To: "David S. Miller" Subject: [PATCH v3 1/4] net: mvmdio: make orion_mdio_wait_ready consistent Date: Tue, 29 Oct 2013 09:33:31 +0000 Message-Id: X-Mailer: git-send-email 1.8.4.rc3 In-Reply-To: References: In-Reply-To: References: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131029_053424_347170_F4E364BE X-CRM114-Status: GOOD ( 14.46 ) X-Spam-Score: -1.9 (-) Cc: Thomas Petazzoni , Leigh Brown , Jason Cooper , netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Sebastian Hesselbarth 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.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 Amend orion_mdio_wait_ready so that the same timeout is used when polling or using wait_event_timeout. Set the timeout to 1ms. Replace udelay with usleep_range to avoid a busy loop, and set the polling interval range as 45us to 55us, so that the first sleep will be enough in almost all cases. Generate the same log message at timeout when polling or using wait_event_timeout. Signed-off-by: Leigh Brown --- drivers/net/ethernet/marvell/mvmdio.c | 52 ++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c index e2f6626..971a4c1 100644 --- a/drivers/net/ethernet/marvell/mvmdio.c +++ b/drivers/net/ethernet/marvell/mvmdio.c @@ -44,6 +44,15 @@ #define MVMDIO_ERR_INT_SMI_DONE 0x00000010 #define MVMDIO_ERR_INT_MASK 0x0080 +/* + * SMI Timeout measurements: + * - Kirkwood 88F6281 (Globalscale Dreamplug): 45us to 95us (Interrupt) + * - Armada 370 (Globalscale Mirabox): 41us to 43us (Polled) + */ +#define MVMDIO_SMI_TIMEOUT 1000 /* 1000us = 1ms */ +#define MVMDIO_SMI_POLL_INTERVAL_MIN 45 +#define MVMDIO_SMI_POLL_INTERVAL_MAX 55 + struct orion_mdio_dev { struct mutex lock; void __iomem *regs; @@ -68,34 +77,33 @@ static int orion_mdio_smi_is_done(struct orion_mdio_dev *dev) static int orion_mdio_wait_ready(struct mii_bus *bus) { struct orion_mdio_dev *dev = bus->priv; - int count; + unsigned long timeout = usecs_to_jiffies(MVMDIO_SMI_TIMEOUT); + unsigned long end = jiffies + timeout; + int timedout = 0; - if (dev->err_interrupt <= 0) { - count = 0; - while (1) { - if (orion_mdio_smi_is_done(dev)) - break; + while (1) { + if (orion_mdio_smi_is_done(dev)) + return 0; + else if (timedout) + break; - if (count > 100) { - dev_err(bus->parent, - "Timeout: SMI busy for too long\n"); - return -ETIMEDOUT; - } + if (dev->err_interrupt <= 0) { + usleep_range(MVMDIO_SMI_POLL_INTERVAL_MIN, + MVMDIO_SMI_POLL_INTERVAL_MAX); - udelay(10); - count++; - } - } else { - if (!orion_mdio_smi_is_done(dev)) { + if (time_is_before_jiffies(end)) + ++timedout; + } else { wait_event_timeout(dev->smi_busy_wait, - orion_mdio_smi_is_done(dev), - msecs_to_jiffies(100)); - if (!orion_mdio_smi_is_done(dev)) - return -ETIMEDOUT; - } + orion_mdio_smi_is_done(dev), + timeout); + + ++timedout; + } } - return 0; + dev_err(bus->parent, "Timeout: SMI busy for too long\n"); + return -ETIMEDOUT; } static int orion_mdio_read(struct mii_bus *bus, int mii_id,