1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 /* Copyright 2019 NXP */ 3 #include <linux/fsl/enetc_mdio.h> 4 #include <linux/of_mdio.h> 5 #include "enetc_pf.h" 6 7 #define ENETC_MDIO_DEV_ID 0xee01 8 #define ENETC_MDIO_DEV_NAME "FSL PCIe IE Central MDIO" 9 #define ENETC_MDIO_BUS_NAME ENETC_MDIO_DEV_NAME " Bus" 10 #define ENETC_MDIO_DRV_NAME ENETC_MDIO_DEV_NAME " driver" 11 12 static int enetc_pci_mdio_probe(struct pci_dev *pdev, 13 const struct pci_device_id *ent) 14 { 15 struct enetc_mdio_priv *mdio_priv; 16 struct device *dev = &pdev->dev; 17 void __iomem *port_regs; 18 struct enetc_hw *hw; 19 struct mii_bus *bus; 20 int err; 21 22 port_regs = pci_iomap(pdev, 0, 0); 23 if (!port_regs) { 24 dev_err(dev, "iomap failed\n"); 25 err = -ENXIO; 26 goto err_ioremap; 27 } 28 29 hw = enetc_hw_alloc(dev, port_regs); 30 if (IS_ERR(hw)) { 31 err = PTR_ERR(hw); 32 goto err_hw_alloc; 33 } 34 35 bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv)); 36 if (!bus) { 37 err = -ENOMEM; 38 goto err_mdiobus_alloc; 39 } 40 41 bus->name = ENETC_MDIO_BUS_NAME; 42 bus->read = enetc_mdio_read_c22; 43 bus->write = enetc_mdio_write_c22; 44 bus->read_c45 = enetc_mdio_read_c45; 45 bus->write_c45 = enetc_mdio_write_c45; 46 bus->parent = dev; 47 mdio_priv = bus->priv; 48 mdio_priv->hw = hw; 49 mdio_priv->mdio_base = ENETC_EMDIO_BASE; 50 snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev)); 51 52 pcie_flr(pdev); 53 err = pci_enable_device_mem(pdev); 54 if (err) { 55 dev_err(dev, "device enable failed\n"); 56 goto err_pci_enable; 57 } 58 59 err = pci_request_region(pdev, 0, KBUILD_MODNAME); 60 if (err) { 61 dev_err(dev, "pci_request_region failed\n"); 62 goto err_pci_mem_reg; 63 } 64 65 err = of_mdiobus_register(bus, dev->of_node); 66 if (err) 67 goto err_mdiobus_reg; 68 69 pci_set_drvdata(pdev, bus); 70 71 return 0; 72 73 err_mdiobus_reg: 74 pci_release_region(pdev, 0); 75 err_pci_mem_reg: 76 pci_disable_device(pdev); 77 err_pci_enable: 78 err_mdiobus_alloc: 79 err_hw_alloc: 80 iounmap(port_regs); 81 err_ioremap: 82 return err; 83 } 84 85 static void enetc_pci_mdio_remove(struct pci_dev *pdev) 86 { 87 struct mii_bus *bus = pci_get_drvdata(pdev); 88 struct enetc_mdio_priv *mdio_priv; 89 90 mdiobus_unregister(bus); 91 mdio_priv = bus->priv; 92 iounmap(mdio_priv->hw->port); 93 pci_release_region(pdev, 0); 94 pci_disable_device(pdev); 95 } 96 97 static const struct pci_device_id enetc_pci_mdio_id_table[] = { 98 { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_MDIO_DEV_ID) }, 99 { 0, } /* End of table. */ 100 }; 101 MODULE_DEVICE_TABLE(pci, enetc_pci_mdio_id_table); 102 103 static struct pci_driver enetc_pci_mdio_driver = { 104 .name = KBUILD_MODNAME, 105 .id_table = enetc_pci_mdio_id_table, 106 .probe = enetc_pci_mdio_probe, 107 .remove = enetc_pci_mdio_remove, 108 }; 109 module_pci_driver(enetc_pci_mdio_driver); 110 111 MODULE_DESCRIPTION(ENETC_MDIO_DRV_NAME); 112 MODULE_LICENSE("Dual BSD/GPL"); 113