linux/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c
<<
>>
Prefs
   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
  11static 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
  64err_mdiobus_reg:
  65        iounmap(mdio_priv->hw->port);
  66err_ioremap:
  67        pci_release_mem_regions(pdev);
  68err_pci_mem_reg:
  69        pci_disable_device(pdev);
  70
  71        return err;
  72}
  73
  74static 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
  86static 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};
  90MODULE_DEVICE_TABLE(pci, enetc_pci_mdio_id_table);
  91
  92static 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};
  98module_pci_driver(enetc_pci_mdio_driver);
  99
 100MODULE_DESCRIPTION(ENETC_MDIO_DRV_NAME);
 101MODULE_LICENSE("Dual BSD/GPL");
 102