2018-09-07 02:04:19 +00:00
// SPDX-License-Identifier: GPL-2.0
2016-11-14 19:37:08 +01:00
/*
* Renesas SoC Identification
*
* Copyright ( C ) 2014 - 2016 Glider bvba
*/
# include <linux/io.h>
# include <linux/of.h>
# include <linux/of_address.h>
# include <linux/slab.h>
# include <linux/string.h>
# include <linux/sys_soc.h>
struct renesas_family {
const char name [ 16 ] ;
u32 reg ; /* CCCR or PRR, if not in DT */
} ;
static const struct renesas_family fam_rcar_gen1 __initconst __maybe_unused = {
. name = " R-Car Gen1 " ,
. reg = 0xff000044 , /* PRR (Product Register) */
} ;
static const struct renesas_family fam_rcar_gen2 __initconst __maybe_unused = {
. name = " R-Car Gen2 " ,
. reg = 0xff000044 , /* PRR (Product Register) */
} ;
static const struct renesas_family fam_rcar_gen3 __initconst __maybe_unused = {
. name = " R-Car Gen3 " ,
. reg = 0xfff00044 , /* PRR (Product Register) */
} ;
2021-12-01 16:33:01 +09:00
static const struct renesas_family fam_rcar_gen4 __initconst __maybe_unused = {
. name = " R-Car Gen4 " ,
} ;
2016-11-14 19:37:08 +01:00
static const struct renesas_family fam_rmobile __initconst __maybe_unused = {
. name = " R-Mobile " ,
. reg = 0xe600101c , /* CCCR (Common Chip Code Register) */
} ;
2018-07-27 11:53:32 -05:00
static const struct renesas_family fam_rza1 __initconst __maybe_unused = {
. name = " RZ/A1 " ,
} ;
static const struct renesas_family fam_rza2 __initconst __maybe_unused = {
. name = " RZ/A2 " ,
2016-11-14 19:37:08 +01:00
} ;
2018-07-24 16:47:18 +01:00
static const struct renesas_family fam_rzg1 __initconst __maybe_unused = {
. name = " RZ/G1 " ,
2016-11-14 19:37:08 +01:00
. reg = 0xff000044 , /* PRR (Product Register) */
} ;
2018-07-24 16:47:18 +01:00
static const struct renesas_family fam_rzg2 __initconst __maybe_unused = {
. name = " RZ/G2 " ,
. reg = 0xfff00044 , /* PRR (Product Register) */
} ;
2021-06-09 17:37:16 +01:00
static const struct renesas_family fam_rzg2l __initconst __maybe_unused = {
. name = " RZ/G2L " ,
} ;
2022-03-15 14:26:39 +00:00
static const struct renesas_family fam_rzg2ul __initconst __maybe_unused = {
. name = " RZ/G2UL " ,
} ;
2022-01-10 13:46:49 +00:00
static const struct renesas_family fam_rzv2l __initconst __maybe_unused = {
. name = " RZ/V2L " ,
} ;
2016-11-14 19:37:08 +01:00
static const struct renesas_family fam_shmobile __initconst __maybe_unused = {
. name = " SH-Mobile " ,
. reg = 0xe600101c , /* CCCR (Common Chip Code Register) */
} ;
struct renesas_soc {
const struct renesas_family * family ;
2021-06-09 17:37:16 +01:00
u32 id ;
2016-11-14 19:37:08 +01:00
} ;
static const struct renesas_soc soc_rz_a1h __initconst __maybe_unused = {
2018-07-27 11:53:32 -05:00
. family = & fam_rza1 ,
} ;
static const struct renesas_soc soc_rz_a2m __initconst __maybe_unused = {
. family = & fam_rza2 ,
. id = 0x3b ,
2016-11-14 19:37:08 +01:00
} ;
static const struct renesas_soc soc_rmobile_ape6 __initconst __maybe_unused = {
. family = & fam_rmobile ,
. id = 0x3f ,
} ;
static const struct renesas_soc soc_rmobile_a1 __initconst __maybe_unused = {
. family = & fam_rmobile ,
. id = 0x40 ,
} ;
2017-03-10 14:48:29 +01:00
static const struct renesas_soc soc_rz_g1h __initconst __maybe_unused = {
2018-07-24 16:47:18 +01:00
. family = & fam_rzg1 ,
2017-03-10 14:48:29 +01:00
. id = 0x45 ,
} ;
2016-11-14 19:37:08 +01:00
static const struct renesas_soc soc_rz_g1m __initconst __maybe_unused = {
2018-07-24 16:47:18 +01:00
. family = & fam_rzg1 ,
2016-11-14 19:37:08 +01:00
. id = 0x47 ,
} ;
2017-03-10 14:48:30 +01:00
static const struct renesas_soc soc_rz_g1n __initconst __maybe_unused = {
2018-07-24 16:47:18 +01:00
. family = & fam_rzg1 ,
2017-03-10 14:48:30 +01:00
. id = 0x4b ,
} ;
2016-11-14 19:37:08 +01:00
static const struct renesas_soc soc_rz_g1e __initconst __maybe_unused = {
2018-07-24 16:47:18 +01:00
. family = & fam_rzg1 ,
2016-11-14 19:37:08 +01:00
. id = 0x4c ,
} ;
2018-03-27 15:37:13 +01:00
static const struct renesas_soc soc_rz_g1c __initconst __maybe_unused = {
2018-07-24 16:47:18 +01:00
. family = & fam_rzg1 ,
2018-03-27 15:37:13 +01:00
. id = 0x53 ,
} ;
2018-07-24 16:47:18 +01:00
static const struct renesas_soc soc_rz_g2m __initconst __maybe_unused = {
. family = & fam_rzg2 ,
. id = 0x52 ,
} ;
2019-09-05 10:30:42 +01:00
static const struct renesas_soc soc_rz_g2n __initconst __maybe_unused = {
. family = & fam_rzg2 ,
. id = 0x55 ,
} ;
2018-09-10 12:53:50 +01:00
static const struct renesas_soc soc_rz_g2e __initconst __maybe_unused = {
. family = & fam_rzg2 ,
. id = 0x57 ,
} ;
2020-07-07 17:18:01 +01:00
static const struct renesas_soc soc_rz_g2h __initconst __maybe_unused = {
. family = & fam_rzg2 ,
. id = 0x4f ,
} ;
2021-06-09 17:37:16 +01:00
static const struct renesas_soc soc_rz_g2l __initconst __maybe_unused = {
. family = & fam_rzg2l ,
. id = 0x841c447 ,
} ;
2022-03-15 14:26:39 +00:00
static const struct renesas_soc soc_rz_g2ul __initconst __maybe_unused = {
. family = & fam_rzg2ul ,
. id = 0x8450447 ,
} ;
2022-01-10 13:46:49 +00:00
static const struct renesas_soc soc_rz_v2l __initconst __maybe_unused = {
. family = & fam_rzv2l ,
. id = 0x8447447 ,
} ;
2016-11-14 19:37:08 +01:00
static const struct renesas_soc soc_rcar_m1a __initconst __maybe_unused = {
. family = & fam_rcar_gen1 ,
} ;
static const struct renesas_soc soc_rcar_h1 __initconst __maybe_unused = {
. family = & fam_rcar_gen1 ,
. id = 0x3b ,
} ;
static const struct renesas_soc soc_rcar_h2 __initconst __maybe_unused = {
. family = & fam_rcar_gen2 ,
. id = 0x45 ,
} ;
static const struct renesas_soc soc_rcar_m2_w __initconst __maybe_unused = {
. family = & fam_rcar_gen2 ,
. id = 0x47 ,
} ;
static const struct renesas_soc soc_rcar_v2h __initconst __maybe_unused = {
. family = & fam_rcar_gen2 ,
. id = 0x4a ,
} ;
static const struct renesas_soc soc_rcar_m2_n __initconst __maybe_unused = {
. family = & fam_rcar_gen2 ,
. id = 0x4b ,
} ;
static const struct renesas_soc soc_rcar_e2 __initconst __maybe_unused = {
. family = & fam_rcar_gen2 ,
. id = 0x4c ,
} ;
static const struct renesas_soc soc_rcar_h3 __initconst __maybe_unused = {
. family = & fam_rcar_gen3 ,
. id = 0x4f ,
} ;
static const struct renesas_soc soc_rcar_m3_w __initconst __maybe_unused = {
. family = & fam_rcar_gen3 ,
. id = 0x52 ,
} ;
2018-02-20 16:12:05 +01:00
static const struct renesas_soc soc_rcar_m3_n __initconst __maybe_unused = {
. family = & fam_rcar_gen3 ,
. id = 0x55 ,
} ;
2017-09-12 23:37:17 +03:00
static const struct renesas_soc soc_rcar_v3m __initconst __maybe_unused = {
. family = & fam_rcar_gen3 ,
. id = 0x54 ,
} ;
2018-02-02 21:22:14 +03:00
static const struct renesas_soc soc_rcar_v3h __initconst __maybe_unused = {
. family = & fam_rcar_gen3 ,
. id = 0x56 ,
} ;
2018-04-11 18:36:23 +09:00
static const struct renesas_soc soc_rcar_e3 __initconst __maybe_unused = {
. family = & fam_rcar_gen3 ,
. id = 0x57 ,
} ;
2017-07-20 14:34:51 +02:00
static const struct renesas_soc soc_rcar_d3 __initconst __maybe_unused = {
. family = & fam_rcar_gen3 ,
. id = 0x58 ,
} ;
2020-09-07 18:19:45 +09:00
static const struct renesas_soc soc_rcar_v3u __initconst __maybe_unused = {
. family = & fam_rcar_gen3 ,
. id = 0x59 ,
} ;
2021-12-01 16:33:01 +09:00
static const struct renesas_soc soc_rcar_s4 __initconst __maybe_unused = {
. family = & fam_rcar_gen4 ,
. id = 0x5a ,
} ;
2022-04-20 17:42:50 +09:00
static const struct renesas_soc soc_rcar_v4h __initconst __maybe_unused = {
. family = & fam_rcar_gen4 ,
. id = 0x5c ,
} ;
2016-11-14 19:37:08 +01:00
static const struct renesas_soc soc_shmobile_ag5 __initconst __maybe_unused = {
. family = & fam_shmobile ,
. id = 0x37 ,
} ;
static const struct of_device_id renesas_socs [ ] __initconst = {
# ifdef CONFIG_ARCH_R7S72100
{ . compatible = " renesas,r7s72100 " , . data = & soc_rz_a1h } ,
# endif
2018-07-27 11:53:32 -05:00
# ifdef CONFIG_ARCH_R7S9210
{ . compatible = " renesas,r7s9210 " , . data = & soc_rz_a2m } ,
# endif
2016-11-14 19:37:08 +01:00
# ifdef CONFIG_ARCH_R8A73A4
{ . compatible = " renesas,r8a73a4 " , . data = & soc_rmobile_ape6 } ,
# endif
# ifdef CONFIG_ARCH_R8A7740
{ . compatible = " renesas,r8a7740 " , . data = & soc_rmobile_a1 } ,
# endif
2017-03-10 14:48:29 +01:00
# ifdef CONFIG_ARCH_R8A7742
{ . compatible = " renesas,r8a7742 " , . data = & soc_rz_g1h } ,
# endif
2016-11-14 19:37:08 +01:00
# ifdef CONFIG_ARCH_R8A7743
{ . compatible = " renesas,r8a7743 " , . data = & soc_rz_g1m } ,
# endif
2017-03-10 14:48:30 +01:00
# ifdef CONFIG_ARCH_R8A7744
{ . compatible = " renesas,r8a7744 " , . data = & soc_rz_g1n } ,
# endif
2016-11-14 19:37:08 +01:00
# ifdef CONFIG_ARCH_R8A7745
{ . compatible = " renesas,r8a7745 " , . data = & soc_rz_g1e } ,
# endif
2018-03-27 15:37:13 +01:00
# ifdef CONFIG_ARCH_R8A77470
{ . compatible = " renesas,r8a77470 " , . data = & soc_rz_g1c } ,
# endif
2018-07-24 16:47:18 +01:00
# ifdef CONFIG_ARCH_R8A774A1
{ . compatible = " renesas,r8a774a1 " , . data = & soc_rz_g2m } ,
2019-09-05 10:30:42 +01:00
# endif
# ifdef CONFIG_ARCH_R8A774B1
{ . compatible = " renesas,r8a774b1 " , . data = & soc_rz_g2n } ,
2018-07-24 16:47:18 +01:00
# endif
2018-09-10 12:53:50 +01:00
# ifdef CONFIG_ARCH_R8A774C0
{ . compatible = " renesas,r8a774c0 " , . data = & soc_rz_g2e } ,
# endif
2020-07-07 17:18:01 +01:00
# ifdef CONFIG_ARCH_R8A774E1
{ . compatible = " renesas,r8a774e1 " , . data = & soc_rz_g2h } ,
# endif
2016-11-14 19:37:08 +01:00
# ifdef CONFIG_ARCH_R8A7778
{ . compatible = " renesas,r8a7778 " , . data = & soc_rcar_m1a } ,
# endif
# ifdef CONFIG_ARCH_R8A7779
{ . compatible = " renesas,r8a7779 " , . data = & soc_rcar_h1 } ,
# endif
# ifdef CONFIG_ARCH_R8A7790
{ . compatible = " renesas,r8a7790 " , . data = & soc_rcar_h2 } ,
# endif
# ifdef CONFIG_ARCH_R8A7791
{ . compatible = " renesas,r8a7791 " , . data = & soc_rcar_m2_w } ,
# endif
# ifdef CONFIG_ARCH_R8A7792
{ . compatible = " renesas,r8a7792 " , . data = & soc_rcar_v2h } ,
# endif
# ifdef CONFIG_ARCH_R8A7793
{ . compatible = " renesas,r8a7793 " , . data = & soc_rcar_m2_n } ,
# endif
# ifdef CONFIG_ARCH_R8A7794
{ . compatible = " renesas,r8a7794 " , . data = & soc_rcar_e2 } ,
# endif
2020-02-18 12:24:49 +01:00
# if defined(CONFIG_ARCH_R8A77950) || defined(CONFIG_ARCH_R8A77951)
2016-11-14 19:37:08 +01:00
{ . compatible = " renesas,r8a7795 " , . data = & soc_rcar_h3 } ,
# endif
2021-07-19 17:38:33 +02:00
# ifdef CONFIG_ARCH_R8A77951
2021-08-12 13:23:52 +02:00
{ . compatible = " renesas,r8a779m0 " , . data = & soc_rcar_h3 } ,
2021-07-19 17:38:33 +02:00
{ . compatible = " renesas,r8a779m1 " , . data = & soc_rcar_h3 } ,
2021-08-12 13:23:52 +02:00
{ . compatible = " renesas,r8a779m8 " , . data = & soc_rcar_h3 } ,
2021-07-19 17:38:33 +02:00
# endif
2019-10-23 14:33:33 +02:00
# ifdef CONFIG_ARCH_R8A77960
2016-11-14 19:37:08 +01:00
{ . compatible = " renesas,r8a7796 " , . data = & soc_rcar_m3_w } ,
# endif
2019-10-23 14:33:35 +02:00
# ifdef CONFIG_ARCH_R8A77961
{ . compatible = " renesas,r8a77961 " , . data = & soc_rcar_m3_w } ,
2021-08-12 13:23:52 +02:00
{ . compatible = " renesas,r8a779m2 " , . data = & soc_rcar_m3_w } ,
2021-07-19 17:38:33 +02:00
{ . compatible = " renesas,r8a779m3 " , . data = & soc_rcar_m3_w } ,
2019-10-23 14:33:35 +02:00
# endif
2018-02-20 16:12:05 +01:00
# ifdef CONFIG_ARCH_R8A77965
{ . compatible = " renesas,r8a77965 " , . data = & soc_rcar_m3_n } ,
2021-08-12 13:23:52 +02:00
{ . compatible = " renesas,r8a779m4 " , . data = & soc_rcar_m3_n } ,
{ . compatible = " renesas,r8a779m5 " , . data = & soc_rcar_m3_n } ,
2018-02-20 16:12:05 +01:00
# endif
2017-09-12 23:37:17 +03:00
# ifdef CONFIG_ARCH_R8A77970
{ . compatible = " renesas,r8a77970 " , . data = & soc_rcar_v3m } ,
# endif
2018-02-02 21:22:14 +03:00
# ifdef CONFIG_ARCH_R8A77980
{ . compatible = " renesas,r8a77980 " , . data = & soc_rcar_v3h } ,
# endif
2018-04-11 18:36:23 +09:00
# ifdef CONFIG_ARCH_R8A77990
{ . compatible = " renesas,r8a77990 " , . data = & soc_rcar_e3 } ,
2021-08-12 13:23:52 +02:00
{ . compatible = " renesas,r8a779m6 " , . data = & soc_rcar_e3 } ,
2018-04-11 18:36:23 +09:00
# endif
2017-07-20 14:34:51 +02:00
# ifdef CONFIG_ARCH_R8A77995
{ . compatible = " renesas,r8a77995 " , . data = & soc_rcar_d3 } ,
2021-08-12 13:23:52 +02:00
{ . compatible = " renesas,r8a779m7 " , . data = & soc_rcar_d3 } ,
2017-07-20 14:34:51 +02:00
# endif
2020-09-07 18:19:45 +09:00
# ifdef CONFIG_ARCH_R8A779A0
{ . compatible = " renesas,r8a779a0 " , . data = & soc_rcar_v3u } ,
# endif
2021-12-01 16:33:01 +09:00
# ifdef CONFIG_ARCH_R8A779F0
{ . compatible = " renesas,r8a779f0 " , . data = & soc_rcar_s4 } ,
# endif
2022-04-20 17:42:50 +09:00
# ifdef CONFIG_ARCH_R8A779G0
{ . compatible = " renesas,r8a779g0 " , . data = & soc_rcar_v4h } ,
# endif
2022-03-15 14:26:39 +00:00
# if defined(CONFIG_ARCH_R9A07G043)
{ . compatible = " renesas,r9a07g043 " , . data = & soc_rz_g2ul } ,
# endif
2021-06-09 17:37:16 +01:00
# if defined(CONFIG_ARCH_R9A07G044)
{ . compatible = " renesas,r9a07g044 " , . data = & soc_rz_g2l } ,
# endif
2022-01-10 13:46:49 +00:00
# if defined(CONFIG_ARCH_R9A07G054)
{ . compatible = " renesas,r9a07g054 " , . data = & soc_rz_v2l } ,
# endif
2016-11-14 19:37:08 +01:00
# ifdef CONFIG_ARCH_SH73A0
{ . compatible = " renesas,sh73a0 " , . data = & soc_shmobile_ag5 } ,
# endif
{ /* sentinel */ }
} ;
2021-11-10 20:00:52 +01:00
struct renesas_id {
unsigned int offset ;
u32 mask ;
} ;
static const struct renesas_id id_bsid __initconst = {
. offset = 0 ,
. mask = 0xff0000 ,
/*
* TODO : Upper 4 bits of BSID are for chip version , but the format is
* not known at this time so we don ' t know how to specify eshi and eslo
*/
} ;
static const struct renesas_id id_rzg2l __initconst = {
. offset = 0xa04 ,
. mask = 0xfffffff ,
} ;
static const struct renesas_id id_prr __initconst = {
. offset = 0 ,
. mask = 0xff00 ,
} ;
static const struct of_device_id renesas_ids [ ] __initconst = {
{ . compatible = " renesas,bsid " , . data = & id_bsid } ,
2022-03-15 14:26:39 +00:00
{ . compatible = " renesas,r9a07g043-sysc " , . data = & id_rzg2l } ,
2021-11-10 20:00:52 +01:00
{ . compatible = " renesas,r9a07g044-sysc " , . data = & id_rzg2l } ,
2022-01-10 13:46:49 +00:00
{ . compatible = " renesas,r9a07g054-sysc " , . data = & id_rzg2l } ,
2021-11-10 20:00:52 +01:00
{ . compatible = " renesas,prr " , . data = & id_prr } ,
{ /* sentinel */ }
} ;
2016-11-14 19:37:08 +01:00
static int __init renesas_soc_init ( void )
{
struct soc_device_attribute * soc_dev_attr ;
2021-11-10 20:00:52 +01:00
unsigned int product , eshi = 0 , eslo ;
2016-11-14 19:37:08 +01:00
const struct renesas_family * family ;
const struct of_device_id * match ;
const struct renesas_soc * soc ;
2021-11-10 20:00:52 +01:00
const struct renesas_id * id ;
2016-11-14 19:37:08 +01:00
void __iomem * chipid = NULL ;
2022-01-21 01:41:17 +00:00
const char * rev_prefix = " " ;
2016-11-14 19:37:08 +01:00
struct soc_device * soc_dev ;
struct device_node * np ;
2021-11-10 20:00:52 +01:00
const char * soc_id ;
2022-01-21 01:41:17 +00:00
int ret ;
2016-11-14 19:37:08 +01:00
match = of_match_node ( renesas_socs , of_root ) ;
if ( ! match )
return - ENODEV ;
2021-11-10 20:00:52 +01:00
soc_id = strchr ( match - > compatible , ' , ' ) + 1 ;
2016-11-14 19:37:08 +01:00
soc = match - > data ;
family = soc - > family ;
2021-11-10 20:00:52 +01:00
np = of_find_matching_node_and_match ( NULL , renesas_ids , & match ) ;
2018-07-27 11:53:32 -05:00
if ( np ) {
2021-11-10 20:00:52 +01:00
id = match - > data ;
2018-07-27 11:53:32 -05:00
chipid = of_iomap ( np , 0 ) ;
of_node_put ( np ) ;
2021-11-10 20:00:52 +01:00
} else if ( soc - > id & & family - > reg ) {
/* Try hardcoded CCCR/PRR fallback */
id = & id_prr ;
chipid = ioremap ( family - > reg , 4 ) ;
2018-07-27 11:53:32 -05:00
}
2022-01-21 01:41:17 +00:00
soc_dev_attr = kzalloc ( sizeof ( * soc_dev_attr ) , GFP_KERNEL ) ;
if ( ! soc_dev_attr )
return - ENOMEM ;
np = of_find_node_by_path ( " / " ) ;
of_property_read_string ( np , " model " , & soc_dev_attr - > machine ) ;
of_node_put ( np ) ;
soc_dev_attr - > family = kstrdup_const ( family - > name , GFP_KERNEL ) ;
soc_dev_attr - > soc_id = kstrdup_const ( soc_id , GFP_KERNEL ) ;
2021-11-10 20:00:52 +01:00
if ( chipid ) {
product = readl ( chipid + id - > offset ) ;
iounmap ( chipid ) ;
2021-06-09 17:37:16 +01:00
2021-11-10 20:00:52 +01:00
if ( id = = & id_prr ) {
/* R-Car M3-W ES1.1 incorrectly identifies as ES2.0 */
if ( ( product & 0x7fff ) = = 0x5210 )
product ^ = 0x11 ;
/* R-Car M3-W ES1.3 incorrectly identifies as ES2.1 */
if ( ( product & 0x7fff ) = = 0x5211 )
product ^ = 0x12 ;
2021-06-09 17:37:16 +01:00
2021-11-10 20:00:52 +01:00
eshi = ( ( product > > 4 ) & 0x0f ) + 1 ;
eslo = product & 0xf ;
2022-01-21 01:41:17 +00:00
soc_dev_attr - > revision = kasprintf ( GFP_KERNEL , " ES%u.%u " ,
eshi , eslo ) ;
} else if ( id = = & id_rzg2l ) {
eshi = ( ( product > > 28 ) & 0x0f ) ;
soc_dev_attr - > revision = kasprintf ( GFP_KERNEL , " %u " ,
eshi ) ;
rev_prefix = " Rev " ;
2021-06-09 17:37:16 +01:00
}
2021-11-10 20:00:52 +01:00
if ( soc - > id & &
( ( product & id - > mask ) > > __ffs ( id - > mask ) ) ! = soc - > id ) {
2016-11-14 19:37:08 +01:00
pr_warn ( " SoC mismatch (product = 0x%x) \n " , product ) ;
2022-01-21 01:41:17 +00:00
ret = - ENODEV ;
goto free_soc_dev_attr ;
2016-11-14 19:37:08 +01:00
}
}
2022-01-21 01:41:17 +00:00
pr_info ( " Detected Renesas %s %s %s%s \n " , soc_dev_attr - > family ,
soc_dev_attr - > soc_id , rev_prefix , soc_dev_attr - > revision ? : " " ) ;
2016-11-14 19:37:08 +01:00
soc_dev = soc_device_register ( soc_dev_attr ) ;
if ( IS_ERR ( soc_dev ) ) {
2022-01-21 01:41:17 +00:00
ret = PTR_ERR ( soc_dev ) ;
goto free_soc_dev_attr ;
2016-11-14 19:37:08 +01:00
}
return 0 ;
2022-01-21 01:41:17 +00:00
free_soc_dev_attr :
kfree ( soc_dev_attr - > revision ) ;
kfree_const ( soc_dev_attr - > soc_id ) ;
kfree_const ( soc_dev_attr - > family ) ;
kfree ( soc_dev_attr ) ;
return ret ;
2016-11-14 19:37:08 +01:00
}
2017-03-31 11:01:54 +02:00
early_initcall ( renesas_soc_init ) ;