From nobody Sun Oct 5 23:40:19 2025 Received: from out-189.mta1.migadu.com (out-189.mta1.migadu.com [95.215.58.189]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 46A1470813; Mon, 28 Jul 2025 22:18:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.189 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753741116; cv=none; b=ppTbZH9gv6MQNp7tF3a3lNDP1j9c4c1XNFciMf8A6tPDNGtbxEEhKgXOJqFMnod9PxSS2PS7nqHpSWgUh+RnIXBKFMDMcGNaRZSHnz5QK5w93elcUim+0g7ouaXaQzOdlqQkui250jN/S736EVD+NeCM1DWW0z4xuojaFHTdg3Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753741116; c=relaxed/simple; bh=UUxoVzcyD9RgSudkCBZCQ9NsJr4Lz/rWYjdz0jmLqOA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=liqmQUClNeQmytiv85dZYG/A42dxTreR9givSDp19BnAihcigk31MBNnY8AekczparD27DF84LHWwXatx0TmC/PV9M7H/o/K5elGysbBzChkb/zZiQMmpbBBiC+ldlOLY7FA2lU3D5WOn64w6+b2lQr6zI+wNC0eu3RCBzAVLMY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=caG6b1mq; arc=none smtp.client-ip=95.215.58.189 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="caG6b1mq" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1753741112; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ArPO0aSMNQ4VJy5Cn1NLmMTjUMksppDpeUXhdV8G3FI=; b=caG6b1mqcOoRc7hfIDQrtz1cYWaITOPREObfVtfKia1jZmN7vlxMHX9oKB6w2gS16QjJti xk0Q/+RixGLCsVhA12o23z0dwMnzGI7ozWRqpKHDodTU8HE0r2eUrg1DsdKgwirUfKTVyY 8FPDBeAay50CwX6i62DimCvO9iexmp8= From: Sean Anderson To: Radhey Shyam Pandey , Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Greg Kroah-Hartman , Michal Simek , linux-arm-kernel@lists.infradead.org, Leon Romanovsky , Sean Anderson Subject: [PATCH net-next v3 1/7] net: axienet: Fix resource release ordering Date: Mon, 28 Jul 2025 18:18:17 -0400 Message-Id: <20250728221823.11968-2-sean.anderson@linux.dev> In-Reply-To: <20250728221823.11968-1-sean.anderson@linux.dev> References: <20250728221823.11968-1-sean.anderson@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Device-managed resources are released after manually-managed resources. Therefore, once any manually-managed resource is acquired, all further resources must be manually-managed too. Convert all resources before the MDIO bus is created into device-managed resources. In all cases but one there are already devm variants available. Fixes: 46aa27df8853 ("net: axienet: Use devm_* calls") Signed-off-by: Sean Anderson --- (no changes since v1) .../net/ethernet/xilinx/xilinx_axienet_main.c | 89 ++++++++----------- 1 file changed, 37 insertions(+), 52 deletions(-) diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/ne= t/ethernet/xilinx/xilinx_axienet_main.c index 6011d7eae0c7..1f277e5e4a62 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -2744,6 +2744,11 @@ static void axienet_dma_err_handler(struct work_stru= ct *work) axienet_setoptions(ndev, lp->options); } =20 +static void axienet_disable_misc(void *clocks) +{ + clk_bulk_disable_unprepare(XAE_NUM_MISC_CLOCKS, clocks); +} + /** * axienet_probe - Axi Ethernet probe function. * @pdev: Pointer to platform device structure. @@ -2767,7 +2772,7 @@ static int axienet_probe(struct platform_device *pdev) int addr_width =3D 32; u32 value; =20 - ndev =3D alloc_etherdev(sizeof(*lp)); + ndev =3D devm_alloc_etherdev(&pdev->dev, sizeof(*lp)); if (!ndev) return -ENOMEM; =20 @@ -2795,22 +2800,17 @@ static int axienet_probe(struct platform_device *pd= ev) seqcount_mutex_init(&lp->hw_stats_seqcount, &lp->stats_lock); INIT_DEFERRABLE_WORK(&lp->stats_work, axienet_refresh_stats); =20 - lp->axi_clk =3D devm_clk_get_optional(&pdev->dev, "s_axi_lite_clk"); + lp->axi_clk =3D devm_clk_get_optional_enabled(&pdev->dev, + "s_axi_lite_clk"); if (!lp->axi_clk) { /* For backward compatibility, if named AXI clock is not present, * treat the first clock specified as the AXI clock. */ - lp->axi_clk =3D devm_clk_get_optional(&pdev->dev, NULL); - } - if (IS_ERR(lp->axi_clk)) { - ret =3D PTR_ERR(lp->axi_clk); - goto free_netdev; - } - ret =3D clk_prepare_enable(lp->axi_clk); - if (ret) { - dev_err(&pdev->dev, "Unable to enable AXI clock: %d\n", ret); - goto free_netdev; + lp->axi_clk =3D devm_clk_get_optional_enabled(&pdev->dev, NULL); } + if (IS_ERR(lp->axi_clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(lp->axi_clk), + "could not get AXI clock\n"); =20 lp->misc_clks[0].id =3D "axis_clk"; lp->misc_clks[1].id =3D "ref_clk"; @@ -2818,18 +2818,23 @@ static int axienet_probe(struct platform_device *pd= ev) =20 ret =3D devm_clk_bulk_get_optional(&pdev->dev, XAE_NUM_MISC_CLOCKS, lp->m= isc_clks); if (ret) - goto cleanup_clk; + return dev_err_probe(&pdev->dev, ret, + "could not get misc. clocks\n"); =20 ret =3D clk_bulk_prepare_enable(XAE_NUM_MISC_CLOCKS, lp->misc_clks); if (ret) - goto cleanup_clk; + return dev_err_probe(&pdev->dev, ret, + "could not enable misc. clocks\n"); + + ret =3D devm_add_action_or_reset(&pdev->dev, axienet_disable_misc, + lp->misc_clks); + if (ret) + return ret; =20 /* Map device registers */ lp->regs =3D devm_platform_get_and_ioremap_resource(pdev, 0, ðres); - if (IS_ERR(lp->regs)) { - ret =3D PTR_ERR(lp->regs); - goto cleanup_clk; - } + if (IS_ERR(lp->regs)) + return PTR_ERR(lp->regs); lp->regs_start =3D ethres->start; =20 /* Setup checksum offload, but default to off if not specified */ @@ -2898,19 +2903,17 @@ static int axienet_probe(struct platform_device *pd= ev) lp->phy_mode =3D PHY_INTERFACE_MODE_1000BASEX; break; default: - ret =3D -EINVAL; - goto cleanup_clk; + return -EINVAL; } } else { ret =3D of_get_phy_mode(pdev->dev.of_node, &lp->phy_mode); if (ret) - goto cleanup_clk; + return ret; } if (lp->switch_x_sgmii && lp->phy_mode !=3D PHY_INTERFACE_MODE_SGMII && lp->phy_mode !=3D PHY_INTERFACE_MODE_1000BASEX) { dev_err(&pdev->dev, "xlnx,switch-x-sgmii only supported with SGMII or 10= 00BaseX\n"); - ret =3D -EINVAL; - goto cleanup_clk; + return -EINVAL; } =20 if (!of_property_present(pdev->dev.of_node, "dmas")) { @@ -2925,7 +2928,7 @@ static int axienet_probe(struct platform_device *pdev) dev_err(&pdev->dev, "unable to get DMA resource\n"); of_node_put(np); - goto cleanup_clk; + return ret; } lp->dma_regs =3D devm_ioremap_resource(&pdev->dev, &dmares); @@ -2942,19 +2945,17 @@ static int axienet_probe(struct platform_device *pd= ev) } if (IS_ERR(lp->dma_regs)) { dev_err(&pdev->dev, "could not map DMA regs\n"); - ret =3D PTR_ERR(lp->dma_regs); - goto cleanup_clk; + return PTR_ERR(lp->dma_regs); } if (lp->rx_irq <=3D 0 || lp->tx_irq <=3D 0) { dev_err(&pdev->dev, "could not determine irqs\n"); - ret =3D -ENOMEM; - goto cleanup_clk; + return -ENOMEM; } =20 /* Reset core now that clocks are enabled, prior to accessing MDIO */ ret =3D __axienet_device_reset(lp); if (ret) - goto cleanup_clk; + return ret; =20 /* Autodetect the need for 64-bit DMA pointers. * When the IP is configured for a bus width bigger than 32 bits, @@ -2981,14 +2982,13 @@ static int axienet_probe(struct platform_device *pd= ev) } if (!IS_ENABLED(CONFIG_64BIT) && lp->features & XAE_FEATURE_DMA_64BIT) { dev_err(&pdev->dev, "64-bit addressable DMA is not compatible with 32-b= it architecture\n"); - ret =3D -EINVAL; - goto cleanup_clk; + return -EINVAL; } =20 ret =3D dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(addr_width)); if (ret) { dev_err(&pdev->dev, "No suitable DMA available\n"); - goto cleanup_clk; + return ret; } netif_napi_add(ndev, &lp->napi_rx, axienet_rx_poll); netif_napi_add(ndev, &lp->napi_tx, axienet_tx_poll); @@ -2998,15 +2998,12 @@ static int axienet_probe(struct platform_device *pd= ev) =20 lp->eth_irq =3D platform_get_irq_optional(pdev, 0); if (lp->eth_irq < 0 && lp->eth_irq !=3D -ENXIO) { - ret =3D lp->eth_irq; - goto cleanup_clk; + return lp->eth_irq; } tx_chan =3D dma_request_chan(lp->dev, "tx_chan0"); - if (IS_ERR(tx_chan)) { - ret =3D PTR_ERR(tx_chan); - dev_err_probe(lp->dev, ret, "No Ethernet DMA (TX) channel found\n"); - goto cleanup_clk; - } + if (IS_ERR(tx_chan)) + return dev_err_probe(lp->dev, PTR_ERR(tx_chan), + "No Ethernet DMA (TX) channel found\n"); =20 cfg.reset =3D 1; /* As name says VDMA but it has support for DMA channel reset */ @@ -3014,7 +3011,7 @@ static int axienet_probe(struct platform_device *pdev) if (ret < 0) { dev_err(&pdev->dev, "Reset channel failed\n"); dma_release_channel(tx_chan); - goto cleanup_clk; + return ret; } =20 dma_release_channel(tx_chan); @@ -3119,13 +3116,6 @@ static int axienet_probe(struct platform_device *pde= v) put_device(&lp->pcs_phy->dev); if (lp->mii_bus) axienet_mdio_teardown(lp); -cleanup_clk: - clk_bulk_disable_unprepare(XAE_NUM_MISC_CLOCKS, lp->misc_clks); - clk_disable_unprepare(lp->axi_clk); - -free_netdev: - free_netdev(ndev); - return ret; } =20 @@ -3143,11 +3133,6 @@ static void axienet_remove(struct platform_device *p= dev) put_device(&lp->pcs_phy->dev); =20 axienet_mdio_teardown(lp); - - clk_bulk_disable_unprepare(XAE_NUM_MISC_CLOCKS, lp->misc_clks); - clk_disable_unprepare(lp->axi_clk); - - free_netdev(ndev); } =20 static void axienet_shutdown(struct platform_device *pdev) --=20 2.35.1.1320.gc452695387.dirty From nobody Sun Oct 5 23:40:19 2025 Received: from out-171.mta1.migadu.com (out-171.mta1.migadu.com [95.215.58.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5ABAC2356C0 for ; Mon, 28 Jul 2025 22:18:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753741121; cv=none; b=Fhp0UXbqlmCuu2WUFSsfrhEwBQpBYoyd8s8g8oyLHcCmvK1sCPYthWveQnks0klzdvsXPMZttMiTKETbWijbHUPVUoXghn8arO31OniXKCqSjJ2ikpAc3BWnLueWRtmUbmsl5sT/dJ19cs7yOxU1YUcRJnXos1PLMNwDxn9lEjY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753741121; c=relaxed/simple; bh=PSdCfwvuYNDkLsvpDTX/+fRr02wYzFlfT+kwaFn11do=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=CoPNzv/XcUUTSavSBVE6X71jx1LVCU7tjOx+hZWONaWN3oTdhi8yivKe1UTnnDwNtX/MkG+u1MJ8TA1dLeMBieJH+c7UVI8+P/dLyQmpdFOssRzaycPtGahWBHrMIbTZACgszDKdPy+JW5Al4hw4kKKcCbiryr5is3CIYVA0Fto= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=g98zP0yb; arc=none smtp.client-ip=95.215.58.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="g98zP0yb" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1753741115; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tOXG56ON/OYMfwTBNtCeAQzfV8BAU8WbBn8TalhqNho=; b=g98zP0ybmtfdWwaqcx7JLqCEF8I8SkTztnMareSSKNVq9gW7o6q9lV03SQjbMSqGvCdApf fzfHdcrdWVxqlJ9F6vzoYlki83XqxY/phWzzTQfUflCyWtN/haSb8zHFvne4s+DQ1tGkZO Lqo1X3VtExpVhi07p4W+WlDgIhBygjw= From: Sean Anderson To: Radhey Shyam Pandey , Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Greg Kroah-Hartman , Michal Simek , linux-arm-kernel@lists.infradead.org, Leon Romanovsky , Sean Anderson Subject: [PATCH net-next v3 2/7] net: axienet: Use ioread32/iowrite32 directly Date: Mon, 28 Jul 2025 18:18:18 -0400 Message-Id: <20250728221823.11968-3-sean.anderson@linux.dev> In-Reply-To: <20250728221823.11968-1-sean.anderson@linux.dev> References: <20250728221823.11968-1-sean.anderson@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" In preparation for splitting the MDIO bus into a separate driver, convert all register reads/writes to use ioread32/iowrite32 directly instead of using the axienet_ior/iow helpers. While we're at it, clean up the register calculations a bit. Signed-off-by: Sean Anderson --- Changes in v3: - New .../net/ethernet/xilinx/xilinx_axienet_mdio.c | 43 +++++++++---------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/ne= t/ethernet/xilinx/xilinx_axienet_mdio.c index 9ca2643c921e..16f3581390dd 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -32,7 +32,7 @@ static int axienet_mdio_wait_until_ready(struct axienet_l= ocal *lp) { u32 val; =20 - return readx_poll_timeout(axinet_ior_read_mcr, lp, + return readx_poll_timeout(ioread32, lp->regs + XAE_MDIO_MCR_OFFSET, val, val & XAE_MDIO_MCR_READY_MASK, 1, 20000); } @@ -45,8 +45,8 @@ static int axienet_mdio_wait_until_ready(struct axienet_l= ocal *lp) */ static void axienet_mdio_mdc_enable(struct axienet_local *lp) { - axienet_iow(lp, XAE_MDIO_MC_OFFSET, - ((u32)lp->mii_clk_div | XAE_MDIO_MC_MDIOEN_MASK)); + iowrite32((u32)lp->mii_clk_div | XAE_MDIO_MC_MDIOEN_MASK, + lp->regs + XAE_MDIO_MC_OFFSET); } =20 /** @@ -59,9 +59,9 @@ static void axienet_mdio_mdc_disable(struct axienet_local= *lp) { u32 mc_reg; =20 - mc_reg =3D axienet_ior(lp, XAE_MDIO_MC_OFFSET); - axienet_iow(lp, XAE_MDIO_MC_OFFSET, - (mc_reg & ~XAE_MDIO_MC_MDIOEN_MASK)); + mc_reg =3D ioread32(lp->regs + XAE_MDIO_MC_OFFSET); + iowrite32(mc_reg & ~XAE_MDIO_MC_MDIOEN_MASK, + lp->regs + XAE_MDIO_MC_OFFSET); } =20 /** @@ -90,13 +90,11 @@ static int axienet_mdio_read(struct mii_bus *bus, int p= hy_id, int reg) return ret; } =20 - axienet_iow(lp, XAE_MDIO_MCR_OFFSET, - (((phy_id << XAE_MDIO_MCR_PHYAD_SHIFT) & - XAE_MDIO_MCR_PHYAD_MASK) | - ((reg << XAE_MDIO_MCR_REGAD_SHIFT) & - XAE_MDIO_MCR_REGAD_MASK) | - XAE_MDIO_MCR_INITIATE_MASK | - XAE_MDIO_MCR_OP_READ_MASK)); + rc =3D FIELD_PREP(XAE_MDIO_MCR_PHYAD_MASK, phy_id) | + FIELD_PREP(XAE_MDIO_MCR_REGAD_MASK, reg) | + XAE_MDIO_MCR_INITIATE_MASK | + XAE_MDIO_MCR_OP_READ_MASK; + iowrite32(rc, lp->regs + XAE_MDIO_MCR_OFFSET); =20 ret =3D axienet_mdio_wait_until_ready(lp); if (ret < 0) { @@ -104,7 +102,7 @@ static int axienet_mdio_read(struct mii_bus *bus, int p= hy_id, int reg) return ret; } =20 - rc =3D axienet_ior(lp, XAE_MDIO_MRD_OFFSET) & 0x0000FFFF; + rc =3D ioread32(lp->regs + XAE_MDIO_MRD_OFFSET) & 0x0000FFFF; =20 dev_dbg(lp->dev, "axienet_mdio_read(phy_id=3D%i, reg=3D%x) =3D=3D %x\n", phy_id, reg, rc); @@ -129,8 +127,9 @@ static int axienet_mdio_read(struct mii_bus *bus, int p= hy_id, int reg) static int axienet_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 val) { - int ret; struct axienet_local *lp =3D bus->priv; + int ret; + u32 mcr; =20 dev_dbg(lp->dev, "axienet_mdio_write(phy_id=3D%i, reg=3D%x, val=3D%x)\n", phy_id, reg, val); @@ -143,14 +142,12 @@ static int axienet_mdio_write(struct mii_bus *bus, in= t phy_id, int reg, return ret; } =20 - axienet_iow(lp, XAE_MDIO_MWD_OFFSET, (u32)val); - axienet_iow(lp, XAE_MDIO_MCR_OFFSET, - (((phy_id << XAE_MDIO_MCR_PHYAD_SHIFT) & - XAE_MDIO_MCR_PHYAD_MASK) | - ((reg << XAE_MDIO_MCR_REGAD_SHIFT) & - XAE_MDIO_MCR_REGAD_MASK) | - XAE_MDIO_MCR_INITIATE_MASK | - XAE_MDIO_MCR_OP_WRITE_MASK)); + iowrite32(val, lp->regs + XAE_MDIO_MWD_OFFSET); + mcr =3D FIELD_PREP(XAE_MDIO_MCR_PHYAD_MASK, phy_id) | + FIELD_PREP(XAE_MDIO_MCR_REGAD_MASK, reg) | + XAE_MDIO_MCR_INITIATE_MASK | + XAE_MDIO_MCR_OP_WRITE_MASK; + iowrite32(mcr, lp->regs + XAE_MDIO_MCR_OFFSET); =20 ret =3D axienet_mdio_wait_until_ready(lp); if (ret < 0) { --=20 2.35.1.1320.gc452695387.dirty From nobody Sun Oct 5 23:40:19 2025 Received: from out-174.mta1.migadu.com (out-174.mta1.migadu.com [95.215.58.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3C8402367B7 for ; Mon, 28 Jul 2025 22:18:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753741122; cv=none; b=C/f7GQCoVOPwwoij/+S6puwAcxWKwHEKSDmBR+oB44rmS+o2TorvXuz1y0+pFJWPCUkdX1A7+EYWkAviYBAnKsRAeL6bRxmVzObQLLJqUO+8YEgWz0wjBxFfLm+l4OZSxL6ari0V0nLPVlR9urkOq4zVZZ+D+3tpRlLwNaTB8Fw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753741122; c=relaxed/simple; bh=uVC16RdMBF1d1tYhBbIPtfkNn1gMbamjFske7+8KHqw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=FAE0ZUJWnmqJD9/aK6MdkzJfGg2NjgYR3nPGcE1wnU0kLg3bynccIVMi+Wc1s/SoaF5TRyw0Iuv+Eron3iCY8I40HFkCnW6BfBpp9JDVLm7Ts/OQk2cn9sqgi6452LsjWfhU6VwsEHYE8B7NUvkyp/S0H0Zko91dW0KgXeo15Ws= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=gtgtrZGQ; arc=none smtp.client-ip=95.215.58.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="gtgtrZGQ" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1753741117; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=N4ypV3tQbWdlibJNYX1clwuOwlvFN4BhFLLDGnhlf6o=; b=gtgtrZGQ/U1EmzXqAkhmEymzW7RZNBvppn61y0FwIzzgqLlzy0oxkYZZ8E/TnbbgKjlVxz MXX3kdfoEGxk/8hQc7Tg23/arS3VSr8ni7dwf1cJTrl2uG2jclzKgLXb0KXpDBmeEX32j7 K0YA2VVbbvEjWhYbeZHyqKyO4E4hupw= From: Sean Anderson To: Radhey Shyam Pandey , Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Greg Kroah-Hartman , Michal Simek , linux-arm-kernel@lists.infradead.org, Leon Romanovsky , Sean Anderson Subject: [PATCH net-next v3 3/7] net: axienet: Use MDIO bus device in prints Date: Mon, 28 Jul 2025 18:18:19 -0400 Message-Id: <20250728221823.11968-4-sean.anderson@linux.dev> In-Reply-To: <20250728221823.11968-1-sean.anderson@linux.dev> References: <20250728221823.11968-1-sean.anderson@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" For clarity and to remove the dependency on the parent netdev, use the MDIO bus device in print statements. Signed-off-by: Sean Anderson --- Changes in v3: - New .../net/ethernet/xilinx/xilinx_axienet_mdio.c | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/ne= t/ethernet/xilinx/xilinx_axienet_mdio.c index 16f3581390dd..cacd5590731d 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -104,7 +104,7 @@ static int axienet_mdio_read(struct mii_bus *bus, int p= hy_id, int reg) =20 rc =3D ioread32(lp->regs + XAE_MDIO_MRD_OFFSET) & 0x0000FFFF; =20 - dev_dbg(lp->dev, "axienet_mdio_read(phy_id=3D%i, reg=3D%x) =3D=3D %x\n", + dev_dbg(&bus->dev, "%s(phy_id=3D%i, reg=3D%x) =3D=3D %x\n", __func__, phy_id, reg, rc); =20 axienet_mdio_mdc_disable(lp); @@ -131,7 +131,7 @@ static int axienet_mdio_write(struct mii_bus *bus, int = phy_id, int reg, int ret; u32 mcr; =20 - dev_dbg(lp->dev, "axienet_mdio_write(phy_id=3D%i, reg=3D%x, val=3D%x)\n", + dev_dbg(&bus->dev, "%s(phy_id=3D%i, reg=3D%x, val=3D%x)\n", __func__, phy_id, reg, val); =20 axienet_mdio_mdc_enable(lp); @@ -169,8 +169,9 @@ static int axienet_mdio_write(struct mii_bus *bus, int = phy_id, int reg, * Sets up the MDIO interface by initializing the MDIO clock and enabling = the * MDIO interface in hardware. **/ -static int axienet_mdio_enable(struct axienet_local *lp, struct device_nod= e *np) +static int axienet_mdio_enable(struct mii_bus *bus, struct device_node *np) { + struct axienet_local *lp =3D bus->priv; u32 mdio_freq =3D DEFAULT_MDIO_FREQ; u32 host_clock; u32 clk_div; @@ -186,28 +187,31 @@ static int axienet_mdio_enable(struct axienet_local *= lp, struct device_node *np) /* Legacy fallback: detect CPU clock frequency and use as AXI * bus clock frequency. This only works on certain platforms. */ - np1 =3D of_find_node_by_name(NULL, "cpu"); + np1 =3D of_find_node_by_name(NULL, "lpu"); if (!np1) { - netdev_warn(lp->ndev, "Could not find CPU device node.\n"); + dev_warn(&bus->dev, + "Could not find CPU device node.\n"); host_clock =3D DEFAULT_HOST_CLOCK; } else { int ret =3D of_property_read_u32(np1, "clock-frequency", &host_clock); if (ret) { - netdev_warn(lp->ndev, "CPU clock-frequency property not found.\n"); + dev_warn(&bus->dev, + "CPU clock-frequency property not found.\n"); host_clock =3D DEFAULT_HOST_CLOCK; } of_node_put(np1); } - netdev_info(lp->ndev, "Setting assumed host clock to %u\n", - host_clock); + dev_info(&bus->dev, + "Setting assumed host clock to %u\n", host_clock); } =20 if (np) of_property_read_u32(np, "clock-frequency", &mdio_freq); if (mdio_freq !=3D DEFAULT_MDIO_FREQ) - netdev_info(lp->ndev, "Setting non-standard mdio bus frequency to %u Hz\= n", - mdio_freq); + dev_info(&bus->dev, + "Setting non-standard mdio bus frequency to %u Hz\n", + mdio_freq); =20 /* clk_div can be calculated by deriving it from the equation: * fMDIO =3D fHOST / ((1 + clk_div) * 2) @@ -245,14 +249,14 @@ static int axienet_mdio_enable(struct axienet_local *= lp, struct device_node *np) =20 /* Check for overflow of mii_clk_div */ if (clk_div & ~XAE_MDIO_MC_CLOCK_DIVIDE_MAX) { - netdev_warn(lp->ndev, "MDIO clock divisor overflow\n"); + dev_warn(&bus->dev, "MDIO clock divisor overflow\n"); return -EOVERFLOW; } lp->mii_clk_div =3D (u8)clk_div; =20 - netdev_dbg(lp->ndev, - "Setting MDIO clock divisor to %u/%u Hz host clock.\n", - lp->mii_clk_div, host_clock); + dev_dbg(&bus->dev, + "Setting MDIO clock divisor to %u/%u Hz host clock.\n", + lp->mii_clk_div, host_clock); =20 axienet_mdio_mdc_enable(lp); =20 @@ -295,7 +299,7 @@ int axienet_mdio_setup(struct axienet_local *lp) lp->mii_bus =3D bus; =20 mdio_node =3D of_get_child_by_name(lp->dev->of_node, "mdio"); - ret =3D axienet_mdio_enable(lp, mdio_node); + ret =3D axienet_mdio_enable(bus, mdio_node); if (ret < 0) goto unregister; ret =3D of_mdiobus_register(bus, mdio_node); --=20 2.35.1.1320.gc452695387.dirty From nobody Sun Oct 5 23:40:19 2025 Received: from out-173.mta1.migadu.com (out-173.mta1.migadu.com [95.215.58.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0428E236A88 for ; Mon, 28 Jul 2025 22:18:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753741122; cv=none; b=Bnuo/hrYMEniujOQNRJI87f+8nZfP+3GLTUSuU8/LQRPj3GKt/PaATiRRGYZeNEMvu0SZP3Zqg9nBbDGyivjn1aA5zHhA5z2H6XEw2S2FxUGlaUtSYacU0IU5TUsed69to5A6dcKFqz4g4yMJCYl95u8XyT5S4IohVyywJo1CvA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753741122; c=relaxed/simple; bh=55XA8P1iUeREP32fWmuyomheQ5mp0ReLFQKKdLev96g=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ml7wB4EP1hsCBsOa2TXdKcq17f9+1pPi0kPFk3EY/u+T9N69DqXqbBUaabTgQjwH8jhBdXc0+Ifni2VhbPhJfdwjE8DdkbjaMCI7XHXdj+j846WNdjmBKG17bYnFDnPA8/7kN1M0e37/u6JEIqHS3Jxc3haXtCN+0kGXxnsuw78= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=JVGSeMEo; arc=none smtp.client-ip=95.215.58.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="JVGSeMEo" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1753741119; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/Di1cyw3vFeHymmCdFM7oOslo1PcW+F7Rf0w8IzgGW8=; b=JVGSeMEoXYCLwM/PnBAUMf4YVK5EEjqIUhOBiZuCM3Bcf24r39TLSDmI5zMR54RsALG0ZX iOneZpgb/8VWYVXnHlFYF3iGjCuwVKtrNWEOxcS/sMZtz6Eec4ds7Id6B2yyc4TN3n1ExL dz429R5R/NSAifUUikaf48uvFulpmok= From: Sean Anderson To: Radhey Shyam Pandey , Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Greg Kroah-Hartman , Michal Simek , linux-arm-kernel@lists.infradead.org, Leon Romanovsky , Sean Anderson Subject: [PATCH net-next v3 4/7] net: axienet: Simplify axienet_mdio_setup Date: Mon, 28 Jul 2025 18:18:20 -0400 Message-Id: <20250728221823.11968-5-sean.anderson@linux.dev> In-Reply-To: <20250728221823.11968-1-sean.anderson@linux.dev> References: <20250728221823.11968-1-sean.anderson@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" We always put the mdio_node and disable the bus after probing, so perform these steps unconditionally. Signed-off-by: Sean Anderson --- (no changes since v1) drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/ne= t/ethernet/xilinx/xilinx_axienet_mdio.c index cacd5590731d..2799d168ed9d 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -302,19 +302,14 @@ int axienet_mdio_setup(struct axienet_local *lp) ret =3D axienet_mdio_enable(bus, mdio_node); if (ret < 0) goto unregister; + ret =3D of_mdiobus_register(bus, mdio_node); - if (ret) - goto unregister_mdio_enabled; of_node_put(mdio_node); axienet_mdio_mdc_disable(lp); - return 0; - -unregister_mdio_enabled: - axienet_mdio_mdc_disable(lp); -unregister: - of_node_put(mdio_node); - mdiobus_free(bus); - lp->mii_bus =3D NULL; + if (ret) { + mdiobus_free(bus); + lp->mii_bus =3D NULL; + } return ret; } =20 --=20 2.35.1.1320.gc452695387.dirty From nobody Sun Oct 5 23:40:19 2025 Received: from out-188.mta1.migadu.com (out-188.mta1.migadu.com [95.215.58.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5760523A9B0 for ; Mon, 28 Jul 2025 22:18:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.188 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753741125; cv=none; b=TWWxfS4MniO9DcspRgZnZJHSq+j2i+F21ADtvC5MKyvYW3as0PnDBVQlxtqcqg0eNUqFB4AbICkb0K2z8KTA58m5az4MTcxJ0+JT3sKLjHVeNLibnTMQCe7F0XU1rSAlI/e23fhZMbVUBZlw7+X+/ivHUPmSc9s9Io7/sGf9Z6c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753741125; c=relaxed/simple; bh=GfSA2XX8U5H/FDguHjRe+AA9pdRSkOx7ESbL9bMyK2I=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WKK+TnxGt+atv/HY+TC2KNCBmMYD0Cuak0qfrHww4nB5T+KX5Lw8JHbrIdKKbM1yICdfZNcfb0ud53CSV2uxgcb4arEf0Xrn3EJsiac4GFyw9hv/9wM0pPsOQRwDdjLET3x9Vz7XhAn2aI0fJ7cnVjDHmntm5/4siGQIwWZC7tw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=fLJsW90+; arc=none smtp.client-ip=95.215.58.188 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="fLJsW90+" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1753741121; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=POWcbrzxD1nx0V6VO4ze6P6md5CtQ52lbSHa2nlLUDw=; b=fLJsW90+cfYAXMqmbSOg2v1XBclO1mzeuvH+MbglyoSVv5bc0aSLPAugoCKLQy7jTUdSXh iDIMH5ae+vD/z9kBfeEpxEVjAPXOj6g8obsa5EUjM2N37v5972PAIOtUnsO1MIsy4VurN4 QSxsqa9WlkV2KSel3rCqG7V+O7j+ztM= From: Sean Anderson To: Radhey Shyam Pandey , Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Greg Kroah-Hartman , Michal Simek , linux-arm-kernel@lists.infradead.org, Leon Romanovsky , Sean Anderson Subject: [PATCH net-next v3 5/7] net: axienet: Use device variable in probe Date: Mon, 28 Jul 2025 18:18:21 -0400 Message-Id: <20250728221823.11968-6-sean.anderson@linux.dev> In-Reply-To: <20250728221823.11968-1-sean.anderson@linux.dev> References: <20250728221823.11968-1-sean.anderson@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" There are a lot of references to pdev->dev that we can shorten by using a dev variable. Signed-off-by: Sean Anderson --- Changes in v3: - New .../net/ethernet/xilinx/xilinx_axienet_main.c | 83 +++++++++---------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/ne= t/ethernet/xilinx/xilinx_axienet_main.c index 1f277e5e4a62..28927c7c6c41 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -2764,6 +2764,7 @@ static void axienet_disable_misc(void *clocks) static int axienet_probe(struct platform_device *pdev) { int ret; + struct device *dev =3D &pdev->dev; struct device_node *np; struct axienet_local *lp; struct net_device *ndev; @@ -2772,13 +2773,13 @@ static int axienet_probe(struct platform_device *pd= ev) int addr_width =3D 32; u32 value; =20 - ndev =3D devm_alloc_etherdev(&pdev->dev, sizeof(*lp)); + ndev =3D devm_alloc_etherdev(dev, sizeof(*lp)); if (!ndev) return -ENOMEM; =20 platform_set_drvdata(pdev, ndev); =20 - SET_NETDEV_DEV(ndev, &pdev->dev); + SET_NETDEV_DEV(ndev, dev); ndev->features =3D NETIF_F_SG; ndev->ethtool_ops =3D &axienet_ethtool_ops; =20 @@ -2788,7 +2789,7 @@ static int axienet_probe(struct platform_device *pdev) =20 lp =3D netdev_priv(ndev); lp->ndev =3D ndev; - lp->dev =3D &pdev->dev; + lp->dev =3D dev; lp->options =3D XAE_OPTION_DEFAULTS; lp->rx_bd_num =3D RX_BD_NUM_DEFAULT; lp->tx_bd_num =3D TX_BD_NUM_DEFAULT; @@ -2800,33 +2801,32 @@ static int axienet_probe(struct platform_device *pd= ev) seqcount_mutex_init(&lp->hw_stats_seqcount, &lp->stats_lock); INIT_DEFERRABLE_WORK(&lp->stats_work, axienet_refresh_stats); =20 - lp->axi_clk =3D devm_clk_get_optional_enabled(&pdev->dev, - "s_axi_lite_clk"); + lp->axi_clk =3D devm_clk_get_optional_enabled(dev, "s_axi_lite_clk"); if (!lp->axi_clk) { /* For backward compatibility, if named AXI clock is not present, * treat the first clock specified as the AXI clock. */ - lp->axi_clk =3D devm_clk_get_optional_enabled(&pdev->dev, NULL); + lp->axi_clk =3D devm_clk_get_optional_enabled(dev, NULL); } if (IS_ERR(lp->axi_clk)) - return dev_err_probe(&pdev->dev, PTR_ERR(lp->axi_clk), + return dev_err_probe(dev, PTR_ERR(lp->axi_clk), "could not get AXI clock\n"); =20 lp->misc_clks[0].id =3D "axis_clk"; lp->misc_clks[1].id =3D "ref_clk"; lp->misc_clks[2].id =3D "mgt_clk"; =20 - ret =3D devm_clk_bulk_get_optional(&pdev->dev, XAE_NUM_MISC_CLOCKS, lp->m= isc_clks); + ret =3D devm_clk_bulk_get_optional(dev, XAE_NUM_MISC_CLOCKS, lp->misc_clk= s); if (ret) - return dev_err_probe(&pdev->dev, ret, + return dev_err_probe(dev, ret, "could not get misc. clocks\n"); =20 ret =3D clk_bulk_prepare_enable(XAE_NUM_MISC_CLOCKS, lp->misc_clks); if (ret) - return dev_err_probe(&pdev->dev, ret, + return dev_err_probe(dev, ret, "could not enable misc. clocks\n"); =20 - ret =3D devm_add_action_or_reset(&pdev->dev, axienet_disable_misc, + ret =3D devm_add_action_or_reset(dev, axienet_disable_misc, lp->misc_clks); if (ret) return ret; @@ -2843,7 +2843,7 @@ static int axienet_probe(struct platform_device *pdev) if (axienet_ior(lp, XAE_ABILITY_OFFSET) & XAE_ABILITY_STATS) lp->features |=3D XAE_FEATURE_STATS; =20 - ret =3D of_property_read_u32(pdev->dev.of_node, "xlnx,txcsum", &value); + ret =3D of_property_read_u32(dev->of_node, "xlnx,txcsum", &value); if (!ret) { switch (value) { case 1: @@ -2858,7 +2858,7 @@ static int axienet_probe(struct platform_device *pdev) break; } } - ret =3D of_property_read_u32(pdev->dev.of_node, "xlnx,rxcsum", &value); + ret =3D of_property_read_u32(dev->of_node, "xlnx,rxcsum", &value); if (!ret) { switch (value) { case 1: @@ -2877,13 +2877,13 @@ static int axienet_probe(struct platform_device *pd= ev) * Here we check for memory allocated for Rx/Tx in the hardware from * the device-tree and accordingly set flags. */ - of_property_read_u32(pdev->dev.of_node, "xlnx,rxmem", &lp->rxmem); + of_property_read_u32(dev->of_node, "xlnx,rxmem", &lp->rxmem); =20 - lp->switch_x_sgmii =3D of_property_read_bool(pdev->dev.of_node, + lp->switch_x_sgmii =3D of_property_read_bool(dev->of_node, "xlnx,switch-x-sgmii"); =20 /* Start with the proprietary, and broken phy_type */ - ret =3D of_property_read_u32(pdev->dev.of_node, "xlnx,phy-type", &value); + ret =3D of_property_read_u32(dev->of_node, "xlnx,phy-type", &value); if (!ret) { netdev_warn(ndev, "Please upgrade your device tree binary blob to use ph= y-mode"); switch (value) { @@ -2906,32 +2906,31 @@ static int axienet_probe(struct platform_device *pd= ev) return -EINVAL; } } else { - ret =3D of_get_phy_mode(pdev->dev.of_node, &lp->phy_mode); + ret =3D of_get_phy_mode(dev->of_node, &lp->phy_mode); if (ret) return ret; } if (lp->switch_x_sgmii && lp->phy_mode !=3D PHY_INTERFACE_MODE_SGMII && lp->phy_mode !=3D PHY_INTERFACE_MODE_1000BASEX) { - dev_err(&pdev->dev, "xlnx,switch-x-sgmii only supported with SGMII or 10= 00BaseX\n"); + dev_err(dev, "xlnx,switch-x-sgmii only supported with SGMII or 1000BaseX= \n"); return -EINVAL; } =20 - if (!of_property_present(pdev->dev.of_node, "dmas")) { + if (!of_property_present(dev->of_node, "dmas")) { /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ - np =3D of_parse_phandle(pdev->dev.of_node, "axistream-connected", 0); + np =3D of_parse_phandle(dev->of_node, "axistream-connected", 0); =20 if (np) { struct resource dmares; =20 ret =3D of_address_to_resource(np, 0, &dmares); if (ret) { - dev_err(&pdev->dev, + dev_err(dev, "unable to get DMA resource\n"); of_node_put(np); return ret; } - lp->dma_regs =3D devm_ioremap_resource(&pdev->dev, - &dmares); + lp->dma_regs =3D devm_ioremap_resource(dev, &dmares); lp->rx_irq =3D irq_of_parse_and_map(np, 1); lp->tx_irq =3D irq_of_parse_and_map(np, 0); of_node_put(np); @@ -2944,11 +2943,11 @@ static int axienet_probe(struct platform_device *pd= ev) lp->eth_irq =3D platform_get_irq_optional(pdev, 2); } if (IS_ERR(lp->dma_regs)) { - dev_err(&pdev->dev, "could not map DMA regs\n"); + dev_err(dev, "could not map DMA regs\n"); return PTR_ERR(lp->dma_regs); } if (lp->rx_irq <=3D 0 || lp->tx_irq <=3D 0) { - dev_err(&pdev->dev, "could not determine irqs\n"); + dev_err(dev, "could not determine irqs\n"); return -ENOMEM; } =20 @@ -2974,20 +2973,20 @@ static int axienet_probe(struct platform_device *pd= ev) if (ioread32(desc) > 0) { lp->features |=3D XAE_FEATURE_DMA_64BIT; addr_width =3D 64; - dev_info(&pdev->dev, + dev_info(dev, "autodetected 64-bit DMA range\n"); } iowrite32(0x0, desc); } } if (!IS_ENABLED(CONFIG_64BIT) && lp->features & XAE_FEATURE_DMA_64BIT) { - dev_err(&pdev->dev, "64-bit addressable DMA is not compatible with 32-b= it architecture\n"); + dev_err(dev, "64-bit addressable DMA is not compatible with 32-bit arch= itecture\n"); return -EINVAL; } =20 - ret =3D dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(addr_width)); + ret =3D dma_set_mask_and_coherent(dev, DMA_BIT_MASK(addr_width)); if (ret) { - dev_err(&pdev->dev, "No suitable DMA available\n"); + dev_err(dev, "No suitable DMA available\n"); return ret; } netif_napi_add(ndev, &lp->napi_rx, axienet_rx_poll); @@ -3000,16 +2999,16 @@ static int axienet_probe(struct platform_device *pd= ev) if (lp->eth_irq < 0 && lp->eth_irq !=3D -ENXIO) { return lp->eth_irq; } - tx_chan =3D dma_request_chan(lp->dev, "tx_chan0"); + tx_chan =3D dma_request_chan(dev, "tx_chan0"); if (IS_ERR(tx_chan)) - return dev_err_probe(lp->dev, PTR_ERR(tx_chan), + return dev_err_probe(dev, PTR_ERR(tx_chan), "No Ethernet DMA (TX) channel found\n"); =20 cfg.reset =3D 1; /* As name says VDMA but it has support for DMA channel reset */ ret =3D xilinx_vdma_channel_set_config(tx_chan, &cfg); if (ret < 0) { - dev_err(&pdev->dev, "Reset channel failed\n"); + dev_err(dev, "Reset channel failed\n"); dma_release_channel(tx_chan); return ret; } @@ -3024,14 +3023,14 @@ static int axienet_probe(struct platform_device *pd= ev) ndev->netdev_ops =3D &axienet_netdev_ops; /* Check for Ethernet core IRQ (optional) */ if (lp->eth_irq <=3D 0) - dev_info(&pdev->dev, "Ethernet core IRQ not defined\n"); + dev_info(dev, "Ethernet core IRQ not defined\n"); =20 /* Retrieve the MAC address */ - ret =3D of_get_mac_address(pdev->dev.of_node, mac_addr); + ret =3D of_get_mac_address(dev->of_node, mac_addr); if (!ret) { axienet_set_mac_address(ndev, mac_addr); } else { - dev_warn(&pdev->dev, "could not find MAC address property: %d\n", + dev_warn(dev, "could not find MAC address property: %d\n", ret); axienet_set_mac_address(ndev, NULL); } @@ -3048,21 +3047,21 @@ static int axienet_probe(struct platform_device *pd= ev) =20 ret =3D axienet_mdio_setup(lp); if (ret) - dev_warn(&pdev->dev, + dev_warn(dev, "error registering MDIO bus: %d\n", ret); =20 if (lp->phy_mode =3D=3D PHY_INTERFACE_MODE_SGMII || lp->phy_mode =3D=3D PHY_INTERFACE_MODE_1000BASEX) { - np =3D of_parse_phandle(pdev->dev.of_node, "pcs-handle", 0); + np =3D of_parse_phandle(dev->of_node, "pcs-handle", 0); if (!np) { /* Deprecated: Always use "pcs-handle" for pcs_phy. * Falling back to "phy-handle" here is only for * backward compatibility with old device trees. */ - np =3D of_parse_phandle(pdev->dev.of_node, "phy-handle", 0); + np =3D of_parse_phandle(dev->of_node, "phy-handle", 0); } if (!np) { - dev_err(&pdev->dev, "pcs-handle (preferred) or phy-handle required for = 1000BaseX/SGMII\n"); + dev_err(dev, "pcs-handle (preferred) or phy-handle required for 1000Bas= eX/SGMII\n"); ret =3D -EINVAL; goto cleanup_mdio; } @@ -3091,18 +3090,18 @@ static int axienet_probe(struct platform_device *pd= ev) lp->phylink_config.supported_interfaces); } =20 - lp->phylink =3D phylink_create(&lp->phylink_config, pdev->dev.fwnode, + lp->phylink =3D phylink_create(&lp->phylink_config, dev->fwnode, lp->phy_mode, &axienet_phylink_ops); if (IS_ERR(lp->phylink)) { ret =3D PTR_ERR(lp->phylink); - dev_err(&pdev->dev, "phylink_create error (%i)\n", ret); + dev_err(dev, "phylink_create error (%i)\n", ret); goto cleanup_mdio; } =20 ret =3D register_netdev(lp->ndev); if (ret) { - dev_err(lp->dev, "register_netdev() error (%i)\n", ret); + dev_err(dev, "register_netdev() error (%i)\n", ret); goto cleanup_phylink; } =20 --=20 2.35.1.1320.gc452695387.dirty From nobody Sun Oct 5 23:40:19 2025 Received: from out-187.mta1.migadu.com (out-187.mta1.migadu.com [95.215.58.187]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7BC79229B15 for ; Mon, 28 Jul 2025 22:18:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.187 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753741127; cv=none; b=J2cSaJtRavIWMACLa/GTNxA/sV6OWxhHBZ5IGIUS9QYJD+Uy/wt0ibRm2qsON+dK/IPX2cmcBEsc2HUMBvu7g/swB8p74iV1sPSGc7gTKlj7/6/54FLCV5H8DsY1E6NuDmouK95E4ybAcQpLPQu/0TRX0+XmJRe+G5ookUWNQg8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753741127; c=relaxed/simple; bh=VgjIJAfhat9oaagbpBOV76xwh+ZSWiXaWBxfJNOZKpo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Pdo9iVaRZQU4yXgnX+wkwvBuT81cG9U/jb4UwCqK0JxaW0GnUWhz05SvlJydtal5l8Seyleg1AOuDEL8v/lFdcLWXP9I4X02B713R48GtaUaofs6l1heHxQcOV8R+GjcXx8Hr+L7QdiJ9wIrT/Oe/CAc58rynjP86nV4q2cMFeo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=rS1cwFPC; arc=none smtp.client-ip=95.215.58.187 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="rS1cwFPC" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1753741123; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=b5qR6sSpW8TJQpTI7gicjIvT2YeTf7KcnOssCWqRgzc=; b=rS1cwFPCwK+hGLT6FTjEtZetJWEzqFED5y8zHUQfmF8VNlFZqpUFkeaj5dsJQI71zRZuYZ Xi7z9Zu1lCJ5ILH1lN3sNZbMf0gsdupqvpZ72lUW7c2ZaxrtvLMZE4iQpB4Tn7OANwQCWh AI9G+epkQHzlkaifhwBu0FTCjiIaXM4= From: Sean Anderson To: Radhey Shyam Pandey , Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Greg Kroah-Hartman , Michal Simek , linux-arm-kernel@lists.infradead.org, Leon Romanovsky , Sean Anderson Subject: [PATCH net-next v3 6/7] net: axienet: Rearrange lifetime functions Date: Mon, 28 Jul 2025 18:18:22 -0400 Message-Id: <20250728221823.11968-7-sean.anderson@linux.dev> In-Reply-To: <20250728221823.11968-1-sean.anderson@linux.dev> References: <20250728221823.11968-1-sean.anderson@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Rearrange the lifetime functions (probe, remove, etc.) in preparation for the next commit. No functional change intended. Signed-off-by: Sean Anderson --- Changes in v3: - Rework to use a separate axienet_common structure drivers/net/ethernet/xilinx/xilinx_axienet.h | 41 ++++-- .../net/ethernet/xilinx/xilinx_axienet_main.c | 135 ++++++++++-------- .../net/ethernet/xilinx/xilinx_axienet_mdio.c | 45 +++--- 3 files changed, 127 insertions(+), 94 deletions(-) diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/eth= ernet/xilinx/xilinx_axienet.h index 5ff742103beb..d7215dd92ce9 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet.h +++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h @@ -467,6 +467,29 @@ struct skbuf_dma_descriptor { int sg_len; }; =20 +/** + * struct axienet_common - axienet private common data + * @pdev: Pointer to common platform device structure + * @axi_clk: AXI4-Lite bus clock + * @reset_lock: Lock held while resetting the device to prevent register a= ccess + * @mii_bus: Pointer to MII bus structure + * @mii_clk_div: MII bus clock divider value + * @regs_start: Resource start for axienet device addresses + * @regs: Base address for the axienet_local device address space + */ +struct axienet_common { + struct platform_device *pdev; + + struct clk *axi_clk; + + struct mutex reset_lock; + struct mii_bus *mii_bus; + u8 mii_clk_div; + + void __iomem *regs; + resource_size_t regs_start; +}; + /** * struct axienet_local - axienet private per device data * @ndev: Pointer for net_device to which it will be attached. @@ -549,6 +572,7 @@ struct skbuf_dma_descriptor { struct axienet_local { struct net_device *ndev; struct device *dev; + struct axienet_common *cp; =20 struct phylink *phylink; struct phylink_config phylink_config; @@ -558,13 +582,11 @@ struct axienet_local { =20 bool switch_x_sgmii; =20 - struct clk *axi_clk; struct clk_bulk_data misc_clks[XAE_NUM_MISC_CLOCKS]; =20 struct mii_bus *mii_bus; u8 mii_clk_div; =20 - resource_size_t regs_start; void __iomem *regs; void __iomem *dma_regs; =20 @@ -654,21 +676,14 @@ static inline u32 axienet_ior(struct axienet_local *l= p, off_t offset) return ioread32(lp->regs + offset); } =20 -static inline u32 axinet_ior_read_mcr(struct axienet_local *lp) -{ - return axienet_ior(lp, XAE_MDIO_MCR_OFFSET); -} - static inline void axienet_lock_mii(struct axienet_local *lp) { - if (lp->mii_bus) - mutex_lock(&lp->mii_bus->mdio_lock); + mutex_lock(&lp->cp->reset_lock); } =20 static inline void axienet_unlock_mii(struct axienet_local *lp) { - if (lp->mii_bus) - mutex_unlock(&lp->mii_bus->mdio_lock); + mutex_unlock(&lp->cp->reset_lock); } =20 /** @@ -738,7 +753,7 @@ static inline void axienet_dma_out_addr(struct axienet_= local *lp, off_t reg, #endif /* CONFIG_64BIT */ =20 /* Function prototypes visible in xilinx_axienet_mdio.c for other files */ -int axienet_mdio_setup(struct axienet_local *lp); -void axienet_mdio_teardown(struct axienet_local *lp); +int axienet_mdio_setup(struct axienet_common *lp); +void axienet_mdio_teardown(struct axienet_common *lp); =20 #endif /* XILINX_AXI_ENET_H */ diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/ne= t/ethernet/xilinx/xilinx_axienet_main.c index 28927c7c6c41..f235ef15187c 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -225,8 +225,8 @@ static void axienet_dma_bd_release(struct net_device *n= dev) =20 static u64 axienet_dma_rate(struct axienet_local *lp) { - if (lp->axi_clk) - return clk_get_rate(lp->axi_clk); + if (lp->cp->axi_clk) + return clk_get_rate(lp->cp->axi_clk); return 125000000; /* arbitrary guess if no clock rate set */ } =20 @@ -2749,29 +2749,17 @@ static void axienet_disable_misc(void *clocks) clk_bulk_disable_unprepare(XAE_NUM_MISC_CLOCKS, clocks); } =20 -/** - * axienet_probe - Axi Ethernet probe function. - * @pdev: Pointer to platform device structure. - * - * Return: 0, on success - * Non-zero error value on failure. - * - * This is the probe routine for Axi Ethernet driver. This is called before - * any other driver routines are invoked. It allocates and sets up the Eth= ernet - * device. Parses through device tree and populates fields of - * axienet_local. It registers the Ethernet device. - */ -static int axienet_probe(struct platform_device *pdev) +static int axienet_mac_probe(struct axienet_common *cp) { - int ret; + struct platform_device *pdev =3D cp->pdev; struct device *dev =3D &pdev->dev; - struct device_node *np; struct axienet_local *lp; struct net_device *ndev; - struct resource *ethres; + struct device_node *np; u8 mac_addr[ETH_ALEN]; int addr_width =3D 32; u32 value; + int ret; =20 ndev =3D devm_alloc_etherdev(dev, sizeof(*lp)); if (!ndev) @@ -2790,6 +2778,8 @@ static int axienet_probe(struct platform_device *pdev) lp =3D netdev_priv(ndev); lp->ndev =3D ndev; lp->dev =3D dev; + lp->cp =3D cp; + lp->regs =3D cp->regs; lp->options =3D XAE_OPTION_DEFAULTS; lp->rx_bd_num =3D RX_BD_NUM_DEFAULT; lp->tx_bd_num =3D TX_BD_NUM_DEFAULT; @@ -2801,17 +2791,6 @@ static int axienet_probe(struct platform_device *pde= v) seqcount_mutex_init(&lp->hw_stats_seqcount, &lp->stats_lock); INIT_DEFERRABLE_WORK(&lp->stats_work, axienet_refresh_stats); =20 - lp->axi_clk =3D devm_clk_get_optional_enabled(dev, "s_axi_lite_clk"); - if (!lp->axi_clk) { - /* For backward compatibility, if named AXI clock is not present, - * treat the first clock specified as the AXI clock. - */ - lp->axi_clk =3D devm_clk_get_optional_enabled(dev, NULL); - } - if (IS_ERR(lp->axi_clk)) - return dev_err_probe(dev, PTR_ERR(lp->axi_clk), - "could not get AXI clock\n"); - lp->misc_clks[0].id =3D "axis_clk"; lp->misc_clks[1].id =3D "ref_clk"; lp->misc_clks[2].id =3D "mgt_clk"; @@ -2831,12 +2810,6 @@ static int axienet_probe(struct platform_device *pde= v) if (ret) return ret; =20 - /* Map device registers */ - lp->regs =3D devm_platform_get_and_ioremap_resource(pdev, 0, ðres); - if (IS_ERR(lp->regs)) - return PTR_ERR(lp->regs); - lp->regs_start =3D ethres->start; - /* Setup checksum offload, but default to off if not specified */ lp->features =3D 0; =20 @@ -3045,11 +3018,6 @@ static int axienet_probe(struct platform_device *pde= v) lp->tx_dma_cr =3D axienet_calc_cr(lp, XAXIDMA_DFT_TX_THRESHOLD, XAXIDMA_DFT_TX_USEC); =20 - ret =3D axienet_mdio_setup(lp); - if (ret) - dev_warn(dev, - "error registering MDIO bus: %d\n", ret); - if (lp->phy_mode =3D=3D PHY_INTERFACE_MODE_SGMII || lp->phy_mode =3D=3D PHY_INTERFACE_MODE_1000BASEX) { np =3D of_parse_phandle(dev->of_node, "pcs-handle", 0); @@ -3061,17 +3029,14 @@ static int axienet_probe(struct platform_device *pd= ev) np =3D of_parse_phandle(dev->of_node, "phy-handle", 0); } if (!np) { - dev_err(dev, "pcs-handle (preferred) or phy-handle required for 1000Bas= eX/SGMII\n"); - ret =3D -EINVAL; - goto cleanup_mdio; + dev_err(dev, + "pcs-handle (preferred) or phy-handle required for 1000BaseX/SGMII\n"); + return -EINVAL; } lp->pcs_phy =3D of_mdio_find_device(np); - if (!lp->pcs_phy) { - ret =3D -EPROBE_DEFER; - of_node_put(np); - goto cleanup_mdio; - } of_node_put(np); + if (!lp->pcs_phy) + return -EPROBE_DEFER; lp->pcs.ops =3D &axienet_pcs_ops; lp->pcs.poll =3D true; } @@ -3096,7 +3061,7 @@ static int axienet_probe(struct platform_device *pdev) if (IS_ERR(lp->phylink)) { ret =3D PTR_ERR(lp->phylink); dev_err(dev, "phylink_create error (%i)\n", ret); - goto cleanup_mdio; + goto cleanup_pcs; } =20 ret =3D register_netdev(lp->ndev); @@ -3109,32 +3074,24 @@ static int axienet_probe(struct platform_device *pd= ev) =20 cleanup_phylink: phylink_destroy(lp->phylink); - -cleanup_mdio: +cleanup_pcs: if (lp->pcs_phy) put_device(&lp->pcs_phy->dev); - if (lp->mii_bus) - axienet_mdio_teardown(lp); return ret; } =20 -static void axienet_remove(struct platform_device *pdev) +static void axienet_mac_remove(struct platform_device *pdev) { struct net_device *ndev =3D platform_get_drvdata(pdev); struct axienet_local *lp =3D netdev_priv(ndev); =20 unregister_netdev(ndev); - - if (lp->phylink) - phylink_destroy(lp->phylink); - + phylink_destroy(lp->phylink); if (lp->pcs_phy) put_device(&lp->pcs_phy->dev); - - axienet_mdio_teardown(lp); } =20 -static void axienet_shutdown(struct platform_device *pdev) +static void axienet_mac_shutdown(struct platform_device *pdev) { struct net_device *ndev =3D platform_get_drvdata(pdev); =20 @@ -3182,10 +3139,64 @@ static int axienet_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(axienet_pm_ops, axienet_suspend, axienet_resume); =20 +static int axienet_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct axienet_common *cp; + struct resource *ethres; + int ret; + + cp =3D devm_kzalloc(dev, sizeof(*cp), GFP_KERNEL); + if (!cp) + return -ENOMEM; + + cp->pdev =3D pdev; + mutex_init(&cp->reset_lock); + + cp->axi_clk =3D devm_clk_get_optional_enabled(dev, "s_axi_lite_clk"); + if (!cp->axi_clk) { + /* For backward compatibility, if named AXI clock is not present, + * treat the first clock specified as the AXI clock. + */ + cp->axi_clk =3D devm_clk_get_optional_enabled(dev, NULL); + } + if (IS_ERR(cp->axi_clk)) + return dev_err_probe(dev, PTR_ERR(cp->axi_clk), + "could not get AXI clock\n"); + + /* Map device registers */ + cp->regs =3D devm_platform_get_and_ioremap_resource(pdev, 0, ðres); + if (IS_ERR(cp->regs)) + return PTR_ERR(cp->regs); + cp->regs_start =3D ethres->start; + + ret =3D axienet_mdio_setup(cp); + if (ret) + dev_warn(dev, "error registering MDIO bus: %d\n", ret); + + ret =3D axienet_mac_probe(cp); + if (!ret) + return 0; + + if (cp->mii_bus) + axienet_mdio_teardown(cp); + return ret; +} + +static void axienet_remove(struct platform_device *pdev) +{ + struct net_device *ndev =3D platform_get_drvdata(pdev); + struct axienet_local *lp =3D netdev_priv(ndev); + + axienet_mac_remove(pdev); + if (lp->mii_bus) + axienet_mdio_teardown(lp->cp); +} + static struct platform_driver axienet_driver =3D { .probe =3D axienet_probe, .remove =3D axienet_remove, - .shutdown =3D axienet_shutdown, + .shutdown =3D axienet_mac_shutdown, .driver =3D { .name =3D "xilinx_axienet", .pm =3D &axienet_pm_ops, diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/ne= t/ethernet/xilinx/xilinx_axienet_mdio.c index 2799d168ed9d..d428ce6da639 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include =20 @@ -22,13 +23,13 @@ =20 /** * axienet_mdio_wait_until_ready - MDIO wait function - * @lp: Pointer to axienet local data structure. + * @lp: Pointer to axienet common data structure. * * Return : 0 on success, Negative value on errors * * Wait till MDIO interface is ready to accept a new transaction. */ -static int axienet_mdio_wait_until_ready(struct axienet_local *lp) +static int axienet_mdio_wait_until_ready(struct axienet_common *lp) { u32 val; =20 @@ -39,11 +40,11 @@ static int axienet_mdio_wait_until_ready(struct axienet= _local *lp) =20 /** * axienet_mdio_mdc_enable - MDIO MDC enable function - * @lp: Pointer to axienet local data structure. + * @lp: Pointer to axienet common data structure. * * Enable the MDIO MDC. Called prior to a read/write operation */ -static void axienet_mdio_mdc_enable(struct axienet_local *lp) +static void axienet_mdio_mdc_enable(struct axienet_common *lp) { iowrite32((u32)lp->mii_clk_div | XAE_MDIO_MC_MDIOEN_MASK, lp->regs + XAE_MDIO_MC_OFFSET); @@ -51,11 +52,11 @@ static void axienet_mdio_mdc_enable(struct axienet_loca= l *lp) =20 /** * axienet_mdio_mdc_disable - MDIO MDC disable function - * @lp: Pointer to axienet local data structure. + * @lp: Pointer to axienet common data structure. * * Disable the MDIO MDC. Called after a read/write operation */ -static void axienet_mdio_mdc_disable(struct axienet_local *lp) +static void axienet_mdio_mdc_disable(struct axienet_common *lp) { u32 mc_reg; =20 @@ -80,8 +81,9 @@ static int axienet_mdio_read(struct mii_bus *bus, int phy= _id, int reg) { u32 rc; int ret; - struct axienet_local *lp =3D bus->priv; + struct axienet_common *lp =3D bus->priv; =20 + guard(mutex)(&lp->reset_lock); axienet_mdio_mdc_enable(lp); =20 ret =3D axienet_mdio_wait_until_ready(lp); @@ -127,13 +129,14 @@ static int axienet_mdio_read(struct mii_bus *bus, int= phy_id, int reg) static int axienet_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 val) { - struct axienet_local *lp =3D bus->priv; + struct axienet_common *lp =3D bus->priv; int ret; u32 mcr; =20 dev_dbg(&bus->dev, "%s(phy_id=3D%i, reg=3D%x, val=3D%x)\n", __func__, phy_id, reg, val); =20 + guard(mutex)(&lp->reset_lock); axienet_mdio_mdc_enable(lp); =20 ret =3D axienet_mdio_wait_until_ready(lp); @@ -160,7 +163,7 @@ static int axienet_mdio_write(struct mii_bus *bus, int = phy_id, int reg, =20 /** * axienet_mdio_enable - MDIO hardware setup function - * @lp: Pointer to axienet local data structure. + * @lp: Pointer to axienet common data structure. * @np: Pointer to mdio device tree node. * * Return: 0 on success, -ETIMEDOUT on a timeout, -EOVERFLOW on a clock @@ -171,7 +174,7 @@ static int axienet_mdio_write(struct mii_bus *bus, int = phy_id, int reg, **/ static int axienet_mdio_enable(struct mii_bus *bus, struct device_node *np) { - struct axienet_local *lp =3D bus->priv; + struct axienet_common *lp =3D bus->priv; u32 mdio_freq =3D DEFAULT_MDIO_FREQ; u32 host_clock; u32 clk_div; @@ -187,7 +190,7 @@ static int axienet_mdio_enable(struct mii_bus *bus, str= uct device_node *np) /* Legacy fallback: detect CPU clock frequency and use as AXI * bus clock frequency. This only works on certain platforms. */ - np1 =3D of_find_node_by_name(NULL, "lpu"); + np1 =3D of_find_node_by_name(NULL, "cpu"); if (!np1) { dev_warn(&bus->dev, "Could not find CPU device node.\n"); @@ -258,6 +261,7 @@ static int axienet_mdio_enable(struct mii_bus *bus, str= uct device_node *np) "Setting MDIO clock divisor to %u/%u Hz host clock.\n", lp->mii_clk_div, host_clock); =20 + guard(mutex)(&lp->reset_lock); axienet_mdio_mdc_enable(lp); =20 ret =3D axienet_mdio_wait_until_ready(lp); @@ -269,7 +273,7 @@ static int axienet_mdio_enable(struct mii_bus *bus, str= uct device_node *np) =20 /** * axienet_mdio_setup - MDIO setup function - * @lp: Pointer to axienet local data structure. + * @lp: Pointer to axienet common data structure. * * Return: 0 on success, -ETIMEDOUT on a timeout, -EOVERFLOW on a clock * divisor overflow, -ENOMEM when mdiobus_alloc (to allocate @@ -278,7 +282,7 @@ static int axienet_mdio_enable(struct mii_bus *bus, str= uct device_node *np) * Sets up the MDIO interface by initializing the MDIO clock. * Register the MDIO interface. **/ -int axienet_mdio_setup(struct axienet_local *lp) +int axienet_mdio_setup(struct axienet_common *lp) { struct device_node *mdio_node; struct mii_bus *bus; @@ -295,18 +299,21 @@ int axienet_mdio_setup(struct axienet_local *lp) bus->name =3D "Xilinx Axi Ethernet MDIO"; bus->read =3D axienet_mdio_read; bus->write =3D axienet_mdio_write; - bus->parent =3D lp->dev; + bus->parent =3D &lp->pdev->dev; lp->mii_bus =3D bus; =20 - mdio_node =3D of_get_child_by_name(lp->dev->of_node, "mdio"); - ret =3D axienet_mdio_enable(bus, mdio_node); + mdio_node =3D of_get_child_by_name(lp->pdev->dev.of_node, "mdio"); + scoped_guard(mutex, &lp->reset_lock) + ret =3D axienet_mdio_enable(bus, mdio_node); if (ret < 0) goto unregister; =20 ret =3D of_mdiobus_register(bus, mdio_node); of_node_put(mdio_node); - axienet_mdio_mdc_disable(lp); + scoped_guard(mutex, &lp->reset_lock) + axienet_mdio_mdc_disable(lp); if (ret) { +unregister: mdiobus_free(bus); lp->mii_bus =3D NULL; } @@ -315,11 +322,11 @@ int axienet_mdio_setup(struct axienet_local *lp) =20 /** * axienet_mdio_teardown - MDIO remove function - * @lp: Pointer to axienet local data structure. + * @lp: Pointer to axienet common data structure. * * Unregisters the MDIO and frees any associate memory for mii bus. */ -void axienet_mdio_teardown(struct axienet_local *lp) +void axienet_mdio_teardown(struct axienet_common *lp) { mdiobus_unregister(lp->mii_bus); mdiobus_free(lp->mii_bus); --=20 2.35.1.1320.gc452695387.dirty From nobody Sun Oct 5 23:40:19 2025 Received: from out-172.mta1.migadu.com (out-172.mta1.migadu.com [95.215.58.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A39C238C15 for ; Mon, 28 Jul 2025 22:18:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753741130; cv=none; b=IpbZzB6qJ5aXw6u+dx7ap5XhpqcTLXiw6qScXKtYJRQ/C6iJq1ViosjxQ9pOIPMVmh5Cg22zafpZIUWddT4Vx9ANdkHLB0vFItMBP5lDGReeIf3GGEgfqGpQgfpKKSsTqJrajsTgM3o0/KLDgw3uawZgTmvQ6Y2eKifOpFjDQfg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753741130; c=relaxed/simple; bh=Du7wSOiVjtgKvcFvEV/Ua5/p9cKvEnHoqJYSycauhl0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=J7+3os7cF/7OEUFuMUq852c0yzr45TeWtf5al0iivRKfook+FbEscovTED3ZhxZLb9wHBuchuNsd3gGoEWxcltcv5NE1LBn7LtE/J/fMgzMfSzPVOJ6Svn8BApFY/LTAAm0NWDuIyMUYkOEpJ2Q3p890I+iyn+Tl7RrL0AtOMTU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Mw12Y+9d; arc=none smtp.client-ip=95.215.58.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Mw12Y+9d" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1753741125; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=n17YgDJ5HzDuuvYFKxWVMhkXCItP/j4fG+awnCjSKSA=; b=Mw12Y+9d3qtWJeTNKwoC2hntKyund/b9S9GlER2ktZPFg2ELwnL18S8r5TuFW8Zopj5c4D reIpMGAd3SbDfAuJMooTHD5rY4RIRtn1SOBtG/TmMYE3GPj8H8co6PVWWncRu77loV4FUH 4Jnxrum6CfXHqDPKJtIAZB5l/OriLMA= From: Sean Anderson To: Radhey Shyam Pandey , Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Greg Kroah-Hartman , Michal Simek , linux-arm-kernel@lists.infradead.org, Leon Romanovsky , Sean Anderson Subject: [PATCH net-next v3 7/7] net: axienet: Split into MAC and MDIO drivers Date: Mon, 28 Jul 2025 18:18:23 -0400 Message-Id: <20250728221823.11968-8-sean.anderson@linux.dev> In-Reply-To: <20250728221823.11968-1-sean.anderson@linux.dev> References: <20250728221823.11968-1-sean.anderson@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Returning EPROBE_DEFER after probing a bus may result in an infinite probe loop if the EPROBE_DEFER error is never resolved. There are two mutually-exclusive scenarios (that can both occur in the same system). First, the PCS can be attached to our own MDIO bus: MAC | +->MDIO | +->PCS +->PHY (etc) In this scenario, we have to probe the MDIO bus before we can look up the PCS, since otherwise the PCS will always be missing when we look for it. But if we do things in the right order then we can't get EPROBE_DEFER, and so there's no risk of a probe loop. Second, the PCS can be attached to some other MDIO bus: MAC MDIO | | +->MDIO +->PCS | +->PHY (etc) In this scenario, the MDIO bus might not be present for whatever reason (module not loaded, error in probe, etc.) and we have the possibility of an EPROBE_DEFER error. If that happens, we will end up in a probe loop because the PHY on our own MDIO bus incremented deferred_trigger_count when it probed successfully: deferred_probe_work_func() driver_probe_device(MAC) axienet_probe(MAC) mdiobus_register(MDIO) device_add(PHY) (probe successful) driver_bound(PHY) driver_deferred_probe_trigger() return -EPROBE_DEFER driver_deferred_probe_add(MAC) // deferred_trigger_count changed, so... driver_deferred_probe_trigger() As I see it, this problem could be solved in the following four ways: - Modify the driver core to detect and mitigate this sort of scenario (NACKed by Greg). - Split the driver into MAC and MDIO parts (this commit). - Modify phylink to allow connecting a PCS after phylink_create but before phylink_start. This is tricky because the PCS can affect the supported phy interfaces, and phy interfaces are validated in phylink_create. - Defer phylink_create to ndo_open. This means that all the netdev/ethtool ops that use phylink now need to check ip the netdev is open and fall back to some other implementation. I don't think we can just return -EINVAL or whatever because using ethtool on a down device has historically worked. I am wary of breaking userspace because some tool assumes it can get_ksettings while the netdev is down. Aside from the first option, the second one (this commit) has the best UX. With the latter two, you could have a netdev that never comes up and the user may not have very good insight as to why. For example, it may not be obvious that the user should try to bring the netdev up again after the PCS is probed. By waiting to create the netdev until after we successfully probe the PCS we show up in devices_deferred and the netdev can be brought up as usual. Per the second bullet point above, split the MAC and MDIO functionality into separate auxiliary devices. If the MAC fails with EPROBE_DEFER, then the MDIO bus will remain bound, preventing a probe loop. Fixes: 1a02556086fc ("net: axienet: Properly handle PCS/PMA PHY for 1000Bas= eX mode") Signed-off-by: Sean Anderson --- Changes in v3: - Rework to use a separate axienet_common structure, as netdevs cannot be reused once registered. - Use ida_alloc for aux id Changes in v2: - Fix building as a module - Expand commit message with much more info on the problem and possible solutions drivers/net/ethernet/xilinx/Kconfig | 1 + drivers/net/ethernet/xilinx/xilinx_axienet.h | 10 +- .../net/ethernet/xilinx/xilinx_axienet_main.c | 168 ++++++++++++++---- .../net/ethernet/xilinx/xilinx_axienet_mdio.c | 59 +++--- 4 files changed, 169 insertions(+), 69 deletions(-) diff --git a/drivers/net/ethernet/xilinx/Kconfig b/drivers/net/ethernet/xil= inx/Kconfig index 7502214cc7d5..3b940d2d3115 100644 --- a/drivers/net/ethernet/xilinx/Kconfig +++ b/drivers/net/ethernet/xilinx/Kconfig @@ -27,6 +27,7 @@ config XILINX_AXI_EMAC tristate "Xilinx 10/100/1000 AXI Ethernet support" depends on HAS_IOMEM depends on XILINX_DMA + select AUXILIARY_BUS select PHYLINK select DIMLIB help diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/eth= ernet/xilinx/xilinx_axienet.h index d7215dd92ce9..69665c7f264a 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet.h +++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h @@ -470,6 +470,7 @@ struct skbuf_dma_descriptor { /** * struct axienet_common - axienet private common data * @pdev: Pointer to common platform device structure + * @mac: Pointer to MAC (netdev parent) device structure * @axi_clk: AXI4-Lite bus clock * @reset_lock: Lock held while resetting the device to prevent register a= ccess * @mii_bus: Pointer to MII bus structure @@ -479,11 +480,12 @@ struct skbuf_dma_descriptor { */ struct axienet_common { struct platform_device *pdev; + struct auxiliary_device mac; =20 struct clk *axi_clk; =20 struct mutex reset_lock; - struct mii_bus *mii_bus; + struct auxiliary_device mii_bus; u8 mii_clk_div; =20 void __iomem *regs; @@ -493,7 +495,7 @@ struct axienet_common { /** * struct axienet_local - axienet private per device data * @ndev: Pointer for net_device to which it will be attached. - * @dev: Pointer to device structure + * @dev: Pointer to parent device structure for DMA access * @phylink: Pointer to phylink instance * @phylink_config: phylink configuration settings * @pcs_phy: Reference to PCS/PMA PHY if used @@ -752,8 +754,6 @@ static inline void axienet_dma_out_addr(struct axienet_= local *lp, off_t reg, =20 #endif /* CONFIG_64BIT */ =20 -/* Function prototypes visible in xilinx_axienet_mdio.c for other files */ -int axienet_mdio_setup(struct axienet_common *lp); -void axienet_mdio_teardown(struct axienet_common *lp); +extern struct auxiliary_driver xilinx_axienet_mdio; =20 #endif /* XILINX_AXI_ENET_H */ diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/ne= t/ethernet/xilinx/xilinx_axienet_main.c index f235ef15187c..23e5c8090d45 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -22,6 +22,7 @@ * - Add support for extended VLAN support. */ =20 +#include #include #include #include @@ -1907,8 +1908,11 @@ static const struct net_device_ops axienet_netdev_dm= aengine_ops =3D { static void axienet_ethtools_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *ed) { + struct axienet_local *lp =3D netdev_priv(ndev); + strscpy(ed->driver, DRIVER_NAME, sizeof(ed->driver)); strscpy(ed->version, DRIVER_VERSION, sizeof(ed->version)); + strscpy(ed->bus_info, dev_name(lp->dev), sizeof(ed->bus_info)); } =20 /** @@ -2749,10 +2753,12 @@ static void axienet_disable_misc(void *clocks) clk_bulk_disable_unprepare(XAE_NUM_MISC_CLOCKS, clocks); } =20 -static int axienet_mac_probe(struct axienet_common *cp) +static int axienet_mac_probe(struct auxiliary_device *auxdev, + const struct auxiliary_device_id *id) { + struct axienet_common *cp =3D auxdev->dev.platform_data; struct platform_device *pdev =3D cp->pdev; - struct device *dev =3D &pdev->dev; + struct device *dev =3D &auxdev->dev; struct axienet_local *lp; struct net_device *ndev; struct device_node *np; @@ -2765,7 +2771,7 @@ static int axienet_mac_probe(struct axienet_common *c= p) if (!ndev) return -ENOMEM; =20 - platform_set_drvdata(pdev, ndev); + auxiliary_set_drvdata(auxdev, ndev); =20 SET_NETDEV_DEV(ndev, dev); ndev->features =3D NETIF_F_SG; @@ -2777,7 +2783,7 @@ static int axienet_mac_probe(struct axienet_common *c= p) =20 lp =3D netdev_priv(ndev); lp->ndev =3D ndev; - lp->dev =3D dev; + lp->dev =3D &pdev->dev; lp->cp =3D cp; lp->regs =3D cp->regs; lp->options =3D XAE_OPTION_DEFAULTS; @@ -2909,8 +2915,11 @@ static int axienet_mac_probe(struct axienet_common *= cp) of_node_put(np); lp->eth_irq =3D platform_get_irq_optional(pdev, 0); } else { + struct resource *dmares; + /* Check for these resources directly on the Ethernet node. */ - lp->dma_regs =3D devm_platform_get_and_ioremap_resource(pdev, 1, NULL); + dmares =3D platform_get_resource(pdev, IORESOURCE_MEM, 1); + lp->dma_regs =3D devm_ioremap_resource(dev, dmares); lp->rx_irq =3D platform_get_irq(pdev, 1); lp->tx_irq =3D platform_get_irq(pdev, 0); lp->eth_irq =3D platform_get_irq_optional(pdev, 2); @@ -2925,7 +2934,9 @@ static int axienet_mac_probe(struct axienet_common *c= p) } =20 /* Reset core now that clocks are enabled, prior to accessing MDIO */ + axienet_lock_mii(lp); ret =3D __axienet_device_reset(lp); + axienet_unlock_mii(lp); if (ret) return ret; =20 @@ -2957,7 +2968,8 @@ static int axienet_mac_probe(struct axienet_common *c= p) return -EINVAL; } =20 - ret =3D dma_set_mask_and_coherent(dev, DMA_BIT_MASK(addr_width)); + ret =3D dma_set_mask_and_coherent(lp->dev, + DMA_BIT_MASK(addr_width)); if (ret) { dev_err(dev, "No suitable DMA available\n"); return ret; @@ -3055,7 +3067,7 @@ static int axienet_mac_probe(struct axienet_common *c= p) lp->phylink_config.supported_interfaces); } =20 - lp->phylink =3D phylink_create(&lp->phylink_config, dev->fwnode, + lp->phylink =3D phylink_create(&lp->phylink_config, dev_fwnode(dev), lp->phy_mode, &axienet_phylink_ops); if (IS_ERR(lp->phylink)) { @@ -3080,9 +3092,9 @@ static int axienet_mac_probe(struct axienet_common *c= p) return ret; } =20 -static void axienet_mac_remove(struct platform_device *pdev) +static void axienet_mac_remove(struct auxiliary_device *auxdev) { - struct net_device *ndev =3D platform_get_drvdata(pdev); + struct net_device *ndev =3D auxiliary_get_drvdata(auxdev); struct axienet_local *lp =3D netdev_priv(ndev); =20 unregister_netdev(ndev); @@ -3091,9 +3103,9 @@ static void axienet_mac_remove(struct platform_device= *pdev) put_device(&lp->pcs_phy->dev); } =20 -static void axienet_mac_shutdown(struct platform_device *pdev) +static void axienet_mac_shutdown(struct auxiliary_device *auxdev) { - struct net_device *ndev =3D platform_get_drvdata(pdev); + struct net_device *ndev =3D auxiliary_get_drvdata(auxdev); =20 rtnl_lock(); netif_device_detach(ndev); @@ -3139,12 +3151,78 @@ static int axienet_resume(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(axienet_pm_ops, axienet_suspend, axienet_resume); =20 +static const struct auxiliary_device_id xilinx_axienet_mac_id_table[] =3D { + { .name =3D KBUILD_MODNAME ".mac", }, + { }, +}; +MODULE_DEVICE_TABLE(auxiliary, xilinx_axienet_mac_id_table); + +static struct auxiliary_driver xilinx_axienet_mac =3D { + .name =3D "mac", + .id_table =3D xilinx_axienet_mac_id_table, + .probe =3D axienet_mac_probe, + .remove =3D axienet_mac_remove, + .shutdown =3D axienet_mac_shutdown, + .driver =3D { + .pm =3D &axienet_pm_ops, + }, +}; + +static DEFINE_IDA(axienet_id); + +static void axienet_id_free(void *data) +{ + int id =3D (intptr_t)data; + + ida_free(&axienet_id, id); +} + +static void auxenet_aux_release(struct device *dev) { } + +static void axienet_aux_destroy(void *data) +{ + struct auxiliary_device *auxdev =3D data; + + auxiliary_device_delete(auxdev); + auxiliary_device_uninit(auxdev); + fwnode_handle_put(auxdev->dev.fwnode); +} + +static int axienet_aux_create(struct axienet_common *cp, + struct auxiliary_device *auxdev, const char *name, + int id, struct fwnode_handle *fwnode) +{ + struct device *dev =3D &cp->pdev->dev; + int ret; + + auxdev->name =3D name; + auxdev->id =3D id; + auxdev->dev.parent =3D dev; + auxdev->dev.platform_data =3D cp; + auxdev->dev.release =3D auxenet_aux_release; + device_set_node(&auxdev->dev, fwnode); + ret =3D auxiliary_device_init(auxdev); + if (ret) { + fwnode_handle_put(fwnode); + return ret; + } + + ret =3D auxiliary_device_add(auxdev); + if (ret) { + fwnode_handle_put(fwnode); + auxiliary_device_uninit(auxdev); + return ret; + } + + return devm_add_action_or_reset(dev, axienet_aux_destroy, auxdev); +} + static int axienet_probe(struct platform_device *pdev) { struct device *dev =3D &pdev->dev; struct axienet_common *cp; struct resource *ethres; - int ret; + int ret, id; =20 cp =3D devm_kzalloc(dev, sizeof(*cp), GFP_KERNEL); if (!cp) @@ -3170,33 +3248,31 @@ static int axienet_probe(struct platform_device *pd= ev) return PTR_ERR(cp->regs); cp->regs_start =3D ethres->start; =20 - ret =3D axienet_mdio_setup(cp); - if (ret) - dev_warn(dev, "error registering MDIO bus: %d\n", ret); + id =3D ida_alloc(&axienet_id, GFP_KERNEL); + if (id < 0) + return dev_err_probe(dev, id, "could not allocate id\n"); =20 - ret =3D axienet_mac_probe(cp); - if (!ret) - return 0; + ret =3D devm_add_action_or_reset(dev, axienet_id_free, + (void *)(intptr_t)id); + if (ret) + return dev_err_probe(dev, ret, + "could not register id free action\n"); =20 - if (cp->mii_bus) - axienet_mdio_teardown(cp); - return ret; -} + ret =3D axienet_aux_create(cp, &cp->mii_bus, "mdio", id, + device_get_named_child_node(dev, "mdio")); + if (ret) + return dev_err_probe(dev, ret, "could not create mdio bus\n"); =20 -static void axienet_remove(struct platform_device *pdev) -{ - struct net_device *ndev =3D platform_get_drvdata(pdev); - struct axienet_local *lp =3D netdev_priv(ndev); + ret =3D axienet_aux_create(cp, &cp->mac, "mac", id, + fwnode_handle_get(dev_fwnode(dev))); + if (ret) + return dev_err_probe(dev, ret, "could not create MAC\n"); =20 - axienet_mac_remove(pdev); - if (lp->mii_bus) - axienet_mdio_teardown(lp->cp); + return 0; } =20 static struct platform_driver axienet_driver =3D { .probe =3D axienet_probe, - .remove =3D axienet_remove, - .shutdown =3D axienet_mac_shutdown, .driver =3D { .name =3D "xilinx_axienet", .pm =3D &axienet_pm_ops, @@ -3204,7 +3280,35 @@ static struct platform_driver axienet_driver =3D { }, }; =20 -module_platform_driver(axienet_driver); +static int __init axienet_init(void) +{ + int ret; + + ret =3D auxiliary_driver_register(&xilinx_axienet_mdio); + if (ret) + return ret; + + ret =3D auxiliary_driver_register(&xilinx_axienet_mac); + if (ret) + goto unregister_mdio; + + ret =3D platform_driver_register(&axienet_driver); + if (ret) { + auxiliary_driver_unregister(&xilinx_axienet_mac); +unregister_mdio: + auxiliary_driver_unregister(&xilinx_axienet_mdio); + } + return ret; +} +module_init(axienet_init); + +static void __exit axienet_exit(void) +{ + platform_driver_register(&axienet_driver); + auxiliary_driver_unregister(&xilinx_axienet_mac); + auxiliary_driver_unregister(&xilinx_axienet_mdio); +} +module_exit(axienet_exit); =20 MODULE_DESCRIPTION("Xilinx Axi Ethernet driver"); MODULE_AUTHOR("Xilinx"); diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/ne= t/ethernet/xilinx/xilinx_axienet_mdio.c index d428ce6da639..cc8a2a70271b 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -9,10 +9,10 @@ * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved. */ =20 +#include #include #include #include -#include #include #include =20 @@ -271,19 +271,10 @@ static int axienet_mdio_enable(struct mii_bus *bus, s= truct device_node *np) return ret; } =20 -/** - * axienet_mdio_setup - MDIO setup function - * @lp: Pointer to axienet common data structure. - * - * Return: 0 on success, -ETIMEDOUT on a timeout, -EOVERFLOW on a clock - * divisor overflow, -ENOMEM when mdiobus_alloc (to allocate - * memory for mii bus structure) fails. - * - * Sets up the MDIO interface by initializing the MDIO clock. - * Register the MDIO interface. - **/ -int axienet_mdio_setup(struct axienet_common *lp) +static int axienet_mdio_probe(struct auxiliary_device *auxdev, + const struct auxiliary_device_id *id) { + struct axienet_common *lp =3D auxdev->dev.platform_data; struct device_node *mdio_node; struct mii_bus *bus; int ret; @@ -299,36 +290,40 @@ int axienet_mdio_setup(struct axienet_common *lp) bus->name =3D "Xilinx Axi Ethernet MDIO"; bus->read =3D axienet_mdio_read; bus->write =3D axienet_mdio_write; - bus->parent =3D &lp->pdev->dev; - lp->mii_bus =3D bus; + bus->parent =3D &auxdev->dev; + auxiliary_set_drvdata(auxdev, bus); =20 - mdio_node =3D of_get_child_by_name(lp->pdev->dev.of_node, "mdio"); - scoped_guard(mutex, &lp->reset_lock) - ret =3D axienet_mdio_enable(bus, mdio_node); + mdio_node =3D dev_of_node(&auxdev->dev); + ret =3D axienet_mdio_enable(bus, mdio_node); if (ret < 0) goto unregister; =20 ret =3D of_mdiobus_register(bus, mdio_node); - of_node_put(mdio_node); scoped_guard(mutex, &lp->reset_lock) axienet_mdio_mdc_disable(lp); - if (ret) { + if (ret) unregister: mdiobus_free(bus); - lp->mii_bus =3D NULL; - } return ret; } =20 -/** - * axienet_mdio_teardown - MDIO remove function - * @lp: Pointer to axienet common data structure. - * - * Unregisters the MDIO and frees any associate memory for mii bus. - */ -void axienet_mdio_teardown(struct axienet_common *lp) +static void axienet_mdio_remove(struct auxiliary_device *auxdev) { - mdiobus_unregister(lp->mii_bus); - mdiobus_free(lp->mii_bus); - lp->mii_bus =3D NULL; + struct mii_bus *mii_bus =3D auxiliary_get_drvdata(auxdev); + + mdiobus_unregister(mii_bus); + mdiobus_free(mii_bus); } + +static const struct auxiliary_device_id xilinx_axienet_mdio_id_table[] =3D= { + { .name =3D KBUILD_MODNAME ".mdio", }, + { }, +}; +MODULE_DEVICE_TABLE(auxiliary, xilinx_axienet_mdio_id_table); + +struct auxiliary_driver xilinx_axienet_mdio =3D { + .name =3D "mdio", + .id_table =3D xilinx_axienet_mdio_id_table, + .probe =3D axienet_mdio_probe, + .remove =3D axienet_mdio_remove, +}; --=20 2.35.1.1320.gc452695387.dirty