From patchwork Tue Mar 31 08:27:14 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grant Likely X-Patchwork-Id: 25354 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.176.167]) by ozlabs.org (Postfix) with ESMTP id 8172EDDF4B for ; Tue, 31 Mar 2009 19:27:24 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752088AbZCaI1W (ORCPT ); Tue, 31 Mar 2009 04:27:22 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753142AbZCaI1W (ORCPT ); Tue, 31 Mar 2009 04:27:22 -0400 Received: from wa-out-1112.google.com ([209.85.146.182]:47063 "EHLO wa-out-1112.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753445AbZCaI1T (ORCPT ); Tue, 31 Mar 2009 04:27:19 -0400 Received: by wa-out-1112.google.com with SMTP id j5so1584813wah.21 for ; Tue, 31 Mar 2009 01:27:17 -0700 (PDT) Received: by 10.114.176.1 with SMTP id y1mr4226576wae.49.1238488037098; Tue, 31 Mar 2009 01:27:17 -0700 (PDT) Received: from trillian.cg.shawcable.net (S01060016b61d1226.cg.shawcable.net [68.146.92.145]) by mx.google.com with ESMTPS id k37sm5339012waf.7.2009.03.31.01.27.15 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 31 Mar 2009 01:27:16 -0700 (PDT) Received: from localhost.localdomain (trillian [127.0.0.1]) by trillian.cg.shawcable.net (Postfix) with ESMTP id E181AC8085; Tue, 31 Mar 2009 02:27:14 -0600 (MDT) From: Grant Likely Subject: [PATCH 06/14] openfirmware: Add OF phylib support code To: netdev@vger.kernel.org, linuxppc-dev@ozlabs.org Cc: olof@lixom.net, afleming@freescale.com, galak@kernel.crashing.org, Anton Vorontsov , Joakim Tjernlund Date: Tue, 31 Mar 2009 02:27:14 -0600 Message-ID: <20090331082714.1427.19541.stgit@localhost.localdomain> In-Reply-To: <20090331075537.1427.7819.stgit@localhost.localdomain> References: <20090331075537.1427.7819.stgit@localhost.localdomain> User-Agent: StGIT/0.14.2 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Grant Likely Add support for parsing the device tree for PHY devices on an MDIO bus CC: Andy Fleming CC: linuxppc-dev@ozlabs.org CC: devtree-discuss@ozlabs.org Signed-off-by: Grant Likely --- drivers/of/Kconfig | 6 ++ drivers/of/Makefile | 1 drivers/of/of_mdio.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/of_mdio.h | 22 +++++++ 4 files changed, 168 insertions(+), 0 deletions(-) create mode 100644 drivers/of/of_mdio.c create mode 100644 include/linux/of_mdio.h -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index f821dbc..6fe043b 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -19,3 +19,9 @@ config OF_SPI depends on OF && PPC_OF && SPI help OpenFirmware SPI accessors + +config OF_MDIO + def_tristate PHYLIB + depends on OF && PHYLIB + help + OpenFirmware MDIO bus (Ethernet PHY) accessors diff --git a/drivers/of/Makefile b/drivers/of/Makefile index 4c3c6f8..bdfb5f5 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_OF_DEVICE) += device.o platform.o obj-$(CONFIG_OF_GPIO) += gpio.o obj-$(CONFIG_OF_I2C) += of_i2c.o obj-$(CONFIG_OF_SPI) += of_spi.o +obj-$(CONFIG_OF_MDIO) += of_mdio.o diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c new file mode 100644 index 0000000..aee967d --- /dev/null +++ b/drivers/of/of_mdio.c @@ -0,0 +1,139 @@ +/* + * OF helpers for the MDIO (Ethernet PHY) API + * + * Copyright (c) 2009 Secret Lab Technologies, Ltd. + * + * This file is released under the GPLv2 + * + * This file provides helper functions for extracting PHY device information + * out of the OpenFirmware device tree and using it to populate an mii_bus. + */ + +#include +#include +#include +#include + +MODULE_AUTHOR("Grant Likely "); +MODULE_LICENSE("GPL"); + +/** + * of_mdiobus_register - Register mii_bus and create PHYs from the device tree + * @mdio: pointer to mii_bus structure + * @np: pointer to device_node of MDIO bus. + * + * This function registers the mii_bus structure and registers a phy_device + * for each child node of @np. + */ +int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) +{ + struct phy_device *phy; + struct device_node *child; + int rc, i; + + /* Mask out all PHYs from auto probing. Instead the PHYs listed in + * the device tree are populated after the bus has been registered */ + mdio->phy_mask = ~0; + + /* Clear all the IRQ properties */ + if (mdio->irq) + for (i=0; iirq[i] = PHY_POLL; + + /* Register the MDIO bus */ + rc = mdiobus_register(mdio); + if (rc) + return rc; + + /* Loop over the child nodes and register a phy_device for each one */ + for_each_child_of_node(np, child) { + const u32 *addr; + int len; + + /* A PHY must have a reg property in the range [0-31] */ + addr = of_get_property(child, "reg", &len); + if (!addr || len < sizeof(*addr) || *addr >= 32 || *addr < 0) { + dev_err(&mdio->dev, "%s has invalid PHY address\n", + child->full_name); + continue; + } + + if (mdio->irq) { + mdio->irq[*addr] = irq_of_parse_and_map(child, 0); + if (!mdio->irq[*addr]) + mdio->irq[*addr] = PHY_POLL; + } + + phy = get_phy_device(mdio, *addr); + if (!phy) { + dev_err(&mdio->dev, "error probing PHY at address %i\n", + *addr); + continue; + } + phy_scan_fixups(phy); + + /* Associate the OF node with the device structure so it + * can be looked up later */ + of_node_get(child); + dev_archdata_set_node(&phy->dev.archdata, child); + + /* All data is now stored in the phy struct; register it */ + rc = phy_device_register(phy); + if (rc) { + phy_device_free(phy); + of_node_put(child); + continue; + } + + dev_dbg(&mdio->dev, "registered phy %s at address %i\n", + child->name, *addr); + } + + return 0; +} +EXPORT_SYMBOL(of_mdiobus_register); + +/** + * of_phy_find_device - Give a PHY node, find the phy_device + * @phy_np: Pointer to the phy's device tree node + * + * Returns a pointer to the phy_device. + */ +struct phy_device *of_phy_find_device(struct device_node *phy_np) +{ + struct device *d; + int match(struct device *dev, void *phy_np) + { + return dev_archdata_get_node(&dev->archdata) == phy_np; + } + + if (!phy_np) + return NULL; + + d = bus_find_device(&mdio_bus_type, NULL, phy_np, match); + return d ? to_phy_device(d) : NULL; +} +EXPORT_SYMBOL(of_phy_find_device); + +/** + * of_phy_connect - Connect to the phy described in the device tree + * @dev: pointer to net_device claiming the phy + * @phy_np: Pointer to device tree node for the PHY + * @hndlr: Link state callback for the network device + * @iface: PHY data interface type + * + * Returns a pointer to the phy_device if successfull. NULL otherwise + */ +struct phy_device *of_phy_connect(struct net_device *dev, + struct device_node *phy_np, + void (*hndlr)(struct net_device *), u32 flags, + phy_interface_t iface) +{ + struct phy_device *phy = of_phy_find_device(phy_np); + + if (!phy) + return NULL; + + return phy_connect_direct(dev, phy, hndlr, flags, iface) ? NULL : phy; +} +EXPORT_SYMBOL(of_phy_connect); diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h new file mode 100644 index 0000000..c9663c6 --- /dev/null +++ b/include/linux/of_mdio.h @@ -0,0 +1,22 @@ +/* + * OF helpers for the MDIO (Ethernet PHY) API + * + * Copyright (c) 2009 Secret Lab Technologies, Ltd. + * + * This file is released under the GPLv2 + */ + +#ifndef __LINUX_OF_MDIO_H +#define __LINUX_OF_MDIO_H + +#include +#include + +extern int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np); +extern struct phy_device *of_phy_find_device(struct device_node *phy_np); +extern struct phy_device *of_phy_connect(struct net_device *dev, + struct device_node *phy_np, + void (*hndlr)(struct net_device *), + u32 flags, phy_interface_t iface); + +#endif /* __LINUX_OF_MDIO_H */