mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-31 05:54:26 -04:00 
			
		
		
		
	Ran update_kernel.sh in a fresh clone without any existing toolchains. Manually rebased: bcm27xx/950-0993-xhci-quirks-add-link-TRB-quirk-for-VL805.patch layerscape/701-net-0231-enetc-Use-DT-protocol-information-to-set-up-the-port.patch Build system: x86_64 Build-tested: ipq806x/R7800 Run-tested: ipq806x/R7800 No dmesg regressions, everything functional Signed-off-by: John Audia <graysky@archlinux.us> [remove accidental whitespace edit] Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
		
			
				
	
	
		
			447 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			447 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 126e6f022c749ac1bf3a607269a106ccd87d0594 Mon Sep 17 00:00:00 2001
 | |
| From: Claudiu Manoil <claudiu.manoil@nxp.com>
 | |
| Date: Mon, 12 Aug 2019 20:26:42 +0300
 | |
| Subject: [PATCH] enetc: Make MDIO accessors more generic and export to
 | |
|  include/linux/fsl
 | |
| 
 | |
| Within the LS1028A SoC, the register map for the ENETC MDIO controller
 | |
| is instantiated a few times: for the central (external) MDIO controller,
 | |
| for the internal bus of each standalone ENETC port, and for the internal
 | |
| bus of the Felix switch.
 | |
| 
 | |
| Refactoring is needed to support multiple MDIO buses from multiple
 | |
| drivers. The enetc_hw structure is made an opaque type and a smaller
 | |
| enetc_mdio_priv is created.
 | |
| 
 | |
| 'mdio_base' - MDIO registers base address - is being parameterized, to
 | |
| be able to work with different MDIO register bases.
 | |
| 
 | |
| The ENETC MDIO bus operations are exported from the fsl-enetc-mdio
 | |
| kernel object, the same that registers the central MDIO controller (the
 | |
| dedicated PF). The ENETC main driver has been changed to select it, and
 | |
| use its exported helpers to further register its private MDIO bus. The
 | |
| DSA Felix driver will do the same.
 | |
| 
 | |
| Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
 | |
| Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
 | |
| 
 | |
| Conflicts:
 | |
| 	drivers/net/ethernet/freescale/enetc/enetc_mdio.c
 | |
| 	drivers/net/ethernet/freescale/enetc/enetc_mdio.h
 | |
| 	drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c
 | |
| 	drivers/net/ethernet/freescale/enetc/enetc_pf.c
 | |
| 	drivers/net/ethernet/freescale/enetc/enetc_pf.h
 | |
| 
 | |
| mostly with the previous (downstream version of this commit) patch
 | |
| 572ee5d842da ("enetc: Make mdio accessors more generic"), which couldn't
 | |
| be reverted cleanly due to the existing downstream workaround for the
 | |
| MDIO erratum.
 | |
| ---
 | |
|  drivers/net/ethernet/freescale/enetc/Kconfig       |  1 +
 | |
|  drivers/net/ethernet/freescale/enetc/Makefile      |  2 +-
 | |
|  drivers/net/ethernet/freescale/enetc/enetc_mdio.c  | 76 ++++------------------
 | |
|  drivers/net/ethernet/freescale/enetc/enetc_mdio.h  | 12 ----
 | |
|  .../net/ethernet/freescale/enetc/enetc_pci_mdio.c  | 41 +++++++-----
 | |
|  drivers/net/ethernet/freescale/enetc/enetc_pf.c    | 71 ++++++++++++++++++++
 | |
|  drivers/net/ethernet/freescale/enetc/enetc_pf.h    |  5 --
 | |
|  include/linux/fsl/enetc_mdio.h                     | 55 ++++++++++++++++
 | |
|  8 files changed, 163 insertions(+), 100 deletions(-)
 | |
|  delete mode 100644 drivers/net/ethernet/freescale/enetc/enetc_mdio.h
 | |
|  create mode 100644 include/linux/fsl/enetc_mdio.h
 | |
| 
 | |
| --- a/drivers/net/ethernet/freescale/enetc/Kconfig
 | |
| +++ b/drivers/net/ethernet/freescale/enetc/Kconfig
 | |
| @@ -2,6 +2,7 @@
 | |
|  config FSL_ENETC
 | |
|  	tristate "ENETC PF driver"
 | |
|  	depends on PCI && PCI_MSI && (ARCH_LAYERSCAPE || COMPILE_TEST)
 | |
| +	select FSL_ENETC_MDIO
 | |
|  	select PHYLIB
 | |
|  	help
 | |
