2525
2626static struct platform_device * cpufreq_dt_pdev , * sun50i_cpufreq_pdev ;
2727
28+ struct sunxi_cpufreq_data {
29+ u32 (* efuse_xlate )(u32 speedbin );
30+ };
31+
32+ static u32 sun50i_h6_efuse_xlate (u32 speedbin )
33+ {
34+ u32 efuse_value ;
35+
36+ efuse_value = (speedbin >> NVMEM_SHIFT ) & NVMEM_MASK ;
37+
38+ /*
39+ * We treat unexpected efuse values as if the SoC was from
40+ * the slowest bin. Expected efuse values are 1-3, slowest
41+ * to fastest.
42+ */
43+ if (efuse_value >= 1 && efuse_value <= 3 )
44+ return efuse_value - 1 ;
45+ else
46+ return 0 ;
47+ }
48+
49+ static struct sunxi_cpufreq_data sun50i_h6_cpufreq_data = {
50+ .efuse_xlate = sun50i_h6_efuse_xlate ,
51+ };
52+
53+ static const struct of_device_id cpu_opp_match_list [] = {
54+ { .compatible = "allwinner,sun50i-h6-operating-points" ,
55+ .data = & sun50i_h6_cpufreq_data ,
56+ },
57+ {}
58+ };
59+
2860/**
2961 * sun50i_cpufreq_get_efuse() - Determine speed grade from efuse value
30- * @versions: Set to the value parsed from efuse
3162 *
32- * Returns 0 if success.
63+ * Returns non-negative speed bin index on success, a negative error
64+ * value otherwise.
3365 */
34- static int sun50i_cpufreq_get_efuse (u32 * versions )
66+ static int sun50i_cpufreq_get_efuse (void )
3567{
68+ const struct sunxi_cpufreq_data * opp_data ;
3669 struct nvmem_cell * speedbin_nvmem ;
70+ const struct of_device_id * match ;
3771 struct device_node * np ;
3872 struct device * cpu_dev ;
39- u32 * speedbin , efuse_value ;
40- size_t len ;
73+ u32 * speedbin ;
4174 int ret ;
4275
4376 cpu_dev = get_cpu_device (0 );
@@ -48,57 +81,48 @@ static int sun50i_cpufreq_get_efuse(u32 *versions)
4881 if (!np )
4982 return - ENOENT ;
5083
51- ret = of_device_is_compatible (np ,
52- "allwinner,sun50i-h6-operating-points" );
53- if (!ret ) {
84+ match = of_match_node (cpu_opp_match_list , np );
85+ if (!match ) {
5486 of_node_put (np );
5587 return - ENOENT ;
5688 }
89+ opp_data = match -> data ;
5790
5891 speedbin_nvmem = of_nvmem_cell_get (np , NULL );
5992 of_node_put (np );
6093 if (IS_ERR (speedbin_nvmem ))
6194 return dev_err_probe (cpu_dev , PTR_ERR (speedbin_nvmem ),
6295 "Could not get nvmem cell\n" );
6396
64- speedbin = nvmem_cell_read (speedbin_nvmem , & len );
97+ speedbin = nvmem_cell_read (speedbin_nvmem , NULL );
6598 nvmem_cell_put (speedbin_nvmem );
6699 if (IS_ERR (speedbin ))
67100 return PTR_ERR (speedbin );
68101
69- efuse_value = (* speedbin >> NVMEM_SHIFT ) & NVMEM_MASK ;
70-
71- /*
72- * We treat unexpected efuse values as if the SoC was from
73- * the slowest bin. Expected efuse values are 1-3, slowest
74- * to fastest.
75- */
76- if (efuse_value >= 1 && efuse_value <= 3 )
77- * versions = efuse_value - 1 ;
78- else
79- * versions = 0 ;
102+ ret = opp_data -> efuse_xlate (* speedbin );
80103
81104 kfree (speedbin );
82- return 0 ;
105+
106+ return ret ;
83107};
84108
85109static int sun50i_cpufreq_nvmem_probe (struct platform_device * pdev )
86110{
87111 int * opp_tokens ;
88112 char name [MAX_NAME_LEN ];
89113 unsigned int cpu ;
90- u32 speed = 0 ;
114+ int speed ;
91115 int ret ;
92116
93117 opp_tokens = kcalloc (num_possible_cpus (), sizeof (* opp_tokens ),
94118 GFP_KERNEL );
95119 if (!opp_tokens )
96120 return - ENOMEM ;
97121
98- ret = sun50i_cpufreq_get_efuse (& speed );
99- if (ret ) {
122+ speed = sun50i_cpufreq_get_efuse ();
123+ if (speed < 0 ) {
100124 kfree (opp_tokens );
101- return ret ;
125+ return speed ;
102126 }
103127
104128 snprintf (name , MAX_NAME_LEN , "speed%d" , speed );
0 commit comments