2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (C) 2009-2015 Cavium, Inc.
9 #include <linux/platform_device.h>
10 #include <linux/of_address.h>
11 #include <linux/of_mdio.h>
12 #include <linux/module.h>
13 #include <linux/gfp.h>
14 #include <linux/phy.h>
17 #include "mdio-cavium.h"
19 static int octeon_mdiobus_probe(struct platform_device
*pdev
)
21 struct cavium_mdiobus
*bus
;
22 struct mii_bus
*mii_bus
;
23 struct resource
*res_mem
;
24 resource_size_t mdio_phys
;
25 resource_size_t regsize
;
26 union cvmx_smix_en smi_en
;
29 mii_bus
= devm_mdiobus_alloc_size(&pdev
->dev
, sizeof(*bus
));
33 res_mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
34 if (res_mem
== NULL
) {
35 dev_err(&pdev
->dev
, "found no memory resource\n");
40 bus
->mii_bus
= mii_bus
;
41 mdio_phys
= res_mem
->start
;
42 regsize
= resource_size(res_mem
);
44 if (!devm_request_mem_region(&pdev
->dev
, mdio_phys
, regsize
,
46 dev_err(&pdev
->dev
, "request_mem_region failed\n");
51 (u64
)devm_ioremap(&pdev
->dev
, mdio_phys
, regsize
);
52 if (!bus
->register_base
) {
53 dev_err(&pdev
->dev
, "dev_ioremap failed\n");
59 oct_mdio_writeq(smi_en
.u64
, bus
->register_base
+ SMI_EN
);
61 bus
->mii_bus
->name
= KBUILD_MODNAME
;
62 snprintf(bus
->mii_bus
->id
, MII_BUS_ID_SIZE
, "%llx", bus
->register_base
);
63 bus
->mii_bus
->parent
= &pdev
->dev
;
65 bus
->mii_bus
->read
= cavium_mdiobus_read
;
66 bus
->mii_bus
->write
= cavium_mdiobus_write
;
68 platform_set_drvdata(pdev
, bus
);
70 err
= of_mdiobus_register(bus
->mii_bus
, pdev
->dev
.of_node
);
74 dev_info(&pdev
->dev
, "Probed\n");
78 mdiobus_free(bus
->mii_bus
);
80 oct_mdio_writeq(smi_en
.u64
, bus
->register_base
+ SMI_EN
);
84 static int octeon_mdiobus_remove(struct platform_device
*pdev
)
86 struct cavium_mdiobus
*bus
;
87 union cvmx_smix_en smi_en
;
89 bus
= platform_get_drvdata(pdev
);
91 mdiobus_unregister(bus
->mii_bus
);
92 mdiobus_free(bus
->mii_bus
);
94 oct_mdio_writeq(smi_en
.u64
, bus
->register_base
+ SMI_EN
);
98 static const struct of_device_id octeon_mdiobus_match
[] = {
100 .compatible
= "cavium,octeon-3860-mdio",
104 MODULE_DEVICE_TABLE(of
, octeon_mdiobus_match
);
106 static struct platform_driver octeon_mdiobus_driver
= {
108 .name
= KBUILD_MODNAME
,
109 .of_match_table
= octeon_mdiobus_match
,
111 .probe
= octeon_mdiobus_probe
,
112 .remove
= octeon_mdiobus_remove
,
115 void octeon_mdiobus_force_mod_depencency(void)
117 /* Let ethernet drivers force us to be loaded. */
119 EXPORT_SYMBOL(octeon_mdiobus_force_mod_depencency
);
121 module_platform_driver(octeon_mdiobus_driver
);
123 MODULE_DESCRIPTION("Cavium OCTEON MDIO bus driver");
124 MODULE_AUTHOR("David Daney");
125 MODULE_LICENSE("GPL");