|  	  This driver supports NXP ENETC gigabit ethernet controller PCIe
 | |
| --- a/drivers/net/ethernet/freescale/enetc/Makefile
 | |
| +++ b/drivers/net/ethernet/freescale/enetc/Makefile
 | |
| @@ -3,7 +3,7 @@
 | |
|  common-objs := enetc.o enetc_cbdr.o enetc_ethtool.o
 | |
|  
 | |
|  obj-$(CONFIG_FSL_ENETC) += fsl-enetc.o
 | |
| -fsl-enetc-y := enetc_pf.o enetc_mdio.o $(common-objs)
 | |
| +fsl-enetc-y := enetc_pf.o $(common-objs)
 | |
|  fsl-enetc-$(CONFIG_PCI_IOV) += enetc_msg.o
 | |
|  fsl-enetc-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o
 | |
|  fsl-enetc-$(CONFIG_ENETC_TSN) += enetc_tsn.o
 | |
| --- a/drivers/net/ethernet/freescale/enetc/enetc_mdio.c
 | |
| +++ b/drivers/net/ethernet/freescale/enetc/enetc_mdio.c
 | |
| @@ -1,13 +1,13 @@
 | |
|  // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 | |
|  /* Copyright 2019 NXP */
 | |
|  
 | |
| +#include <linux/fsl/enetc_mdio.h>
 | |
|  #include <linux/mdio.h>
 | |
|  #include <linux/of_mdio.h>
 | |
|  #include <linux/iopoll.h>
 | |
|  #include <linux/of.h>
 | |
|  
 | |
|  #include "enetc_pf.h"
 | |
| -#include "enetc_mdio.h"
 | |
|  
 | |
|  #define	ENETC_MDIO_CFG	0x0	/* MDIO configuration and status */
 | |
|  #define	ENETC_MDIO_CTL	0x4	/* MDIO control */
 | |
| @@ -99,6 +99,7 @@ int enetc_mdio_write(struct mii_bus *bus
 | |
|  
 | |
|  	return 0;
 | |
|  }
 | |
| +EXPORT_SYMBOL_GPL(enetc_mdio_write);
 | |
|  
 | |
|  int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
 | |
|  {
 | |
| @@ -154,73 +155,18 @@ int enetc_mdio_read(struct mii_bus *bus,
 | |
|  
 | |
|  	return value;
 | |
|  }
 | |
| +EXPORT_SYMBOL_GPL(enetc_mdio_read);
 | |
|  
 | |
| -int enetc_mdio_probe(struct enetc_pf *pf)
 | |
| +struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs)
 | |
|  {
 | |
| -	struct device *dev = &pf->si->pdev->dev;
 | |
| -	struct enetc_mdio_priv *mdio_priv;
 | |
| -	struct device_node *np;
 | |
| -	struct mii_bus *bus;
 | |
| -	int err;
 | |
| -
 | |
| -	bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
 | |
| -	if (!bus)
 | |
| -		return -ENOMEM;
 | |
| -
 | |
| -	bus->name = "Freescale ENETC MDIO Bus";
 | |
| -	bus->read = enetc_mdio_read;
 | |
| -	bus->write = enetc_mdio_write;
 | |
| -	bus->parent = dev;
 | |
| -	mdio_priv = bus->priv;
 | |
| -	mdio_priv->hw = &pf->si->hw;
 | |
| -	mdio_priv->mdio_base = ENETC_EMDIO_BASE;
 | |
| -	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
 | |
| -
 | |
| -	np = of_get_child_by_name(dev->of_node, "mdio");
 | |
| -	if (!np) {
 | |
| -		dev_err(dev, "MDIO node missing\n");
 | |
| -		return -EINVAL;
 | |
| -	}
 | |
| -
 | |
| -	err = of_mdiobus_register(bus, np);
 | |
| -	if (err) {
 | |
| -		of_node_put(np);
 | |
| -		dev_err(dev, "cannot register MDIO bus\n");
 | |
| -		return err;
 | |
| -	}
 | |
| -
 | |
| -	of_node_put(np);
 | |
| -	pf->mdio = bus;
 | |
| -
 | |
| -	return 0;
 | |
| -}
 | |
| +	struct enetc_hw *hw;
 | |
|  
 | |
| -void enetc_mdio_remove(struct enetc_pf *pf)
 | |
| -{
 | |
| -	if (pf->mdio)
 | |
| -		mdiobus_unregister(pf->mdio);
 | |
| -}
 | |
| -
 | |
