Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
0002 /* Copyright 2019 NXP */
0003 #include <linux/fsl/enetc_mdio.h>
0004 #include <linux/of_mdio.h>
0005 #include "enetc_pf.h"
0006 
0007 #define ENETC_MDIO_DEV_ID   0xee01
0008 #define ENETC_MDIO_DEV_NAME "FSL PCIe IE Central MDIO"
0009 #define ENETC_MDIO_BUS_NAME ENETC_MDIO_DEV_NAME " Bus"
0010 #define ENETC_MDIO_DRV_NAME ENETC_MDIO_DEV_NAME " driver"
0011 
0012 static int enetc_pci_mdio_probe(struct pci_dev *pdev,
0013                 const struct pci_device_id *ent)
0014 {
0015     struct enetc_mdio_priv *mdio_priv;
0016     struct device *dev = &pdev->dev;
0017     void __iomem *port_regs;
0018     struct enetc_hw *hw;
0019     struct mii_bus *bus;
0020     int err;
0021 
0022     port_regs = pci_iomap(pdev, 0, 0);
0023     if (!port_regs) {
0024         dev_err(dev, "iomap failed\n");
0025         err = -ENXIO;
0026         goto err_ioremap;
0027     }
0028 
0029     hw = enetc_hw_alloc(dev, port_regs);
0030     if (IS_ERR(hw)) {
0031         err = PTR_ERR(hw);
0032         goto err_hw_alloc;
0033     }
0034 
0035     bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
0036     if (!bus) {
0037         err = -ENOMEM;
0038         goto err_mdiobus_alloc;
0039     }
0040 
0041     bus->name = ENETC_MDIO_BUS_NAME;
0042     bus->read = enetc_mdio_read;
0043     bus->write = enetc_mdio_write;
0044     bus->parent = dev;
0045     mdio_priv = bus->priv;
0046     mdio_priv->hw = hw;
0047     mdio_priv->mdio_base = ENETC_EMDIO_BASE;
0048     snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
0049 
0050     pcie_flr(pdev);
0051     err = pci_enable_device_mem(pdev);
0052     if (err) {
0053         dev_err(dev, "device enable failed\n");
0054         goto err_pci_enable;
0055     }
0056 
0057     err = pci_request_region(pdev, 0, KBUILD_MODNAME);
0058     if (err) {
0059         dev_err(dev, "pci_request_region failed\n");
0060         goto err_pci_mem_reg;
0061     }
0062 
0063     err = of_mdiobus_register(bus, dev->of_node);
0064     if (err)
0065         goto err_mdiobus_reg;
0066 
0067     pci_set_drvdata(pdev, bus);
0068 
0069     return 0;
0070 
0071 err_mdiobus_reg:
0072     pci_release_region(pdev, 0);
0073 err_pci_mem_reg:
0074     pci_disable_device(pdev);
0075 err_pci_enable:
0076 err_mdiobus_alloc:
0077 err_hw_alloc:
0078     iounmap(port_regs);
0079 err_ioremap:
0080     return err;
0081 }
0082 
0083 static void enetc_pci_mdio_remove(struct pci_dev *pdev)
0084 {
0085     struct mii_bus *bus = pci_get_drvdata(pdev);
0086     struct enetc_mdio_priv *mdio_priv;
0087 
0088     mdiobus_unregister(bus);
0089     mdio_priv = bus->priv;
0090     iounmap(mdio_priv->hw->port);
0091     pci_release_region(pdev, 0);
0092     pci_disable_device(pdev);
0093 }
0094 
0095 static const struct pci_device_id enetc_pci_mdio_id_table[] = {
0096     { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_MDIO_DEV_ID) },
0097     { 0, } /* End of table. */
0098 };
0099 MODULE_DEVICE_TABLE(pci, enetc_pci_mdio_id_table);
0100 
0101 static struct pci_driver enetc_pci_mdio_driver = {
0102     .name = KBUILD_MODNAME,
0103     .id_table = enetc_pci_mdio_id_table,
0104     .probe = enetc_pci_mdio_probe,
0105     .remove = enetc_pci_mdio_remove,
0106 };
0107 module_pci_driver(enetc_pci_mdio_driver);
0108 
0109 MODULE_DESCRIPTION(ENETC_MDIO_DRV_NAME);
0110 MODULE_LICENSE("Dual BSD/GPL");