[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID:
<PAXPR04MB8510CADFAAD3F4F0DA046ADB88402@PAXPR04MB8510.eurprd04.prod.outlook.com>
Date: Fri, 18 Oct 2024 01:23:24 +0000
From: Wei Fang <wei.fang@....com>
To: Frank Li <frank.li@....com>
CC: "davem@...emloft.net" <davem@...emloft.net>, "edumazet@...gle.com"
<edumazet@...gle.com>, "kuba@...nel.org" <kuba@...nel.org>,
"pabeni@...hat.com" <pabeni@...hat.com>, "robh@...nel.org" <robh@...nel.org>,
"krzk+dt@...nel.org" <krzk+dt@...nel.org>, "conor+dt@...nel.org"
<conor+dt@...nel.org>, Vladimir Oltean <vladimir.oltean@....com>, Claudiu
Manoil <claudiu.manoil@....com>, Clark Wang <xiaoning.wang@....com>,
"christophe.leroy@...roup.eu" <christophe.leroy@...roup.eu>,
"linux@...linux.org.uk" <linux@...linux.org.uk>, "bhelgaas@...gle.com"
<bhelgaas@...gle.com>, "horms@...nel.org" <horms@...nel.org>,
"imx@...ts.linux.dev" <imx@...ts.linux.dev>, "netdev@...r.kernel.org"
<netdev@...r.kernel.org>, "devicetree@...r.kernel.org"
<devicetree@...r.kernel.org>, "linux-kernel@...r.kernel.org"
<linux-kernel@...r.kernel.org>, "linux-pci@...r.kernel.org"
<linux-pci@...r.kernel.org>
Subject: RE: [PATCH v3 net-next 04/13] net: enetc: add initial netc-blk-ctrl
driver support
> -----Original Message-----
> From: Frank Li <frank.li@....com>
> Sent: 2024年10月18日 0:34
> To: Wei Fang <wei.fang@....com>
> Cc: davem@...emloft.net; edumazet@...gle.com; kuba@...nel.org;
> pabeni@...hat.com; robh@...nel.org; krzk+dt@...nel.org;
> conor+dt@...nel.org; Vladimir Oltean <vladimir.oltean@....com>; Claudiu
> Manoil <claudiu.manoil@....com>; Clark Wang <xiaoning.wang@....com>;
> christophe.leroy@...roup.eu; linux@...linux.org.uk; bhelgaas@...gle.com;
> horms@...nel.org; imx@...ts.linux.dev; netdev@...r.kernel.org;
> devicetree@...r.kernel.org; linux-kernel@...r.kernel.org;
> linux-pci@...r.kernel.org
> Subject: Re: [PATCH v3 net-next 04/13] net: enetc: add initial netc-blk-ctrl
> driver support
>
> On Thu, Oct 17, 2024 at 03:46:28PM +0800, Wei Fang wrote:
> > The netc-blk-ctrl driver is used to configure Integrated Endpoint
> > Register Block (IERB) and Privileged Register Block (PRB) of NETC.
> > For i.MX platforms, it is also used to configure the NETCMIX block.
> >
> > The IERB contains registers that are used for pre-boot initialization,
> > debug, and non-customer configuration. The PRB controls global reset
> > and global error handling for NETC. The NETCMIX block is mainly used
> > to set MII protocol and PCS protocol of the links, it also contains
> > settings for some other functions.
> >
> > Note the IERB configuration registers can only be written after being
> > unlocked by PRB, otherwise, all write operations are inhibited. A warm
> > reset is performed when the IERB is unlocked, and it results in an FLR
> > to all NETC devices. Therefore, all NETC device drivers must be probed
> > or initialized after the warm reset is finished.
> >
> > Signed-off-by: Wei Fang <wei.fang@....com>
> > ---
> > v2 changes:
> > 1. Add linux/bits.h
> > 2. Remove the useless check at the beginning of netc_blk_ctrl_probe().
> > 3. Use dev_err_probe() in netc_blk_ctrl_probe().
> > v3 changes:
> > 1. Change the compatible string to "pci1131,e101".
> > 2. Add devm_clk_get_optional_enabled() instead of
> > devm_clk_get_optional() 3. Directly return dev_err_probe().
> > 4. Remove unused netc_read64().
> > ---
> > drivers/net/ethernet/freescale/enetc/Kconfig | 14 +
> > drivers/net/ethernet/freescale/enetc/Makefile | 3 +
> > .../ethernet/freescale/enetc/netc_blk_ctrl.c | 440 ++++++++++++++++++
> > include/linux/fsl/netc_global.h | 19 +
> > 4 files changed, 476 insertions(+)
> > create mode 100644
> > drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c
> > create mode 100644 include/linux/fsl/netc_global.h
> >
> > diff --git a/drivers/net/ethernet/freescale/enetc/Kconfig
> > b/drivers/net/ethernet/freescale/enetc/Kconfig
> > index 4d75e6807e92..51d80ea959d4 100644
> > --- a/drivers/net/ethernet/freescale/enetc/Kconfig
> > +++ b/drivers/net/ethernet/freescale/enetc/Kconfig
> > @@ -75,3 +75,17 @@ config FSL_ENETC_QOS
> > enable/disable from user space via Qos commands(tc). In the kernel
> > side, it can be loaded by Qos driver. Currently, it is only support
> > taprio(802.1Qbv) and Credit Based Shaper(802.1Qbu).
> > +
> > +config NXP_NETC_BLK_CTRL
> > + tristate "NETC blocks control driver"
> > + help
> > + This driver configures Integrated Endpoint Register Block (IERB) and
> > + Privileged Register Block (PRB) of NETC. For i.MX platforms, it also
> > + includes the configuration of NETCMIX block.
> > + The IERB contains registers that are used for pre-boot initialization,
> > + debug, and non-customer configuration. The PRB controls global reset
> > + and global error handling for NETC. The NETCMIX block is mainly used
> > + to set MII protocol and PCS protocol of the links, it also contains
> > + settings for some other functions.
> > +
> > + If compiled as module (M), the module name is nxp-netc-blk-ctrl.
> > diff --git a/drivers/net/ethernet/freescale/enetc/Makefile
> > b/drivers/net/ethernet/freescale/enetc/Makefile
> > index b13cbbabb2ea..5c277910d538 100644
> > --- a/drivers/net/ethernet/freescale/enetc/Makefile
> > +++ b/drivers/net/ethernet/freescale/enetc/Makefile
> > @@ -19,3 +19,6 @@ fsl-enetc-mdio-y := enetc_pci_mdio.o enetc_mdio.o
> >
> > obj-$(CONFIG_FSL_ENETC_PTP_CLOCK) += fsl-enetc-ptp.o fsl-enetc-ptp-y
> > := enetc_ptp.o
> > +
> > +obj-$(CONFIG_NXP_NETC_BLK_CTRL) += nxp-netc-blk-ctrl.o
> > +nxp-netc-blk-ctrl-y := netc_blk_ctrl.o
> > \ No newline at end of file
> > diff --git a/drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c
> > b/drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c
> > new file mode 100644
> > index 000000000000..d720bb613b5b
> > --- /dev/null
> > +++ b/drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c
> > @@ -0,0 +1,440 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
> > +/*
> > + * NXP NETC Blocks Control Driver
> > + *
> > + * Copyright 2024 NXP
> > + */
> > +#include <linux/bits.h>
> > +#include <linux/clk.h>
> > +#include <linux/debugfs.h>
> > +#include <linux/delay.h>
> > +#include <linux/fsl/netc_global.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_net.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/phy.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/seq_file.h>
> > +
> > +/* NETCMIX registers */
> > +#define IMX95_CFG_LINK_IO_VAR 0x0
> > +#define IO_VAR_16FF_16G_SERDES 0x1
> > +#define IO_VAR(port, var) (((var) & 0xf) << ((port) << 2))
> > +
> > +#define IMX95_CFG_LINK_MII_PROT 0x4
> > +#define CFG_LINK_MII_PORT_0 GENMASK(3, 0)
> > +#define CFG_LINK_MII_PORT_1 GENMASK(7, 4)
> > +#define MII_PROT_MII 0x0
> > +#define MII_PROT_RMII 0x1
> > +#define MII_PROT_RGMII 0x2
> > +#define MII_PROT_SERIAL 0x3
> > +#define MII_PROT(port, prot) (((prot) & 0xf) << ((port) << 2))
> > +
> > +#define IMX95_CFG_LINK_PCS_PROT(a) (0x8 + (a) * 4)
> > +#define PCS_PROT_1G_SGMII BIT(0)
> > +#define PCS_PROT_2500M_SGMII BIT(1)
> > +#define PCS_PROT_XFI BIT(3)
> > +#define PCS_PROT_SFI BIT(4)
> > +#define PCS_PROT_10G_SXGMII BIT(6)
> > +
> > +/* NETC privileged register block register */
> > +#define PRB_NETCRR 0x100
> > +#define NETCRR_SR BIT(0)
> > +#define NETCRR_LOCK BIT(1)
> > +
> > +#define PRB_NETCSR 0x104
> > +#define NETCSR_ERROR BIT(0)
> > +#define NETCSR_STATE BIT(1)
> > +
> > +/* NETC integrated endpoint register block register */
> > +#define IERB_EMDIOFAUXR 0x344
> > +#define IERB_T0FAUXR 0x444
> > +#define IERB_EFAUXR(a) (0x3044 + 0x100 * (a))
> > +#define IERB_VFAUXR(a) (0x4004 + 0x40 * (a))
> > +#define FAUXR_LDID GENMASK(3, 0)
> > +
> > +/* Platform information */
> > +#define IMX95_ENETC0_BUS_DEVFN 0x0
> > +#define IMX95_ENETC1_BUS_DEVFN 0x40
> > +#define IMX95_ENETC2_BUS_DEVFN 0x80
> > +
> > +/* Flags for different platforms */
> > +#define NETC_HAS_NETCMIX BIT(0)
> > +
> > +struct netc_devinfo {
> > + u32 flags;
> > + int (*netcmix_init)(struct platform_device *pdev);
> > + int (*ierb_init)(struct platform_device *pdev); };
> > +
> > +struct netc_blk_ctrl {
> > + void __iomem *prb;
> > + void __iomem *ierb;
> > + void __iomem *netcmix;
> > +
> > + const struct netc_devinfo *devinfo;
> > + struct platform_device *pdev;
> > + struct dentry *debugfs_root;
> > +};
> > +
> > +static void netc_reg_write(void __iomem *base, u32 offset, u32 val) {
> > + netc_write(base + offset, val);
> > +}
> > +
> > +static u32 netc_reg_read(void __iomem *base, u32 offset) {
> > + return netc_read(base + offset);
> > +}
> > +
> > +static int netc_of_pci_get_bus_devfn(struct device_node *np) {
> > + u32 reg[5];
> > + int error;
> > +
> > + error = of_property_read_u32_array(np, "reg", reg, ARRAY_SIZE(reg));
> > + if (error)
> > + return error;
> > +
> > + return (reg[0] >> 8) & 0xffff;
> > +}
> > +
> > +static int netc_get_link_mii_protocol(phy_interface_t interface) {
> > + switch (interface) {
> > + case PHY_INTERFACE_MODE_MII:
> > + return MII_PROT_MII;
> > + case PHY_INTERFACE_MODE_RMII:
> > + return MII_PROT_RMII;
> > + case PHY_INTERFACE_MODE_RGMII:
> > + case PHY_INTERFACE_MODE_RGMII_ID:
> > + case PHY_INTERFACE_MODE_RGMII_RXID:
> > + case PHY_INTERFACE_MODE_RGMII_TXID:
> > + return MII_PROT_RGMII;
> > + case PHY_INTERFACE_MODE_SGMII:
> > + case PHY_INTERFACE_MODE_2500BASEX:
> > + case PHY_INTERFACE_MODE_10GBASER:
> > + case PHY_INTERFACE_MODE_XGMII:
> > + case PHY_INTERFACE_MODE_USXGMII:
> > + return MII_PROT_SERIAL;
> > + default:
> > + return -EINVAL;
> > + }
> > +}
> > +
> > +static int imx95_netcmix_init(struct platform_device *pdev) {
> > + struct netc_blk_ctrl *priv = platform_get_drvdata(pdev);
> > + struct device_node *np = pdev->dev.of_node;
> > + phy_interface_t interface;
> > + int bus_devfn, mii_proto;
> > + u32 val;
> > + int err;
> > +
> > + /* Default setting of MII protocol */
> > + val = MII_PROT(0, MII_PROT_RGMII) | MII_PROT(1, MII_PROT_RGMII) |
> > + MII_PROT(2, MII_PROT_SERIAL);
> > +
> > + /* Update the link MII protocol through parsing phy-mode */
> > + for_each_available_child_of_node_scoped(np, child) {
> > + for_each_available_child_of_node_scoped(child, gchild) {
> > + if (!of_device_is_compatible(gchild, "pci1131,e101"))
> > + continue;
> > +
> > + bus_devfn = netc_of_pci_get_bus_devfn(gchild);
> > + if (bus_devfn < 0)
> > + return -EINVAL;
> > +
> > + if (bus_devfn == IMX95_ENETC2_BUS_DEVFN)
> > + continue;
> > +
> > + err = of_get_phy_mode(gchild, &interface);
> > + if (err)
> > + continue;
> > +
> > + mii_proto = netc_get_link_mii_protocol(interface);
> > + if (mii_proto < 0)
> > + return -EINVAL;
> > +
> > + switch (bus_devfn) {
> > + case IMX95_ENETC0_BUS_DEVFN:
> > + val = u32_replace_bits(val, mii_proto,
> > + CFG_LINK_MII_PORT_0);
> > + break;
> > + case IMX95_ENETC1_BUS_DEVFN:
> > + val = u32_replace_bits(val, mii_proto,
> > + CFG_LINK_MII_PORT_1);
> > + break;
> > + default:
> > + return -EINVAL;
> > + }
> > + }
> > + }
> > +
> > + /* Configure Link I/O variant */
> > + netc_reg_write(priv->netcmix, IMX95_CFG_LINK_IO_VAR,
> > + IO_VAR(2, IO_VAR_16FF_16G_SERDES));
> > + /* Configure Link 2 PCS protocol */
> > + netc_reg_write(priv->netcmix, IMX95_CFG_LINK_PCS_PROT(2),
> > + PCS_PROT_10G_SXGMII);
> > + netc_reg_write(priv->netcmix, IMX95_CFG_LINK_MII_PROT, val);
> > +
> > + return 0;
> > +}
> > +
> > +static bool netc_ierb_is_locked(struct netc_blk_ctrl *priv) {
> > + return !!(netc_reg_read(priv->prb, PRB_NETCRR) & NETCRR_LOCK); }
> > +
> > +static int netc_lock_ierb(struct netc_blk_ctrl *priv) {
> > + u32 val;
> > +
> > + netc_reg_write(priv->prb, PRB_NETCRR, NETCRR_LOCK);
> > +
> > + return read_poll_timeout(netc_reg_read, val, !(val & NETCSR_STATE),
> > + 100, 2000, false, priv->prb, PRB_NETCSR); }
> > +
> > +static int netc_unlock_ierb_with_warm_reset(struct netc_blk_ctrl
> > +*priv) {
> > + u32 val;
> > +
> > + netc_reg_write(priv->prb, PRB_NETCRR, 0);
> > +
> > + return read_poll_timeout(netc_reg_read, val, !(val & NETCRR_LOCK),
> > + 1000, 100000, true, priv->prb, PRB_NETCRR); }
> > +
> > +static int imx95_ierb_init(struct platform_device *pdev) {
> > + struct netc_blk_ctrl *priv = platform_get_drvdata(pdev);
> > +
> > + /* EMDIO : No MSI-X intterupt */
> > + netc_reg_write(priv->ierb, IERB_EMDIOFAUXR, 0);
> > + /* ENETC0 PF */
> > + netc_reg_write(priv->ierb, IERB_EFAUXR(0), 0);
> > + /* ENETC0 VF0 */
> > + netc_reg_write(priv->ierb, IERB_VFAUXR(0), 1);
> > + /* ENETC0 VF1 */
> > + netc_reg_write(priv->ierb, IERB_VFAUXR(1), 2);
> > + /* ENETC1 PF */
> > + netc_reg_write(priv->ierb, IERB_EFAUXR(1), 3);
> > + /* ENETC1 VF0 */
> > + netc_reg_write(priv->ierb, IERB_VFAUXR(2), 5);
> > + /* ENETC1 VF1 */
> > + netc_reg_write(priv->ierb, IERB_VFAUXR(3), 6);
> > + /* ENETC2 PF */
> > + netc_reg_write(priv->ierb, IERB_EFAUXR(2), 4);
> > + /* ENETC2 VF0 */
> > + netc_reg_write(priv->ierb, IERB_VFAUXR(4), 5);
> > + /* ENETC2 VF1 */
> > + netc_reg_write(priv->ierb, IERB_VFAUXR(5), 6);
> > + /* NETC TIMER */
> > + netc_reg_write(priv->ierb, IERB_T0FAUXR, 7);
> > +
> > + return 0;
> > +}
> > +
> > +static int netc_ierb_init(struct platform_device *pdev) {
> > + struct netc_blk_ctrl *priv = platform_get_drvdata(pdev);
> > + const struct netc_devinfo *devinfo = priv->devinfo;
> > + int err;
> > +
> > + if (netc_ierb_is_locked(priv)) {
> > + err = netc_unlock_ierb_with_warm_reset(priv);
> > + if (err) {
> > + dev_err(&pdev->dev, "Unlock IERB failed.\n");
> > + return err;
> > + }
> > + }
> > +
> > + if (devinfo->ierb_init) {
> > + err = devinfo->ierb_init(pdev);
> > + if (err)
> > + return err;
> > + }
> > +
> > + err = netc_lock_ierb(priv);
> > + if (err) {
> > + dev_err(&pdev->dev, "Lock IERB failed.\n");
> > + return err;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +#if IS_ENABLED(CONFIG_DEBUG_FS)
> > +static int netc_prb_show(struct seq_file *s, void *data) {
> > + struct netc_blk_ctrl *priv = s->private;
> > + u32 val;
> > +
> > + val = netc_reg_read(priv->prb, PRB_NETCRR);
> > + seq_printf(s, "[PRB NETCRR] Lock:%d SR:%d\n",
> > + (val & NETCRR_LOCK) ? 1 : 0,
> > + (val & NETCRR_SR) ? 1 : 0);
> > +
> > + val = netc_reg_read(priv->prb, PRB_NETCSR);
> > + seq_printf(s, "[PRB NETCSR] State:%d Error:%d\n",
> > + (val & NETCSR_STATE) ? 1 : 0,
> > + (val & NETCSR_ERROR) ? 1 : 0);
> > +
> > + return 0;
> > +}
> > +DEFINE_SHOW_ATTRIBUTE(netc_prb);
> > +
> > +static void netc_blk_ctrl_create_debugfs(struct netc_blk_ctrl *priv)
> > +{
> > + struct dentry *root;
> > +
> > + root = debugfs_create_dir("netc_blk_ctrl", NULL);
> > + if (IS_ERR(root))
> > + return;
> > +
> > + priv->debugfs_root = root;
> > +
> > + debugfs_create_file("prb", 0444, root, priv, &netc_prb_fops); }
> > +
> > +static void netc_blk_ctrl_remove_debugfs(struct netc_blk_ctrl *priv)
> > +{
> > + debugfs_remove_recursive(priv->debugfs_root);
> > + priv->debugfs_root = NULL;
> > +}
> > +
> > +#else
> > +
> > +static void netc_blk_ctrl_create_debugfs(struct netc_blk_ctrl *priv)
> > +{ }
> > +
> > +static void netc_blk_ctrl_remove_debugfs(struct netc_blk_ctrl *priv)
> > +{ } #endif
> > +
> > +static int netc_prb_check_error(struct netc_blk_ctrl *priv) {
> > + u32 val;
> > +
> > + val = netc_reg_read(priv->prb, PRB_NETCSR);
> > + if (val & NETCSR_ERROR)
> > + return -1;
>
> nit:
> if (netc_reg_read(priv->prb, PRB_NETCSR) & NETCSR_ERROR))
> return -1;
>
> return 0;
>
Okay, will fix it.
> Reviewed-by: Frank Li <Frank.Li@....com>
>
> > +
> > + return 0;
> > +}
> > +
> > +static const struct netc_devinfo imx95_devinfo = {
> > + .flags = NETC_HAS_NETCMIX,
> > + .netcmix_init = imx95_netcmix_init,
> > + .ierb_init = imx95_ierb_init,
> > +};
> > +
> > +static const struct of_device_id netc_blk_ctrl_match[] = {
> > + { .compatible = "nxp,imx95-netc-blk-ctrl", .data = &imx95_devinfo },
> > + {},
> > +};
> > +MODULE_DEVICE_TABLE(of, netc_blk_ctrl_match);
> > +
> > +static int netc_blk_ctrl_probe(struct platform_device *pdev) {
> > + struct device_node *node = pdev->dev.of_node;
> > + const struct netc_devinfo *devinfo;
> > + struct device *dev = &pdev->dev;
> > + const struct of_device_id *id;
> > + struct netc_blk_ctrl *priv;
> > + struct clk *ipg_clk;
> > + void __iomem *regs;
> > + int err;
> > +
> > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > + if (!priv)
> > + return -ENOMEM;
> > +
> > + priv->pdev = pdev;
> > + ipg_clk = devm_clk_get_optional_enabled(dev, "ipg");
> > + if (IS_ERR(ipg_clk))
> > + return dev_err_probe(dev, PTR_ERR(ipg_clk),
> > + "Set ipg clock failed\n");
> > +
> > + id = of_match_device(netc_blk_ctrl_match, dev);
> > + if (!id)
> > + return dev_err_probe(dev, -EINVAL, "Cannot match device\n");
> > +
> > + devinfo = (struct netc_devinfo *)id->data;
> > + if (!devinfo)
> > + return dev_err_probe(dev, -EINVAL, "No device information\n");
> > +
> > + priv->devinfo = devinfo;
> > + regs = devm_platform_ioremap_resource_byname(pdev, "ierb");
> > + if (IS_ERR(regs))
> > + return dev_err_probe(dev, PTR_ERR(regs),
> > + "Missing IERB resource\n");
> > +
> > + priv->ierb = regs;
> > + regs = devm_platform_ioremap_resource_byname(pdev, "prb");
> > + if (IS_ERR(regs))
> > + return dev_err_probe(dev, PTR_ERR(regs),
> > + "Missing PRB resource\n");
> > +
> > + priv->prb = regs;
> > + if (devinfo->flags & NETC_HAS_NETCMIX) {
> > + regs = devm_platform_ioremap_resource_byname(pdev, "netcmix");
> > + if (IS_ERR(regs))
> > + return dev_err_probe(dev, PTR_ERR(regs),
> > + "Missing NETCMIX resource\n");
> > + priv->netcmix = regs;
> > + }
> > +
> > + platform_set_drvdata(pdev, priv);
> > + if (devinfo->netcmix_init) {
> > + err = devinfo->netcmix_init(pdev);
> > + if (err)
> > + return dev_err_probe(dev, err,
> > + "Initializing NETCMIX failed\n");
> > + }
> > +
> > + err = netc_ierb_init(pdev);
> > + if (err)
> > + return dev_err_probe(dev, err, "Initializing IERB failed\n");
> > +
> > + if (netc_prb_check_error(priv) < 0)
> > + dev_warn(dev, "The current IERB configuration is invalid\n");
> > +
> > + netc_blk_ctrl_create_debugfs(priv);
> > +
> > + err = of_platform_populate(node, NULL, NULL, dev);
> > + if (err) {
> > + netc_blk_ctrl_remove_debugfs(priv);
> > + return dev_err_probe(dev, err, "of_platform_populate failed\n");
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static void netc_blk_ctrl_remove(struct platform_device *pdev) {
> > + struct netc_blk_ctrl *priv = platform_get_drvdata(pdev);
> > +
> > + of_platform_depopulate(&pdev->dev);
> > + netc_blk_ctrl_remove_debugfs(priv);
> > +}
> > +
> > +static struct platform_driver netc_blk_ctrl_driver = {
> > + .driver = {
> > + .name = "nxp-netc-blk-ctrl",
> > + .of_match_table = netc_blk_ctrl_match,
> > + },
> > + .probe = netc_blk_ctrl_probe,
> > + .remove = netc_blk_ctrl_remove,
> > +};
> > +
> > +module_platform_driver(netc_blk_ctrl_driver);
> > +
> > +MODULE_DESCRIPTION("NXP NETC Blocks Control Driver");
> > +MODULE_LICENSE("Dual BSD/GPL");
> > diff --git a/include/linux/fsl/netc_global.h
> > b/include/linux/fsl/netc_global.h new file mode 100644 index
> > 000000000000..fdecca8c90f0
> > --- /dev/null
> > +++ b/include/linux/fsl/netc_global.h
> > @@ -0,0 +1,19 @@
> > +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
> > +/* Copyright 2024 NXP
> > + */
> > +#ifndef __NETC_GLOBAL_H
> > +#define __NETC_GLOBAL_H
> > +
> > +#include <linux/io.h>
> > +
> > +static inline u32 netc_read(void __iomem *reg) {
> > + return ioread32(reg);
> > +}
> > +
> > +static inline void netc_write(void __iomem *reg, u32 val) {
> > + iowrite32(val, reg);
> > +}
> > +
> > +#endif
> > --
> > 2.34.1
> >
Powered by blists - more mailing lists