From patchwork Sat Apr 25 22:52:51 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grant Likely X-Patchwork-Id: 26454 Return-Path: X-Original-To: patchwork-incoming@bilbo.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ozlabs.org (ozlabs.org [203.10.76.45]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "mx.ozlabs.org", Issuer "CA Cert Signing Authority" (verified OK)) by bilbo.ozlabs.org (Postfix) with ESMTPS id 053A7B7067 for ; Sun, 26 Apr 2009 08:56:55 +1000 (EST) Received: by ozlabs.org (Postfix) id A8F1B4F763; Sun, 26 Apr 2009 08:54:56 +1000 (EST) Delivered-To: patchwork-incoming@ozlabs.org Received: from ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix) with ESMTP id A67C24F762 for ; Sun, 26 Apr 2009 08:54:56 +1000 (EST) X-Original-To: linuxppc-dev@ozlabs.org Delivered-To: linuxppc-dev@ozlabs.org Received: from rv-out-0506.google.com (rv-out-0506.google.com [209.85.198.225]) by ozlabs.org (Postfix) with ESMTP id 679684F39D for ; Sun, 26 Apr 2009 08:52:54 +1000 (EST) Received: by rv-out-0506.google.com with SMTP id f9so973104rvb.1 for ; Sat, 25 Apr 2009 15:52:54 -0700 (PDT) Received: by 10.141.132.1 with SMTP id j1mr1131217rvn.124.1240699974008; Sat, 25 Apr 2009 15:52:54 -0700 (PDT) Received: from trillian.cg.shawcable.net (S01060016b61d1226.cg.shawcable.net [68.146.92.145]) by mx.google.com with ESMTPS id b39sm81998rvf.39.2009.04.25.15.52.52 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sat, 25 Apr 2009 15:52:53 -0700 (PDT) Received: from localhost.localdomain (trillian [127.0.0.1]) by trillian.cg.shawcable.net (Postfix) with ESMTP id 60C5DC8560; Sat, 25 Apr 2009 16:52:51 -0600 (MDT) From: Grant Likely Subject: [PATCH v3 03/13] phylib: add *_direct() variants of phy_connect and phy_attach functions To: linuxppc-dev@ozlabs.org, netdev@vger.kernel.org, Andy Fleming , David Miller , Benjamin Herrenschmidt Date: Sat, 25 Apr 2009 16:52:51 -0600 Message-ID: <20090425225251.32392.51049.stgit@localhost.localdomain> In-Reply-To: <20090425224458.32392.31296.stgit@localhost.localdomain> References: <20090425224458.32392.31296.stgit@localhost.localdomain> User-Agent: StGIT/0.14.2 MIME-Version: 1.0 Cc: Andy Fleming X-BeenThere: linuxppc-dev@ozlabs.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org From: Grant Likely Add phy_connect_direct() and phy_attach_direct() functions so that drivers can use a pointer to the phy_device instead of trying to determine the phy's bus_id string. This patch is useful for OF device tree descriptions of phy devices where the driver doesn't need or know what the bus_id value in order to get a phy_device pointer. Signed-off-by: Grant Likely Acked-by: Andy Fleming --- drivers/net/phy/phy_device.c | 118 ++++++++++++++++++++++++++++++------------ include/linux/phy.h | 5 ++ 2 files changed, 90 insertions(+), 33 deletions(-) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 9352ca8..a2ece89 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -292,6 +292,33 @@ void phy_prepare_link(struct phy_device *phydev, } /** + * phy_connect_direct - connect an ethernet device to a specific phy_device + * @dev: the network device to connect + * @phydev: the pointer to the phy device + * @handler: callback function for state change notifications + * @flags: PHY device's dev_flags + * @interface: PHY device's interface + */ +int phy_connect_direct(struct net_device *dev, struct phy_device *phydev, + void (*handler)(struct net_device *), u32 flags, + phy_interface_t interface) +{ + int rc; + + rc = phy_attach_direct(dev, phydev, flags, interface); + if (rc) + return rc; + + phy_prepare_link(phydev, handler); + phy_start_machine(phydev, NULL); + if (phydev->irq > 0) + phy_start_interrupts(phydev); + + return 0; +} +EXPORT_SYMBOL(phy_connect_direct); + +/** * phy_connect - connect an ethernet device to a PHY device * @dev: the network device to connect * @bus_id: the id string of the PHY device to connect @@ -312,18 +339,21 @@ struct phy_device * phy_connect(struct net_device *dev, const char *bus_id, phy_interface_t interface) { struct phy_device *phydev; + struct device *d; + int rc; - phydev = phy_attach(dev, bus_id, flags, interface); - - if (IS_ERR(phydev)) - return phydev; - - phy_prepare_link(phydev, handler); - - phy_start_machine(phydev, NULL); + /* Search the list of PHY devices on the mdio bus for the + * PHY with the requested name */ + d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id); + if (!d) { + pr_err("PHY %s not found\n", bus_id); + return ERR_PTR(-ENODEV); + } + phydev = to_phy_device(d); - if (phydev->irq > 0) - phy_start_interrupts(phydev); + rc = phy_connect_direct(dev, phydev, handler, flags, interface); + if (rc) + return ERR_PTR(rc); return phydev; } @@ -347,9 +377,9 @@ void phy_disconnect(struct phy_device *phydev) EXPORT_SYMBOL(phy_disconnect); /** - * phy_attach - attach a network device to a particular PHY device + * phy_attach_direct - attach a network device to a given PHY device pointer * @dev: network device to attach - * @bus_id: PHY device to attach + * @phydev: Pointer to phy_device to attach * @flags: PHY device's dev_flags * @interface: PHY device's interface * @@ -360,22 +390,10 @@ EXPORT_SYMBOL(phy_disconnect); * the attaching device, and given a callback for link status * change. The phy_device is returned to the attaching driver. */ -struct phy_device *phy_attach(struct net_device *dev, - const char *bus_id, u32 flags, phy_interface_t interface) +int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, + u32 flags, phy_interface_t interface) { - struct bus_type *bus = &mdio_bus_type; - struct phy_device *phydev; - struct device *d; - - /* Search the list of PHY devices on the mdio bus for the - * PHY with the requested name */ - d = bus_find_device_by_name(bus, NULL, bus_id); - if (d) { - phydev = to_phy_device(d); - } else { - printk(KERN_ERR "%s not found\n", bus_id); - return ERR_PTR(-ENODEV); - } + struct device *d = &phydev->dev; /* Assume that if there is no driver, that it doesn't * exist, and we should use the genphy driver. */ @@ -388,13 +406,12 @@ struct phy_device *phy_attach(struct net_device *dev, err = device_bind_driver(d); if (err) - return ERR_PTR(err); + return err; } if (phydev->attached_dev) { - printk(KERN_ERR "%s: %s already attached\n", - dev->name, bus_id); - return ERR_PTR(-EBUSY); + dev_err(&dev->dev, "PHY already attached\n"); + return -EBUSY; } phydev->attached_dev = dev; @@ -412,13 +429,48 @@ struct phy_device *phy_attach(struct net_device *dev, err = phy_scan_fixups(phydev); if (err < 0) - return ERR_PTR(err); + return err; err = phydev->drv->config_init(phydev); if (err < 0) - return ERR_PTR(err); + return err; + } + + return 0; +} +EXPORT_SYMBOL(phy_attach_direct); + +/** + * phy_attach - attach a network device to a particular PHY device + * @dev: network device to attach + * @bus_id: Bus ID of PHY device to attach + * @flags: PHY device's dev_flags + * @interface: PHY device's interface + * + * Description: Same as phy_attach_direct() except that a PHY bus_id + * string is passed instead of a pointer to a struct phy_device. + */ +struct phy_device *phy_attach(struct net_device *dev, + const char *bus_id, u32 flags, phy_interface_t interface) +{ + struct bus_type *bus = &mdio_bus_type; + struct phy_device *phydev; + struct device *d; + int rc; + + /* Search the list of PHY devices on the mdio bus for the + * PHY with the requested name */ + d = bus_find_device_by_name(bus, NULL, bus_id); + if (!d) { + pr_err("PHY %s not found\n", bus_id); + return ERR_PTR(-ENODEV); } + phydev = to_phy_device(d); + + rc = phy_attach_direct(dev, phydev, flags, interface); + if (rc) + return ERR_PTR(rc); return phydev; } diff --git a/include/linux/phy.h b/include/linux/phy.h index c0cf354..cd404f1 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -441,8 +441,13 @@ struct phy_device* get_phy_device(struct mii_bus *bus, int addr); int phy_device_register(struct phy_device *phy); int phy_clear_interrupt(struct phy_device *phydev); int phy_config_interrupt(struct phy_device *phydev, u32 interrupts); +int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, + u32 flags, phy_interface_t interface); struct phy_device * phy_attach(struct net_device *dev, const char *bus_id, u32 flags, phy_interface_t interface); +int phy_connect_direct(struct net_device *dev, struct phy_device *phydev, + void (*handler)(struct net_device *), u32 flags, + phy_interface_t interface); struct phy_device * phy_connect(struct net_device *dev, const char *bus_id, void (*handler)(struct net_device *), u32 flags, phy_interface_t interface);