From patchwork Tue Jun 15 16:08:46 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Cochran X-Patchwork-Id: 55744 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 03BD3101FD2 for ; Wed, 16 Jun 2010 02:08:01 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753565Ab0FOQH4 (ORCPT ); Tue, 15 Jun 2010 12:07:56 -0400 Received: from mail-fx0-f46.google.com ([209.85.161.46]:43726 "EHLO mail-fx0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753559Ab0FOQHz (ORCPT ); Tue, 15 Jun 2010 12:07:55 -0400 Received: by mail-fx0-f46.google.com with SMTP id 10so266600fxm.19 for ; Tue, 15 Jun 2010 09:07:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:date:from:to:cc:subject :message-id:references:mime-version:content-type:content-disposition :in-reply-to:user-agent; bh=CCKGMBb+CuWhtlQDYiYzdLLlCq0unAjRF1YM6a4oi+E=; b=sIiIhK8b1NIxt65tJT+lKVmW+aTe1apXOAbNo7Ij2t2RFIpfwNPkqbgwUco9u9la9Y qzuqAl2cduuNrROsyXuK2KBSIOYuLsY+H2nWlhGyq8waoyVn0Dy3/qxfyxL9GmemANSG aQsFxunVaQpyOVWiAVXUg8LlRUwXelfRVOWA4= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; b=OPurLYc1IXFBLNMBeKGWJnmp0LkXAz6FAPhYNSS750HU8+Tay6jJTLn5jgt92nKANP oKZc1k50/EEiK5FVkMcf1eLqQxVMrW19GM4FMz9rJH/9uJhljErwubqUpX7Pm+0PzO9a MQMU+HYYmzfU9FptxeXcJKkd88x+cEFiRVNXY= Received: by 10.223.17.197 with SMTP id t5mr7477852faa.84.1276618074439; Tue, 15 Jun 2010 09:07:54 -0700 (PDT) Received: from riccoc20.at.omicron.at (vs162244.vserver.de [62.75.162.244]) by mx.google.com with ESMTPS id e11sm10089374fak.41.2010.06.15.09.07.53 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 15 Jun 2010 09:07:54 -0700 (PDT) Date: Tue, 15 Jun 2010 18:08:46 +0200 From: Richard Cochran To: netdev@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org, devicetree-discuss@lists.ozlabs.org, Krzysztof Halasa , linux-arm-kernel@lists.infradead.org Subject: [PATCH 05/12] phylib: Allow reading and writing a mii bus from atomic context. Message-ID: <1b8219e7d7993d0e8204b94e959477e3007534ce.1276615626.git.richard.cochran@omicron.at> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.20 (2009-06-14) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org In order to support hardware time stamping from a PHY, it is necessary to read from the PHY while running in_interrupt(). This patch allows a mii bus to operate in an atomic context. An mii_bus driver may declare itself capable for this mode. Drivers which do not do this will remain with the default that bus operations may sleep. Signed-off-by: Richard Cochran --- drivers/net/phy/mdio_bus.c | 35 ++++++++++++++++++++++++++++------- include/linux/phy.h | 13 +++++++++++-- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 6a6b819..441be7d 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -36,6 +36,22 @@ #include #include +static inline void mdiobus_lock(struct mii_bus *bus) +{ + if (MDIOBUS_SLEEPS_RW == bus->locktype) + mutex_lock(&bus->mdio_lock.m); + else + spin_lock(&bus->mdio_lock.s); +} + +static inline void mdiobus_unlock(struct mii_bus *bus) +{ + if (MDIOBUS_SLEEPS_RW == bus->locktype) + mutex_unlock(&bus->mdio_lock.m); + else + spin_unlock(&bus->mdio_lock.s); +} + /** * mdiobus_alloc - allocate a mii_bus structure * @@ -107,7 +123,10 @@ int mdiobus_register(struct mii_bus *bus) return -EINVAL; } - mutex_init(&bus->mdio_lock); + if (MDIOBUS_SLEEPS_RW == bus->locktype) + mutex_init(&bus->mdio_lock.m); + else + spin_lock_init(&bus->mdio_lock.s); if (bus->reset) bus->reset(bus); @@ -212,11 +231,12 @@ int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum) { int retval; - BUG_ON(in_interrupt()); + if (MDIOBUS_SLEEPS_RW == bus->locktype) + BUG_ON(in_interrupt()); - mutex_lock(&bus->mdio_lock); + mdiobus_lock(bus); retval = bus->read(bus, addr, regnum); - mutex_unlock(&bus->mdio_lock); + mdiobus_unlock(bus); return retval; } @@ -237,11 +257,12 @@ int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val) { int err; - BUG_ON(in_interrupt()); + if (MDIOBUS_SLEEPS_RW == bus->locktype) + BUG_ON(in_interrupt()); - mutex_lock(&bus->mdio_lock); + mdiobus_lock(bus); err = bus->write(bus, addr, regnum, val); - mutex_unlock(&bus->mdio_lock); + mdiobus_unlock(bus); return err; } diff --git a/include/linux/phy.h b/include/linux/phy.h index 7a8caac..352b030 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -98,11 +98,20 @@ struct mii_bus { int (*write)(struct mii_bus *bus, int phy_id, int regnum, u16 val); int (*reset)(struct mii_bus *bus); + /* Indicates whether bus may be used from an atomic context. */ + enum { + MDIOBUS_SLEEPS_RW, + MDIOBUS_ATOMIC_RW + } locktype; + /* - * A lock to ensure that only one thing can read/write + * A lock or mutex to ensure that only one thing can read/write * the MDIO bus at a time */ - struct mutex mdio_lock; + union { + struct mutex m; + spinlock_t s; + } mdio_lock; struct device *parent; enum {