]> git.ipfire.org Git - thirdparty/linux.git/blame - drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c
Merge tag 'io_uring-5.7-2020-05-22' of git://git.kernel.dk/linux-block
[thirdparty/linux.git] / drivers / net / ethernet / freescale / enetc / enetc_pci_mdio.c
CommitLineData
231ece36
CM
1// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2/* Copyright 2019 NXP */
6517798d 3#include <linux/fsl/enetc_mdio.h>
231ece36 4#include <linux/of_mdio.h>
6517798d 5#include "enetc_pf.h"
231ece36
CM
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
12static 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;
6517798d 17 void __iomem *port_regs;
231ece36
CM
18 struct enetc_hw *hw;
19 struct mii_bus *bus;
20 int err;
21
6517798d
CM
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);
4addbcb3 30 if (IS_ERR(hw)) {
6517798d
CM
31 err = PTR_ERR(hw);
32 goto err_hw_alloc;
33 }
231ece36
CM
34
35 bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
6517798d
CM
36 if (!bus) {
37 err = -ENOMEM;
38 goto err_mdiobus_alloc;
39 }
231ece36
CM
40
41 bus->name = ENETC_MDIO_BUS_NAME;
42 bus->read = enetc_mdio_read;
43 bus->write = enetc_mdio_write;
44 bus->parent = dev;
45 mdio_priv = bus->priv;
46 mdio_priv->hw = hw;
6517798d 47 mdio_priv->mdio_base = ENETC_EMDIO_BASE;
231ece36
CM
48 snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
49
50 pcie_flr(pdev);
51 err = pci_enable_device_mem(pdev);
52 if (err) {
53 dev_err(dev, "device enable failed\n");
6517798d 54 goto err_pci_enable;
231ece36
CM
55 }
56
57 err = pci_request_region(pdev, 0, KBUILD_MODNAME);
58 if (err) {
59 dev_err(dev, "pci_request_region failed\n");
60 goto err_pci_mem_reg;
61 }
62
231ece36
CM
63 err = of_mdiobus_register(bus, dev->of_node);
64 if (err)
65 goto err_mdiobus_reg;
66
67 pci_set_drvdata(pdev, bus);
68
69 return 0;
70
71err_mdiobus_reg:
231ece36
CM
72 pci_release_mem_regions(pdev);
73err_pci_mem_reg:
74 pci_disable_device(pdev);
6517798d
CM
75err_pci_enable:
76err_mdiobus_alloc:
6517798d 77err_hw_alloc:
d975cb7e 78 iounmap(port_regs);
6517798d 79err_ioremap:
231ece36
CM
80 return err;
81}
82
83static void enetc_pci_mdio_remove(struct pci_dev *pdev)
84{
85 struct mii_bus *bus = pci_get_drvdata(pdev);
86 struct enetc_mdio_priv *mdio_priv;
87
88 mdiobus_unregister(bus);
89 mdio_priv = bus->priv;
90 iounmap(mdio_priv->hw->port);
91 pci_release_mem_regions(pdev);
92 pci_disable_device(pdev);
93}
94
95static const struct pci_device_id enetc_pci_mdio_id_table[] = {
96 { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_MDIO_DEV_ID) },
97 { 0, } /* End of table. */
98};
99MODULE_DEVICE_TABLE(pci, enetc_pci_mdio_id_table);
100
101static struct pci_driver enetc_pci_mdio_driver = {
102 .name = KBUILD_MODNAME,
103 .id_table = enetc_pci_mdio_id_table,
104 .probe = enetc_pci_mdio_probe,
105 .remove = enetc_pci_mdio_remove,
106};
107module_pci_driver(enetc_pci_mdio_driver);
108
109MODULE_DESCRIPTION(ENETC_MDIO_DRV_NAME);
110MODULE_LICENSE("Dual BSD/GPL");