// 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"

#define ENETC_MDIO_DEV_ID	0xee01
#define ENETC_MDIO_DEV_NAME	"FSL PCIe IE Central MDIO"
#define ENETC_MDIO_BUS_NAME	ENETC_MDIO_DEV_NAME " Bus"
#define ENETC_MDIO_DRV_NAME	ENETC_MDIO_DEV_NAME " driver"

static int enetc_pci_mdio_probe(struct pci_dev *pdev,
				const struct pci_device_id *ent)
{
	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;

	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(hw)) {
		err = PTR_ERR(hw);
		goto err_hw_alloc;
	}

	bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
	if (!bus) {
		err = -ENOMEM;
		goto err_mdiobus_alloc;
	}

	bus->name = ENETC_MDIO_BUS_NAME;
	bus->read = enetc_mdio_read;
	bus->write = enetc_mdio_write;
	bus->parent = dev;
	mdio_priv = bus->priv;
	mdio_priv->hw = hw;
	mdio_priv->mdio_base = ENETC_EMDIO_BASE;
	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));

	pcie_flr(pdev);
	err = pci_enable_device_mem(pdev);
	if (err) {
		dev_err(dev, "device enable failed\n");
		goto err_pci_enable;
	}

	err = pci_request_region(pdev, 0, KBUILD_MODNAME);
	if (err) {
		dev_err(dev, "pci_request_region failed\n");
		goto err_pci_mem_reg;
	}

	err = of_mdiobus_register(bus, dev->of_node);
	if (err)
		goto err_mdiobus_reg;

	pci_set_drvdata(pdev, bus);

	return 0;

err_mdiobus_reg:
	pci_release_mem_regions(pdev);
err_pci_mem_reg:
	pci_disable_device(pdev);
err_pci_enable:
err_mdiobus_alloc:
err_hw_alloc:
	iounmap(port_regs);
err_ioremap:
	return err;
}

static void enetc_pci_mdio_remove(struct pci_dev *pdev)
{
	struct mii_bus *bus = pci_get_drvdata(pdev);
	struct enetc_mdio_priv *mdio_priv;

	mdiobus_unregister(bus);
	mdio_priv = bus->priv;
	iounmap(mdio_priv->hw->port);
	pci_release_mem_regions(pdev);
	pci_disable_device(pdev);
}

static const struct pci_device_id enetc_pci_mdio_id_table[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_MDIO_DEV_ID) },
	{ 0, } /* End of table. */
};
MODULE_DEVICE_TABLE(pci, enetc_pci_mdio_id_table);

static struct pci_driver enetc_pci_mdio_driver = {
	.name = KBUILD_MODNAME,
	.id_table = enetc_pci_mdio_id_table,
	.probe = enetc_pci_mdio_probe,
	.remove = enetc_pci_mdio_remove,
};
module_pci_driver(enetc_pci_mdio_driver);

MODULE_DESCRIPTION(ENETC_MDIO_DRV_NAME);
MODULE_LICENSE("Dual BSD/GPL");
