1414
1515#include <linux/array_size.h>
1616#include <linux/device.h>
17- #include <linux/errno.h>
17+ #include <linux/device/devres.h>
18+ #include <linux/err.h>
19+ #include <linux/ioport.h>
1820#include <linux/mfd/syscon.h>
1921#include <linux/module.h>
2022#include <linux/of.h>
2729#include "exynos-asv.h"
2830
2931struct exynos_chipid_variant {
30- unsigned int rev_reg ; /* revision register offset */
32+ unsigned int main_rev_reg ; /* main revision register offset */
33+ unsigned int sub_rev_reg ; /* sub revision register offset */
3134 unsigned int main_rev_shift ; /* main revision offset in rev_reg */
3235 unsigned int sub_rev_shift ; /* sub revision offset in rev_reg */
36+ bool efuse ;
3337};
3438
3539struct exynos_chipid_info {
@@ -68,9 +72,11 @@ static const struct exynos_soc_id {
6872 { "EXYNOS990" , 0xE9830000 },
6973 { "EXYNOSAUTOV9" , 0xAAA80000 },
7074 { "EXYNOSAUTOV920" , 0x0A920000 },
75+ /* Compatible with: google,gs101-otp */
76+ { "GS101" , 0x9845000 },
7177};
7278
73- static const char * product_id_to_soc_id (unsigned int product_id )
79+ static const char * exynos_product_id_to_name (unsigned int product_id )
7480{
7581 int i ;
7682
@@ -80,30 +86,70 @@ static const char *product_id_to_soc_id(unsigned int product_id)
8086 return NULL ;
8187}
8288
83- static int exynos_chipid_get_chipid_info (struct regmap * regmap ,
84- const struct exynos_chipid_variant * data ,
89+ static int exynos_chipid_get_chipid_info (struct device * dev ,
90+ struct regmap * regmap , const struct exynos_chipid_variant * data ,
8591 struct exynos_chipid_info * soc_info )
8692{
8793 int ret ;
8894 unsigned int val , main_rev , sub_rev ;
8995
9096 ret = regmap_read (regmap , EXYNOS_CHIPID_REG_PRO_ID , & val );
9197 if (ret < 0 )
92- return ret ;
98+ return dev_err_probe ( dev , ret , "failed to read Product ID\n" ) ;
9399 soc_info -> product_id = val & EXYNOS_MASK ;
94100
95- if (data -> rev_reg != EXYNOS_CHIPID_REG_PRO_ID ) {
96- ret = regmap_read (regmap , data -> rev_reg , & val );
101+ if (data -> sub_rev_reg == EXYNOS_CHIPID_REG_PRO_ID ) {
102+ /* exynos4210 case */
103+ main_rev = (val >> data -> main_rev_shift ) & EXYNOS_REV_PART_MASK ;
104+ sub_rev = (val >> data -> sub_rev_shift ) & EXYNOS_REV_PART_MASK ;
105+ } else {
106+ unsigned int val2 ;
107+
108+ ret = regmap_read (regmap , data -> sub_rev_reg , & val2 );
97109 if (ret < 0 )
98- return ret ;
110+ return dev_err_probe (dev , ret ,
111+ "failed to read revision\n" );
112+
113+ if (data -> main_rev_reg == EXYNOS_CHIPID_REG_PRO_ID )
114+ /* gs101 case */
115+ main_rev = (val >> data -> main_rev_shift ) & EXYNOS_REV_PART_MASK ;
116+ else
117+ /* exynos850 case */
118+ main_rev = (val2 >> data -> main_rev_shift ) & EXYNOS_REV_PART_MASK ;
119+
120+ sub_rev = (val2 >> data -> sub_rev_shift ) & EXYNOS_REV_PART_MASK ;
99121 }
100- main_rev = (val >> data -> main_rev_shift ) & EXYNOS_REV_PART_MASK ;
101- sub_rev = (val >> data -> sub_rev_shift ) & EXYNOS_REV_PART_MASK ;
122+
102123 soc_info -> revision = (main_rev << EXYNOS_REV_PART_SHIFT ) | sub_rev ;
103124
104125 return 0 ;
105126}
106127
128+ static struct regmap * exynos_chipid_get_efuse_regmap (struct platform_device * pdev )
129+ {
130+ struct resource * res ;
131+ void __iomem * base ;
132+
133+ base = devm_platform_get_and_ioremap_resource (pdev , 0 , & res );
134+ if (IS_ERR (base ))
135+ return ERR_CAST (base );
136+
137+ const struct regmap_config reg_config = {
138+ .reg_bits = 32 ,
139+ .reg_stride = 4 ,
140+ .val_bits = 32 ,
141+ .use_relaxed_mmio = true,
142+ .max_register = (resource_size (res ) - reg_config .reg_stride ),
143+ };
144+
145+ return devm_regmap_init_mmio_clk (& pdev -> dev , "pclk" , base , & reg_config );
146+ }
147+
148+ static void exynos_chipid_unregister_soc (void * data )
149+ {
150+ soc_device_unregister (data );
151+ }
152+
107153static int exynos_chipid_probe (struct platform_device * pdev )
108154{
109155 const struct exynos_chipid_variant * drv_data ;
@@ -117,13 +163,19 @@ static int exynos_chipid_probe(struct platform_device *pdev)
117163
118164 drv_data = of_device_get_match_data (dev );
119165 if (!drv_data )
120- return - EINVAL ;
166+ return dev_err_probe (dev , - EINVAL ,
167+ "failed to get match data\n" );
168+
169+ if (drv_data -> efuse )
170+ regmap = exynos_chipid_get_efuse_regmap (pdev );
171+ else
172+ regmap = device_node_to_regmap (dev -> of_node );
121173
122- regmap = device_node_to_regmap (dev -> of_node );
123174 if (IS_ERR (regmap ))
124- return PTR_ERR (regmap );
175+ return dev_err_probe (dev , PTR_ERR (regmap ),
176+ "failed to get regmap\n" );
125177
126- ret = exynos_chipid_get_chipid_info (regmap , drv_data , & soc_info );
178+ ret = exynos_chipid_get_chipid_info (dev , regmap , drv_data , & soc_info );
127179 if (ret < 0 )
128180 return ret ;
129181
@@ -141,55 +193,55 @@ static int exynos_chipid_probe(struct platform_device *pdev)
141193 soc_info .revision );
142194 if (!soc_dev_attr -> revision )
143195 return - ENOMEM ;
144- soc_dev_attr -> soc_id = product_id_to_soc_id (soc_info .product_id );
145- if (!soc_dev_attr -> soc_id ) {
146- pr_err ("Unknown SoC\n" );
147- return - ENODEV ;
148- }
196+
197+ soc_dev_attr -> soc_id = exynos_product_id_to_name (soc_info .product_id );
198+ if (!soc_dev_attr -> soc_id )
199+ return dev_err_probe (dev , - ENODEV , "Unknown SoC\n" );
149200
150201 /* please note that the actual registration will be deferred */
151202 soc_dev = soc_device_register (soc_dev_attr );
152203 if (IS_ERR (soc_dev ))
153- return PTR_ERR (soc_dev );
204+ return dev_err_probe (dev , PTR_ERR (soc_dev ),
205+ "failed to register to the soc interface\n" );
154206
155- ret = exynos_asv_init (dev , regmap );
207+ ret = devm_add_action_or_reset (dev , exynos_chipid_unregister_soc ,
208+ soc_dev );
156209 if (ret )
157- goto err ;
210+ return dev_err_probe ( dev , ret , "failed to add devm action\n" ) ;
158211
159- platform_set_drvdata (pdev , soc_dev );
212+ ret = exynos_asv_init (dev , regmap );
213+ if (ret )
214+ return ret ;
160215
161- dev_info (dev , "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n" ,
162- soc_dev_attr -> soc_id , soc_info .product_id , soc_info .revision );
216+ dev_dbg (dev , "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n" ,
217+ soc_dev_attr -> soc_id , soc_info .product_id , soc_info .revision );
163218
164219 return 0 ;
165-
166- err :
167- soc_device_unregister (soc_dev );
168-
169- return ret ;
170- }
171-
172- static void exynos_chipid_remove (struct platform_device * pdev )
173- {
174- struct soc_device * soc_dev = platform_get_drvdata (pdev );
175-
176- soc_device_unregister (soc_dev );
177220}
178221
179222static const struct exynos_chipid_variant exynos4210_chipid_drv_data = {
180- .rev_reg = 0x0 ,
181223 .main_rev_shift = 4 ,
182224 .sub_rev_shift = 0 ,
183225};
184226
185227static const struct exynos_chipid_variant exynos850_chipid_drv_data = {
186- .rev_reg = 0x10 ,
228+ .main_rev_reg = 0x10 ,
229+ .sub_rev_reg = 0x10 ,
187230 .main_rev_shift = 20 ,
188231 .sub_rev_shift = 16 ,
189232};
190233
234+ static const struct exynos_chipid_variant gs101_chipid_drv_data = {
235+ .sub_rev_reg = 0x10 ,
236+ .sub_rev_shift = 16 ,
237+ .efuse = true,
238+ };
239+
191240static const struct of_device_id exynos_chipid_of_device_ids [] = {
192241 {
242+ .compatible = "google,gs101-otp" ,
243+ .data = & gs101_chipid_drv_data ,
244+ }, {
193245 .compatible = "samsung,exynos4210-chipid" ,
194246 .data = & exynos4210_chipid_drv_data ,
195247 }, {
@@ -206,7 +258,6 @@ static struct platform_driver exynos_chipid_driver = {
206258 .of_match_table = exynos_chipid_of_device_ids ,
207259 },
208260 .probe = exynos_chipid_probe ,
209- .remove = exynos_chipid_remove ,
210261};
211262module_platform_driver (exynos_chipid_driver );
212263
0 commit comments