| -int enetc_imdio_init(struct enetc_pf *pf)
 | |
| -{
 | |
| -	struct device *dev = &pf->si->pdev->dev;
 | |
| -	struct enetc_mdio_priv *mdio_priv;
 | |
| -	struct mii_bus *bus;
 | |
| +	hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
 | |
| +	if (!hw)
 | |
| +		return ERR_PTR(-ENOMEM);
 | |
|  
 | |
| -	bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
 | |
| -	if (!bus)
 | |
| -		return -ENOMEM;
 | |
| +	hw->port = port_regs;
 | |
|  
 | |
| -	bus->name = "FSL ENETC internal MDIO Bus";
 | |
| -	bus->read = enetc_mdio_read;
 | |
| -	bus->write = enetc_mdio_write;
 | |
| -	bus->parent = dev;
 | |
| -	mdio_priv = bus->priv;
 | |
| -	mdio_priv->hw = &pf->si->hw;
 | |
| -	mdio_priv->mdio_base = ENETC_PM_IMDIO_BASE;
 | |
| -	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
 | |
| -
 | |
| -	pf->imdio = bus;
 | |
| -
 | |
| -	return 0;
 | |
| +	return hw;
 | |
|  }
 | |
| +EXPORT_SYMBOL_GPL(enetc_hw_alloc);
 | |
| --- a/drivers/net/ethernet/freescale/enetc/enetc_mdio.h
 | |
| +++ /dev/null
 | |
| @@ -1,12 +0,0 @@
 | |
| -/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
 | |
| -/* Copyright 2019 NXP */
 | |
| -
 | |
| -#include <linux/phy.h>
 | |
| -
 | |
| -struct enetc_mdio_priv {
 | |
| -	struct enetc_hw *hw;
 | |
| -	int mdio_base;
 | |
| -};
 | |
| -
 | |
| -int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value);
 | |
| -int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum);
 | |
| --- a/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c
 | |
| +++ b/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c
 | |
| @@ -1,8 +1,8 @@
 | |
|  // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 | |
|  /* Copyright 2019 NXP */
 | |
| +#include <linux/fsl/enetc_mdio.h>
 | |
|  #include <linux/of_mdio.h>
 | |
|  #include "enetc_pf.h"
 | |
| -#include "enetc_mdio.h"
 | |
|  
 | |
|  #define ENETC_MDIO_DEV_ID	0xee01
 | |
|  #define ENETC_MDIO_DEV_NAME	"FSL PCIe IE Central MDIO"
 | |
