2019-01-21 19:34:53 +01:00
// SPDX-License-Identifier: GPL-2.0
2009-10-14 12:04:38 -07:00
/*
2016-03-11 09:53:10 -08:00
* Copyright ( C ) 2009 - 2015 Cavium , Inc .
2009-10-14 12:04:38 -07:00
*/
2021-03-15 16:19:05 +05:30
# include <linux/gfp.h>
# include <linux/io.h>
# include <linux/module.h>
2015-07-28 15:12:11 -07:00
# include <linux/of_address.h>
2012-07-05 18:12:39 +02:00
# include <linux/of_mdio.h>
2009-10-14 12:04:38 -07:00
# include <linux/phy.h>
2021-03-15 16:19:05 +05:30
# include <linux/platform_device.h>
2009-10-14 12:04:38 -07:00
2016-03-11 09:53:10 -08:00
# include "mdio-cavium.h"
2009-10-14 12:04:38 -07:00
2012-12-03 09:24:14 -05:00
static int octeon_mdiobus_probe ( struct platform_device * pdev )
2009-10-14 12:04:38 -07:00
{
2016-03-11 09:53:10 -08:00
struct cavium_mdiobus * bus ;
2016-01-06 20:11:14 +01:00
struct mii_bus * mii_bus ;
2012-07-05 18:12:39 +02:00
struct resource * res_mem ;
2016-03-11 09:53:10 -08:00
resource_size_t mdio_phys ;
resource_size_t regsize ;
2010-04-01 18:17:54 -07:00
union cvmx_smix_en smi_en ;
2009-10-14 12:04:38 -07:00
int err = - ENOENT ;
2016-01-06 20:11:14 +01:00
mii_bus = devm_mdiobus_alloc_size ( & pdev - > dev , sizeof ( * bus ) ) ;
if ( ! mii_bus )
2009-10-14 12:04:38 -07:00
return - ENOMEM ;
2012-07-05 18:12:39 +02:00
res_mem = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
if ( res_mem = = NULL ) {
dev_err ( & pdev - > dev , " found no memory resource \n " ) ;
2015-07-28 15:12:12 -07:00
return - ENXIO ;
2012-07-05 18:12:39 +02:00
}
2015-07-28 15:12:12 -07:00
2016-01-06 20:11:14 +01:00
bus = mii_bus - > priv ;
bus - > mii_bus = mii_bus ;
2016-03-11 09:53:10 -08:00
mdio_phys = res_mem - > start ;
regsize = resource_size ( res_mem ) ;
2015-07-28 15:12:12 -07:00
2016-03-11 09:53:10 -08:00
if ( ! devm_request_mem_region ( & pdev - > dev , mdio_phys , regsize ,
2012-07-05 18:12:39 +02:00
res_mem - > name ) ) {
dev_err ( & pdev - > dev , " request_mem_region failed \n " ) ;
2015-07-28 15:12:12 -07:00
return - ENXIO ;
2012-07-05 18:12:39 +02:00
}
2015-07-28 15:12:12 -07:00
2020-07-07 03:49:38 +02:00
bus - > register_base = devm_ioremap ( & pdev - > dev , mdio_phys , regsize ) ;
2015-07-28 15:12:12 -07:00
if ( ! bus - > register_base ) {
dev_err ( & pdev - > dev , " dev_ioremap failed \n " ) ;
return - ENOMEM ;
}
2009-10-14 12:04:38 -07:00
2010-04-01 18:17:54 -07:00
smi_en . u64 = 0 ;
smi_en . s . en = 1 ;
2015-07-28 15:12:11 -07:00
oct_mdio_writeq ( smi_en . u64 , bus - > register_base + SMI_EN ) ;
2009-10-14 12:04:38 -07:00
2016-03-11 09:53:10 -08:00
bus - > mii_bus - > name = KBUILD_MODNAME ;
2020-07-07 03:49:38 +02:00
snprintf ( bus - > mii_bus - > id , MII_BUS_ID_SIZE , " %px " , bus - > register_base ) ;
2009-10-14 12:04:38 -07:00
bus - > mii_bus - > parent = & pdev - > dev ;
2016-03-11 09:53:10 -08:00
bus - > mii_bus - > read = cavium_mdiobus_read ;
bus - > mii_bus - > write = cavium_mdiobus_write ;
2009-10-14 12:04:38 -07:00
2013-08-21 18:15:15 +08:00
platform_set_drvdata ( pdev , bus ) ;
2009-10-14 12:04:38 -07:00
2012-07-05 18:12:39 +02:00
err = of_mdiobus_register ( bus - > mii_bus , pdev - > dev . of_node ) ;
2009-10-14 12:04:38 -07:00
if ( err )
2012-07-05 18:12:39 +02:00
goto fail_register ;
2009-10-14 12:04:38 -07:00
2016-03-11 09:53:10 -08:00
dev_info ( & pdev - > dev , " Probed \n " ) ;
2009-10-14 12:04:38 -07:00
return 0 ;
2012-07-05 18:12:39 +02:00
fail_register :
2010-04-01 18:17:54 -07:00
smi_en . u64 = 0 ;
2015-07-28 15:12:11 -07:00
oct_mdio_writeq ( smi_en . u64 , bus - > register_base + SMI_EN ) ;
2009-10-14 12:04:38 -07:00
return err ;
}
2012-12-03 09:24:14 -05:00
static int octeon_mdiobus_remove ( struct platform_device * pdev )
2009-10-14 12:04:38 -07:00
{
2016-03-11 09:53:10 -08:00
struct cavium_mdiobus * bus ;
2010-04-01 18:17:54 -07:00
union cvmx_smix_en smi_en ;
2009-10-14 12:04:38 -07:00
2013-09-02 17:10:09 +09:00
bus = platform_get_drvdata ( pdev ) ;
2009-10-14 12:04:38 -07:00
mdiobus_unregister ( bus - > mii_bus ) ;
2010-04-01 18:17:54 -07:00
smi_en . u64 = 0 ;
2015-07-28 15:12:11 -07:00
oct_mdio_writeq ( smi_en . u64 , bus - > register_base + SMI_EN ) ;
2009-10-14 12:04:38 -07:00
return 0 ;
}
2015-03-17 19:40:23 +01:00
static const struct of_device_id octeon_mdiobus_match [ ] = {
2012-07-05 18:12:39 +02:00
{
. compatible = " cavium,octeon-3860-mdio " ,
} ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , octeon_mdiobus_match ) ;
2009-10-14 12:04:38 -07:00
static struct platform_driver octeon_mdiobus_driver = {
. driver = {
2016-03-11 09:53:10 -08:00
. name = KBUILD_MODNAME ,
2012-07-05 18:12:39 +02:00
. of_match_table = octeon_mdiobus_match ,
2009-10-14 12:04:38 -07:00
} ,
. probe = octeon_mdiobus_probe ,
2012-12-03 09:24:14 -05:00
. remove = octeon_mdiobus_remove ,
2009-10-14 12:04:38 -07:00
} ;
2013-03-20 01:41:32 +00:00
module_platform_driver ( octeon_mdiobus_driver ) ;
2009-10-14 12:04:38 -07:00
2016-03-11 09:53:10 -08:00
MODULE_DESCRIPTION ( " Cavium OCTEON MDIO bus driver " ) ;
2009-10-14 12:04:38 -07:00
MODULE_AUTHOR ( " David Daney " ) ;
2019-01-21 19:34:53 +01:00
MODULE_LICENSE ( " GPL v2 " ) ;