2019-06-04 10:11:33 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2014-07-25 15:04:52 +02:00
/*
* Copyright ( C ) 2014 Linaro Ltd .
*
* Author : Linus Walleij < linus . walleij @ linaro . org >
*/
# include <linux/init.h>
# include <linux/io.h>
# include <linux/slab.h>
# include <linux/sys_soc.h>
# include <linux/platform_device.h>
# include <linux/mfd/syscon.h>
# include <linux/regmap.h>
# include <linux/of.h>
/* System ID in syscon */
# define REALVIEW_SYS_ID_OFFSET 0x00
static const struct of_device_id realview_soc_of_match [ ] = {
{ . compatible = " arm,realview-eb-soc " , } ,
{ . compatible = " arm,realview-pb1176-soc " , } ,
{ . compatible = " arm,realview-pb11mp-soc " , } ,
{ . compatible = " arm,realview-pba8-soc " , } ,
{ . compatible = " arm,realview-pbx-soc " , } ,
2014-10-19 23:41:00 +08:00
{ }
2014-07-25 15:04:52 +02:00
} ;
static u32 realview_coreid ;
static const char * realview_arch_str ( u32 id )
{
switch ( ( id > > 8 ) & 0xf ) {
2015-10-08 11:08:31 +02:00
case 0x04 :
return " AHB " ;
2014-07-25 15:04:52 +02:00
case 0x05 :
return " Multi-layer AXI " ;
default :
return " Unknown " ;
}
}
2020-05-23 18:08:52 +01:00
static ssize_t
manufacturer_show ( struct device * dev , struct device_attribute * attr , char * buf )
2014-07-25 15:04:52 +02:00
{
return sprintf ( buf , " %02x \n " , realview_coreid > > 24 ) ;
}
2020-05-23 18:08:52 +01:00
static DEVICE_ATTR_RO ( manufacturer ) ;
2014-07-25 15:04:52 +02:00
2020-05-23 18:08:52 +01:00
static ssize_t
board_show ( struct device * dev , struct device_attribute * attr , char * buf )
2014-07-25 15:04:52 +02:00
{
2016-02-18 14:21:54 +01:00
return sprintf ( buf , " HBI-%03x \n " , ( ( realview_coreid > > 16 ) & 0xfff ) ) ;
2014-07-25 15:04:52 +02:00
}
2020-05-23 18:08:52 +01:00
static DEVICE_ATTR_RO ( board ) ;
2014-07-25 15:04:52 +02:00
2020-05-23 18:08:52 +01:00
static ssize_t
fpga_show ( struct device * dev , struct device_attribute * attr , char * buf )
2014-07-25 15:04:52 +02:00
{
return sprintf ( buf , " %s \n " , realview_arch_str ( realview_coreid ) ) ;
}
2020-05-23 18:08:52 +01:00
static DEVICE_ATTR_RO ( fpga ) ;
2014-07-25 15:04:52 +02:00
2020-05-23 18:08:52 +01:00
static ssize_t
build_show ( struct device * dev , struct device_attribute * attr , char * buf )
2014-07-25 15:04:52 +02:00
{
return sprintf ( buf , " %02x \n " , ( realview_coreid & 0xFF ) ) ;
}
2020-05-23 18:08:52 +01:00
static DEVICE_ATTR_RO ( build ) ;
2014-07-25 15:04:52 +02:00
2020-05-23 18:08:53 +01:00
static struct attribute * realview_attrs [ ] = {
& dev_attr_manufacturer . attr ,
& dev_attr_board . attr ,
& dev_attr_fpga . attr ,
& dev_attr_build . attr ,
NULL
} ;
ATTRIBUTE_GROUPS ( realview ) ;
2014-07-25 15:04:52 +02:00
static int realview_soc_probe ( struct platform_device * pdev )
{
2017-07-19 17:40:59 -05:00
struct regmap * syscon_regmap ;
2014-07-25 15:04:52 +02:00
struct soc_device * soc_dev ;
struct soc_device_attribute * soc_dev_attr ;
struct device_node * np = pdev - > dev . of_node ;
int ret ;
syscon_regmap = syscon_regmap_lookup_by_phandle ( np , " regmap " ) ;
if ( IS_ERR ( syscon_regmap ) )
return PTR_ERR ( syscon_regmap ) ;
soc_dev_attr = kzalloc ( sizeof ( * soc_dev_attr ) , GFP_KERNEL ) ;
if ( ! soc_dev_attr )
return - ENOMEM ;
ret = of_property_read_string ( np , " compatible " ,
& soc_dev_attr - > soc_id ) ;
if ( ret )
return - EINVAL ;
soc_dev_attr - > machine = " RealView " ;
soc_dev_attr - > family = " Versatile " ;
2020-05-23 18:08:53 +01:00
soc_dev_attr - > custom_attr_group = realview_groups [ 0 ] ;
2014-07-25 15:04:52 +02:00
soc_dev = soc_device_register ( soc_dev_attr ) ;
if ( IS_ERR ( soc_dev ) ) {
kfree ( soc_dev_attr ) ;
return - ENODEV ;
}
ret = regmap_read ( syscon_regmap , REALVIEW_SYS_ID_OFFSET ,
& realview_coreid ) ;
if ( ret )
return - ENODEV ;
2016-02-18 14:21:54 +01:00
dev_info ( & pdev - > dev , " RealView Syscon Core ID: 0x%08x, HBI-%03x \n " ,
realview_coreid ,
( ( realview_coreid > > 16 ) & 0xfff ) ) ;
2014-07-25 15:04:52 +02:00
/* FIXME: add attributes for SoC to sysfs */
return 0 ;
}
static struct platform_driver realview_soc_driver = {
. probe = realview_soc_probe ,
. driver = {
. name = " realview-soc " ,
. of_match_table = realview_soc_of_match ,
} ,
} ;
2015-05-01 20:10:57 -04:00
builtin_platform_driver ( realview_soc_driver ) ;