| @@ -14,17 +14,29 @@ static int enetc_pci_mdio_probe(struct p
 | |
|  {
 | |
|  	struct enetc_mdio_priv *mdio_priv;
 | |
|  	struct device *dev = &pdev->dev;
 | |
| +	void __iomem *port_regs;
 | |
|  	struct enetc_hw *hw;
 | |
|  	struct mii_bus *bus;
 | |
|  	int err;
 | |
|  
 | |
| -	hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
 | |
| -	if (!hw)
 | |
| -		return -ENOMEM;
 | |
| +	port_regs = pci_iomap(pdev, 0, 0);
 | |
| +	if (!port_regs) {
 | |
| +		dev_err(dev, "iomap failed\n");
 | |
| +		err = -ENXIO;
 | |
| +		goto err_ioremap;
 | |
| +	}
 | |
| +
 | |
| +	hw = enetc_hw_alloc(dev, port_regs);
 | |
| +	if (IS_ERR(enetc_hw_alloc)) {
 | |
| +		err = PTR_ERR(hw);
 | |
| +		goto err_hw_alloc;
 | |
| +	}
 | |
|  
 | |
|  	bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
 | |
| -	if (!bus)
 | |
| -		return -ENOMEM;
 | |
| +	if (!bus) {
 | |
| +		err = -ENOMEM;
 | |
| +		goto err_mdiobus_alloc;
 | |
| +	}
 | |
|  
 | |
|  	bus->name = ENETC_MDIO_BUS_NAME;
 | |
|  	bus->read = enetc_mdio_read;
 | |
| @@ -39,7 +51,7 @@ static int enetc_pci_mdio_probe(struct p
 | |
|  	err = pci_enable_device_mem(pdev);
 | |
|  	if (err) {
 | |
|  		dev_err(dev, "device enable failed\n");
 | |
| -		return err;
 | |
| +		goto err_pci_enable;
 | |
|  	}
 | |
|  
 | |
|  	err = pci_request_region(pdev, 0, KBUILD_MODNAME);
 | |
| @@ -48,13 +60,6 @@ static int enetc_pci_mdio_probe(struct p
 | |
|  		goto err_pci_mem_reg;
 | |
|  	}
 | |
|  
 | |
| -	hw->port = pci_iomap(pdev, 0, 0);
 | |
| -	if (!hw->port) {
 | |
| -		err = -ENXIO;
 | |
| -		dev_err(dev, "iomap failed\n");
 | |
| -		goto err_ioremap;
 | |
| -	}
 | |
| -
 | |
|  	err = of_mdiobus_register(bus, dev->of_node);
 | |
|  	if (err)
 | |
|  		goto err_mdiobus_reg;
 | |
| @@ -64,12 +69,14 @@ static int enetc_pci_mdio_probe(struct p
 | |
|  	return 0;
 | |
|  
 | |
|  err_mdiobus_reg:
 | |
| -	iounmap(mdio_priv->hw->port);
 | |
| -err_ioremap:
 | |
|  	pci_release_mem_regions(pdev);
 | |
|  err_pci_mem_reg:
 | |
|  	pci_disable_device(pdev);
 | |
| -
 | |
| +err_pci_enable:
 | |
| +err_mdiobus_alloc:
 | |
| +	iounmap(port_regs);
 | |
| +err_hw_alloc:
 | |
| +err_ioremap:
 | |
|  	return err;
 | |
|  }
 | |
|  
 | |
| --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
 | |
| +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
 | |
| @@ -2,6 +2,7 @@
 | |
|  /* Copyright 2017-2019 NXP */
 | |
|  
 | |
|  #include <linux/module.h>
 | |
| +#include <linux/fsl/enetc_mdio.h>
 | |
|  #include <linux/of_mdio.h>
 | |
|  #include <linux/of_net.h>
 | |
|  #include "enetc_pf.h"
 | |
| @@ -760,6 +761,52 @@ static void enetc_pf_netdev_setup(struct
 | |
|  	enetc_get_primary_mac_addr(&si->hw, ndev->dev_addr);
 | |
|  }
 | |
|  
 | |
| +static int enetc_mdio_probe(struct enetc_pf *pf)
 | |
| +{
 | |
| +	struct device *dev = &pf->si->pdev->dev;
 | |
| +	struct enetc_mdio_priv *mdio_priv;
 | |
| +	struct device_node *np;
 | |
| +	struct mii_bus *bus;
 | |
| +	int err;
 | |
| +
 | |
| +	bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
 | |
| +	if (!bus)
 | |
| +		return -ENOMEM;
 | |
| +
 | |
| +	bus->name = "Freescale ENETC MDIO Bus";
 | |
| +	bus->read = enetc_mdio_read;
 | |
| +	bus->write = enetc_mdio_write;
 | |
| +	bus->parent = dev;
 | |
| +	mdio_priv = bus->priv;
 | |
| +	mdio_priv->hw = &pf->si->hw;
 | |
| +	mdio_priv->mdio_base = ENETC_EMDIO_BASE;
 | |
| +	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
 | |
| +
 | |
| +	np = of_get_child_by_name(dev->of_node, "mdio");
 | |
| +	if (!np) {
 | |
| +		dev_err(dev, "MDIO node missing\n");
 | |
| +		return -EINVAL;
 | |
| +	}
 | |
| +
 | |
| +	err = of_mdiobus_register(bus, np);
 | |
| +	if (err) {
 | |
| +		of_node_put(np);
 | |
| +		dev_err(dev, "cannot register MDIO bus\n");
 | |
| +		return err;
 | |
| +	}
 | |
| +
 | |
| +	of_node_put(np);
 | |
| +	pf->mdio = bus;
 | |
| +
 | |
| +	return 0;
 | |
| +}
 | |
| +
 | |
| +static void enetc_mdio_remove(struct enetc_pf *pf)
 | |
| +{
 | |
| +	if (pf->mdio)
 | |
| +		mdiobus_unregister(pf->mdio);
 | |
| +}
 | |
| +
 | |
|  static int enetc_of_get_phy(struct enetc_pf *pf)
 | |
|  {
 | |
|  	struct device *dev = &pf->si->pdev->dev;
 | |
| @@ -911,6 +958,30 @@ static void enetc_configure_sxgmii(struc
 | |
|  		     ENETC_PCS_CR_LANE_RESET | ENETC_PCS_CR_RESET_AN);
 | |
|  }
 | |
|  
 | |
| +static int enetc_imdio_init(struct enetc_pf *pf)
 | |
| +{
 | |
| +	struct device *dev = &pf->si->pdev->dev;
 | |
| +	struct enetc_mdio_priv *mdio_priv;
 | |
| +	struct mii_bus *bus;
 | |
| +
 | |
| +	bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
 | |
| +	if (!bus)
 | |
| +		return -ENOMEM;
 | |
| +
 | |
| +	bus->name = "FSL ENETC internal MDIO Bus";
 | |
| +	bus->read = enetc_mdio_read;
 | |
| +	bus->write = enetc_mdio_write;
 | |
| +	bus->parent = dev;
 | |
| +	mdio_priv = bus->priv;
 | |
| +	mdio_priv->hw = &pf->si->hw;
 | |
| +	mdio_priv->mdio_base = ENETC_PM_IMDIO_BASE;
 | |
| +	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
 | |
| +
 | |
| +	pf->imdio = bus;
 | |
| +
 | |
| +	return 0;
 | |
| +}
 | |
| +
 | |
|  static int enetc_configure_serdes(struct enetc_ndev_priv *priv)
 | |
|  {
 | |
|  	struct enetc_pf *pf = enetc_si_priv(priv->si);
 | |
| --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
 | |
| +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
 | |
| @@ -53,8 +53,3 @@ struct enetc_pf {
 | |
|  int enetc_msg_psi_init(struct enetc_pf *pf);
 | |
|  void enetc_msg_psi_free(struct enetc_pf *pf);
 | |
|  void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int mbox_id, u16 *status);
 | |
| -
 | |
| -/* MDIO */
 | |
| -int enetc_mdio_probe(struct enetc_pf *pf);
 | |
| -void enetc_mdio_remove(struct enetc_pf *pf);
 | |
| -int enetc_imdio_init(struct enetc_pf *pf);
 | |
| --- /dev/null
 | |
| +++ b/include/linux/fsl/enetc_mdio.h
 | |
| @@ -0,0 +1,55 @@
 | |
| +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
 | |
| +/* Copyright 2019 NXP */
 | |
| +
 | |
| +#ifndef _FSL_ENETC_MDIO_H_
 | |
| +#define _FSL_ENETC_MDIO_H_
 | |
| +
 | |
| +#include <linux/phy.h>
 | |
| +
 | |
| +/* PCS registers */
 | |
| +#define ENETC_PCS_LINK_TIMER1			0x12
 | |
| +#define ENETC_PCS_LINK_TIMER1_VAL		0x06a0
 | |
| +#define ENETC_PCS_LINK_TIMER2			0x13
 | |
| +#define ENETC_PCS_LINK_TIMER2_VAL		0x0003
 | |
| +#define ENETC_PCS_IF_MODE			0x14
 | |
| +#define ENETC_PCS_IF_MODE_SGMII_EN		BIT(0)
 | |
| +#define ENETC_PCS_IF_MODE_USE_SGMII_AN		BIT(1)
 | |
| +#define ENETC_PCS_IF_MODE_SGMII_SPEED(x)	(((x) << 2) & GENMASK(3, 2))
 | |
| +
 | |
| +/* Not a mistake, the SerDes PLL needs to be set at 3.125 GHz by Reset
 | |
| + * Configuration Word (RCW, outside Linux control) for 2.5G SGMII mode. The PCS
 | |
| + * still thinks it's at gigabit.
 | |
| + */
 | |
| +enum enetc_pcs_speed {
 | |
| +	ENETC_PCS_SPEED_10	= 0,
 | |
| +	ENETC_PCS_SPEED_100	= 1,
 | |
| +	ENETC_PCS_SPEED_1000	= 2,
 | |
| +	ENETC_PCS_SPEED_2500	= 2,
 | |
| +};
 | |
| +
 | |
| +struct enetc_hw;
 | |
| +
 | |
| +struct enetc_mdio_priv {
 | |
| +	struct enetc_hw *hw;
 | |
| +	int mdio_base;
 | |
| +};
 | |
| +
 | |
| +#if IS_REACHABLE(CONFIG_FSL_ENETC_MDIO)
 | |
| +
 | |
| +int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum);
 | |
| +int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value);
 | |
| +struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs);
 | |
| +
 | |
| +#else
 | |
| +
 | |
| +static inline int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
 | |
| +{ return -EINVAL; }
 | |
| +static inline int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum,
 | |
| +				   u16 value)
 | |
| +{ return -EINVAL; }
 | |
| +struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs)
 | |
| +{ return ERR_PTR(-EINVAL); }
 | |
| +
 | |
| +#endif
 | |
| +
 | |
| +#endif
 |