1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2009-2015 Cavium, Inc.
6 #include <linux/platform_device.h>
7 #include <linux/of_address.h>
8 #include <linux/of_mdio.h>
9 #include <linux/module.h>
10 #include <linux/gfp.h>
11 #include <linux/phy.h>
14 #include "mdio-cavium.h"
16 static int octeon_mdiobus_probe(struct platform_device
*pdev
)
18 struct cavium_mdiobus
*bus
;
19 struct mii_bus
*mii_bus
;
20 struct resource
*res_mem
;
21 resource_size_t mdio_phys
;
22 resource_size_t regsize
;
23 union cvmx_smix_en smi_en
;
26 mii_bus
= devm_mdiobus_alloc_size(&pdev
->dev
, sizeof(*bus
));
30 res_mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
31 if (res_mem
== NULL
) {
32 dev_err(&pdev
->dev
, "found no memory resource\n");
37 bus
->mii_bus
= mii_bus
;
38 mdio_phys
= res_mem
->start
;
39 regsize
= resource_size(res_mem
);
41 if (!devm_request_mem_region(&pdev
->dev
, mdio_phys
, regsize
,
43 dev_err(&pdev
->dev
, "request_mem_region failed\n");
48 (u64
)devm_ioremap(&pdev
->dev
, mdio_phys
, regsize
);
49 if (!bus
->register_base
) {
50 dev_err(&pdev
->dev
, "dev_ioremap failed\n");
56 oct_mdio_writeq(smi_en
.u64
, bus
->register_base
+ SMI_EN
);
58 bus
->mii_bus
->name
= KBUILD_MODNAME
;
59 snprintf(bus
->mii_bus
->id
, MII_BUS_ID_SIZE
, "%llx", bus
->register_base
);
60 bus
->mii_bus
->parent
= &pdev
->dev
;
62 bus
->mii_bus
->read
= cavium_mdiobus_read
;
63 bus
->mii_bus
->write
= cavium_mdiobus_write
;
65 platform_set_drvdata(pdev
, bus
);
67 err
= of_mdiobus_register(bus
->mii_bus
, pdev
->dev
.of_node
);
71 dev_info(&pdev
->dev
, "Probed\n");
75 mdiobus_free(bus
->mii_bus
);
77 oct_mdio_writeq(smi_en
.u64
, bus
->register_base
+ SMI_EN
);
81 static int octeon_mdiobus_remove(struct platform_device
*pdev
)
83 struct cavium_mdiobus
*bus
;
84 union cvmx_smix_en smi_en
;
86 bus
= platform_get_drvdata(pdev
);
88 mdiobus_unregister(bus
->mii_bus
);
89 mdiobus_free(bus
->mii_bus
);
91 oct_mdio_writeq(smi_en
.u64
, bus
->register_base
+ SMI_EN
);
95 static const struct of_device_id octeon_mdiobus_match
[] = {
97 .compatible
= "cavium,octeon-3860-mdio",
101 MODULE_DEVICE_TABLE(of
, octeon_mdiobus_match
);
103 static struct platform_driver octeon_mdiobus_driver
= {
105 .name
= KBUILD_MODNAME
,
106 .of_match_table
= octeon_mdiobus_match
,
108 .probe
= octeon_mdiobus_probe
,
109 .remove
= octeon_mdiobus_remove
,
112 void octeon_mdiobus_force_mod_depencency(void)
114 /* Let ethernet drivers force us to be loaded. */
116 EXPORT_SYMBOL(octeon_mdiobus_force_mod_depencency
);
118 module_platform_driver(octeon_mdiobus_driver
);
120 MODULE_DESCRIPTION("Cavium OCTEON MDIO bus driver");
121 MODULE_AUTHOR("David Daney");
122 MODULE_LICENSE("GPL v2");