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