From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.1 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A3C3AC282C4 for ; Mon, 4 Feb 2019 08:59:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6A8B4214DA for ; Mon, 4 Feb 2019 08:59:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=nxp.com header.i=@nxp.com header.b="WhkBJXUN" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728812AbfBDI75 (ORCPT ); Mon, 4 Feb 2019 03:59:57 -0500 Received: from mail-eopbgr140043.outbound.protection.outlook.com ([40.107.14.43]:37457 "EHLO EUR01-VE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726320AbfBDI74 (ORCPT ); Mon, 4 Feb 2019 03:59:56 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=+1Ibr5wy0dTfgF8uuF9jIUDSfvdDlnkllT3hb1LLxuA=; b=WhkBJXUNYdC0ZctgiQbr9BH2ZI5Fz4Sa/MWYeh2XJdffdYUfnNCTwy2qO00/XOKmgFWuO/B+fylfvKrO6Tde9/kE9SmVtd5SFTJ3aEB0aLfbn6VyYrItdnbOPWBaerltMs+69k7/cbPyakh7zfzdj9b38DNpJVvQlaoiLhpbcvw= Received: from VI1PR0401MB2496.eurprd04.prod.outlook.com (10.168.65.10) by VI1PR0401MB2270.eurprd04.prod.outlook.com (10.169.133.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1580.17; Mon, 4 Feb 2019 08:59:50 +0000 Received: from VI1PR0401MB2496.eurprd04.prod.outlook.com ([fe80::208f:755e:b057:2cfe]) by VI1PR0401MB2496.eurprd04.prod.outlook.com ([fe80::208f:755e:b057:2cfe%8]) with mapi id 15.20.1580.019; Mon, 4 Feb 2019 08:59:50 +0000 From: Pankaj Bansal To: Andrew Lunn , Florian Fainelli CC: "netdev@vger.kernel.org" , Pankaj Bansal Subject: [PATCH v2 2/2] netdev/phy: add MDIO bus multiplexer driven by a regmap Thread-Topic: [PATCH v2 2/2] netdev/phy: add MDIO bus multiplexer driven by a regmap Thread-Index: AQHUvGf8eVjLXeG4dEupfRDAu+emoA== Date: Mon, 4 Feb 2019 08:59:50 +0000 Message-ID: <20190204142435.21175-3-pankaj.bansal@nxp.com> References: <20190204142435.21175-1-pankaj.bansal@nxp.com> In-Reply-To: <20190204142435.21175-1-pankaj.bansal@nxp.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: BM1PR0101CA0015.INDPRD01.PROD.OUTLOOK.COM (2603:1096:b00:18::25) To VI1PR0401MB2496.eurprd04.prod.outlook.com (2603:10a6:800:56::10) x-ms-exchange-messagesentrepresentingtype: 1 x-mailer: git-send-email 2.17.1 x-originating-ip: [92.120.1.69] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1;VI1PR0401MB2270;6:dVfSQtor4UpCaDMhVggV7bYucfsZaVXgrGwKxPbY90SMtOA4xk8JBeoOmfM0GS2ozoeynrfjxbRPx6DVyjiExLL+m2uNqLIMm/XKPgnySdmVvlBLnWEIgkkRFAHveOEffJY2IRAymhGEtZ1ysNAE+/3ERw98wYaTSz2udL6abCybax92WitcASh+8snIbaQclTZ6bQw1uCTiEu6KL5XoHiwFzIATmLHVZs2XxvbTiHGubYqum9g/QzkvzaMIA+Jv/wQUlP9lvAZvfOtdwZo5DjtL0cRPzi34ziah08H+vL7saNuA868P/Enlk0zdEINuE7R4WBH6uu5qPP4NM939NyHtoOLNnk1RgLHyCY5urJ9UUhpLWKx9mU0ju5NF1hIRTh8sxt4wzBhQD6VuphlJLuPHen1oCQoRHWPmaR+0yW4RVcujwhEnHJTKgrJdUD4jn6o+ur1uzYlNcC5qh4eW9Q==;5:lLayyQI5oTMbba/Y5heEpH8dLDkYQg263osrFZqUjSPM0pTBzAXUuOqkBKQWiZds+Ct7dWeqKReLJYgFuz+z8ORujAbvrnxlbwjDlDCVVgKnwSRkaX27lciORNjTeaQJ4nvUbDPHneNwPbTU9xvpkyivl5WGRTyvMcJFkURH80iYJ1gqryYYe6axrhlasnr/eqCka7uAGXsVk3SATFs1qg==;7:MoFtHWVUr2AfM6I9n0JkkWBtLW4aeMxhxpewDhtOohQfyu6+lKBJDS31iFDyDYRoAbPMLzNtEcTECvR3BACNdBmxHtuM2OsyMR6eTbAizmLhvUbfUi29nMlP2eT83ymriI48P33xi/QS881x2AVBGg== x-ms-office365-filtering-correlation-id: 34354c13-135b-45bf-a6df-08d68a7f1ec4 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(5600110)(711020)(4605077)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7153060)(7193020);SRVR:VI1PR0401MB2270; x-ms-traffictypediagnostic: VI1PR0401MB2270: authentication-results: spf=none (sender IP is ) smtp.mailfrom=pankaj.bansal@nxp.com; x-microsoft-antispam-prvs: x-forefront-prvs: 0938781D02 x-forefront-antispam-report: SFV:NSPM;SFS:(10009020)(376002)(39860400002)(136003)(396003)(366004)(346002)(189003)(199004)(5024004)(14444005)(256004)(316002)(305945005)(81156014)(7736002)(6486002)(81166006)(54906003)(6506007)(86362001)(386003)(3846002)(6116002)(14454004)(97736004)(68736007)(36756003)(8676002)(50226002)(106356001)(2906002)(105586002)(25786009)(26005)(6436002)(76176011)(2616005)(446003)(44832011)(4326008)(476003)(71200400001)(52116002)(71190400001)(8936002)(486006)(186003)(6512007)(53936002)(102836004)(110136005)(1076003)(478600001)(66066001)(39060400002)(99286004)(11346002);DIR:OUT;SFP:1101;SCL:1;SRVR:VI1PR0401MB2270;H:VI1PR0401MB2496.eurprd04.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: 1JgoB8ZSNn7Ob2t+L7G8FTpskXY/Dp36y/R4rAuOGyaVNQ9hUnDzm7sf9ih1ioVKkXSQV8vkfuG/gPLgD6mapELE3AyX43jEJQjTrlmLSdP1XYtH7iUKGyWl0VQ1tjkQJgYoxpVGdhhWq2GeHzIrLXOhWb/YwGBopHHs02JYqgqYjF9VVyDznuPnidfd/Ox3CStIO0MzNYUo1Eu81ruy20rbCZER/OKbrSClndicfG7/xfDF/FAJ8aZzCSe/Jp77yhIw0IZ1yDJ9VSaYMgInSEsgwssissr0OZfyGw6egTupjNQ+VNfIOYxjMOWOXvINQd29fLhcOcK4JThFMAwlYzjmebr5MHOz7P0rW1ieKzi4oNczFsG36tuFi4LhkkOgDBDn5SeR+jzkXpwagMeMVEw5uB+Jltj8mhZHwwQztS0= Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 34354c13-135b-45bf-a6df-08d68a7f1ec4 X-MS-Exchange-CrossTenant-originalarrivaltime: 04 Feb 2019 08:59:49.1699 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0401MB2270 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add support for an MDIO bus multiplexer controlled by a regmap device, like an FPGA. Tested on a NXP LX2160AQDS board which uses the "QIXIS" FPGA attached to the i2c bus. Signed-off-by: Pankaj Bansal --- Notes: V2: - Added Kconfig entry for regmap based mdio mux - restrict the comment lines to 80 chars - use kerneldoc formatting for this function documentation. drivers/net/phy/Kconfig | 14 +++ drivers/net/phy/Makefile | 1 + drivers/net/phy/mdio-mux-regmap.c | 171 ++++++++++++++++++++++++++++ include/linux/mdio-mux.h | 34 ++++++ 4 files changed, 220 insertions(+) diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 3d187cd50eb0..93ef2505caba 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -87,6 +87,20 @@ config MDIO_BUS_MUX_MMIOREG =20 Currently, only 8/16/32 bits registers are supported. =20 +config MDIO_BUS_MUX_REGMAP + tristate "regmap device controlled MDIO bus multiplexers" + depends on OF_MDIO && REGMAP + select MDIO_BUS_MUX + help + This module provides a driver for MDIO bus multiplexers that + are controlled via a regmap device, like an FPGA connected to i2c bus + or spi bus or memory mapped FPGA. + The multiplexer connects one of several child MDIO busses to a + parent bus. Child bus selection is under the control of one of + the FPGA's registers. + + Currently, only 32 bits registers are supported. + config MDIO_CAVIUM tristate =20 diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 5805c0b7d60e..0827a700eb31 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_MDIO_BCM_IPROC) +=3D mdio-bcm-iproc.o obj-$(CONFIG_MDIO_BCM_UNIMAC) +=3D mdio-bcm-unimac.o obj-$(CONFIG_MDIO_BITBANG) +=3D mdio-bitbang.o obj-$(CONFIG_MDIO_BUS_MUX) +=3D mdio-mux.o +obj-$(CONFIG_MDIO_BUS_MUX_REGMAP) +=3D mdio-mux-regmap.o obj-$(CONFIG_MDIO_BUS_MUX_BCM_IPROC) +=3D mdio-mux-bcm-iproc.o obj-$(CONFIG_MDIO_BUS_MUX_GPIO) +=3D mdio-mux-gpio.o obj-$(CONFIG_MDIO_BUS_MUX_MMIOREG) +=3D mdio-mux-mmioreg.o diff --git a/drivers/net/phy/mdio-mux-regmap.c b/drivers/net/phy/mdio-mux-r= egmap.c new file mode 100644 index 000000000000..f2cb3cad1d9b --- /dev/null +++ b/drivers/net/phy/mdio-mux-regmap.c @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* Simple regmap based MDIO MUX driver + * + * Copyright 2018-2019 NXP + * + * Based on mdio-mux-mmioreg.c by Timur Tabi + * + * Author: + * Pankaj Bansal + */ + +#include +#include +#include +#include +#include +#include +#include + +struct mdio_mux_regmap_state { + void *mux_handle; + struct device *dev; + struct regmap *regmap; + u32 mux_reg; + u32 mask; +}; + +/** + * mdio_mux_regmap_switch_fn - This function is called by the mdio-mux lay= er + * when it thinks the mdio bus multiplexer needs + * to switch. + * @current_child: current value of the mux register (masked via s->mask)= . + * @desired_child: value of the 'reg' property of the target child MDIO no= de. + * @data: Private data used by this switch_fn passed to mdio_mux_init func= tion + * via mdio_mux_init(.., .., .., .., data, ..). + * + * The first time this function is called, current_child =3D=3D -1. + * If current_child =3D=3D desired_child, then the mux is already set to t= he + * correct bus. + */ +static int mdio_mux_regmap_switch_fn(int current_child, int desired_child, + void *data) +{ + struct mdio_mux_regmap_state *s =3D data; + bool change; + int ret; + + ret =3D regmap_update_bits_check(s->regmap, + s->mux_reg, + s->mask, + desired_child, + &change); + + if (ret) + return ret; + if (change) + dev_dbg(s->dev, "%s %d -> %d\n", __func__, current_child, + desired_child); + return ret; +} + +/** + * mdio_mux_regmap_init - control MDIO bus muxing using regmap constructs. + * @dev: device with which regmap construct is associated. + * @mux_node: mdio bus mux node that contains parent mdio bus phandle. + * This node also contains sub nodes, where each subnode denotes + * a child mdio bus. All the child mdio buses are muxed, i.e. at a + * time only one of the child mdio buses can be used. + * @data: to store the address of data allocated by this function + */ +int mdio_mux_regmap_init(struct device *dev, + struct device_node *mux_node, + void **data) +{ + struct device_node *child; + struct mdio_mux_regmap_state *s; + int ret; + u32 val; + + dev_dbg(dev, "probing node %pOF\n", mux_node); + + s =3D devm_kzalloc(dev, sizeof(*s), GFP_KERNEL); + if (!s) + return -ENOMEM; + + s->regmap =3D dev_get_regmap(dev, NULL); + if (IS_ERR(s->regmap)) { + dev_err(dev, "Failed to get parent regmap\n"); + return PTR_ERR(s->regmap); + } + + ret =3D of_property_read_u32(mux_node, "reg", &s->mux_reg); + if (ret) { + dev_err(dev, "missing or invalid reg property\n"); + return -ENODEV; + } + + /* Test Register read write */ + ret =3D regmap_read(s->regmap, s->mux_reg, &val); + if (ret) { + dev_err(dev, "error while reading reg\n"); + return ret; + } + + ret =3D regmap_write(s->regmap, s->mux_reg, val); + if (ret) { + dev_err(dev, "error while writing reg\n"); + return ret; + } + + ret =3D of_property_read_u32(mux_node, "mux-mask", &s->mask); + if (ret) { + dev_err(dev, "missing or invalid mux-mask property\n"); + return -ENODEV; + } + + /* Verify that the 'reg' property of each child MDIO bus does not + * set any bits outside of the 'mask'. + */ + for_each_available_child_of_node(mux_node, child) { + ret =3D of_property_read_u32(child, "reg", &val); + if (ret) { + dev_err(dev, "%pOF is missing a 'reg' property\n", + child); + of_node_put(child); + return -ENODEV; + } + if (val & ~s->mask) { + dev_err(dev, + "%pOF has a 'reg' value with unmasked bits\n", + child); + of_node_put(child); + return -ENODEV; + } + } + + ret =3D mdio_mux_init(dev, mux_node, mdio_mux_regmap_switch_fn, + &s->mux_handle, s, NULL); + if (ret) { + if (ret !=3D -EPROBE_DEFER) + dev_err(dev, "failed to register mdio-mux bus %pOF\n", + mux_node); + return ret; + } + + *data =3D s; + + return 0; +} +EXPORT_SYMBOL_GPL(mdio_mux_regmap_init); + +/** + * mdio_mux_regmap_uninit - relinquish the control of MDIO bus muxing usin= g + * regmap constructs. + * @data: address of data allocated by mdio_mux_regmap_init + */ +int mdio_mux_regmap_uninit(void *data) +{ + struct mdio_mux_regmap_state *s =3D data; + + mdio_mux_uninit(s->mux_handle); + + return 0; +} +EXPORT_SYMBOL_GPL(mdio_mux_regmap_uninit); + +MODULE_AUTHOR("Pankaj Bansal "); +MODULE_DESCRIPTION("regmap based MDIO MUX driver"); +MODULE_LICENSE("GPL"); + diff --git a/include/linux/mdio-mux.h b/include/linux/mdio-mux.h index a5d58f221939..fb715d56999b 100644 --- a/include/linux/mdio-mux.h +++ b/include/linux/mdio-mux.h @@ -29,4 +29,38 @@ int mdio_mux_init(struct device *dev, =20 void mdio_mux_uninit(void *mux_handle); =20 +#ifdef CONFIG_MDIO_BUS_MUX_REGMAP +/** + * mdio_mux_regmap_init - control MDIO bus muxing using regmap constructs. + * @dev: device with which regmap construct is associated. + * @mux_node: mdio bus mux node that contains parent mdio bus phandle. + * This node also contains sub nodes, where each subnode denotes + * a child mdio bus. All the child mdio buses are muxed, i.e. at a + * time only one of the child mdio buses can be used. + * @data: to store the address of data allocated by this function + */ +int mdio_mux_regmap_init(struct device *dev, + struct device_node *mux_node, + void **data); + +/** + * mdio_mux_regmap_uninit - relinquish the control of MDIO bus muxing usin= g + * regmap constructs. + * @data: address of data allocated by mdio_mux_regmap_init + */ +int mdio_mux_regmap_uninit(void *data); +#else /* CONFIG_MDIO_BUS_MUX_REGMAP */ +static inline int mdio_mux_regmap_init(struct device *dev, + struct device_node *mux_node, + void **data) +{ + return -ENODEV; +} + +static inline int mdio_mux_regmap_uninit(void *data) +{ + return 0; +} +#endif /* CONFIG_MDIO_BUS_MUX_REGMAP */ + #endif /* __LINUX_MDIO_MUX_H */ --=20 2.17.1