]>
Commit | Line | Data |
---|---|---|
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 | ||
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; | |
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 | ||
71 | err_mdiobus_reg: | |
231ece36 CM |
72 | pci_release_mem_regions(pdev); |
73 | err_pci_mem_reg: | |
74 | pci_disable_device(pdev); | |
6517798d CM |
75 | err_pci_enable: |
76 | err_mdiobus_alloc: | |
6517798d | 77 | err_hw_alloc: |
d975cb7e | 78 | iounmap(port_regs); |
6517798d | 79 | err_ioremap: |
231ece36 CM |
80 | return err; |
81 | } | |
82 | ||
83 | static 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 | ||
95 | static 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 | }; | |
99 | MODULE_DEVICE_TABLE(pci, enetc_pci_mdio_id_table); | |
100 | ||
101 | static 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 | }; | |
107 | module_pci_driver(enetc_pci_mdio_driver); | |
108 | ||
109 | MODULE_DESCRIPTION(ENETC_MDIO_DRV_NAME); | |
110 | MODULE_LICENSE("Dual BSD/GPL"); |