mediatek-cpufreq.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. /*
  2. * Copyright (c) 2015 Linaro Ltd.
  3. * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include <linux/clk.h>
  15. #include <linux/cpu.h>
  16. #include <linux/cpu_cooling.h>
  17. #include <linux/cpufreq.h>
  18. #include <linux/cpumask.h>
  19. #include <linux/module.h>
  20. #include <linux/of.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/pm_opp.h>
  23. #include <linux/regulator/consumer.h>
  24. #include <linux/slab.h>
  25. #include <linux/thermal.h>
  26. #define MIN_VOLT_SHIFT (100000)
  27. #define MAX_VOLT_SHIFT (200000)
  28. #define MAX_VOLT_LIMIT (1150000)
  29. #define VOLT_TOL (10000)
  30. /*
  31. * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU DVFS
  32. * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in
  33. * Mediatek SoCs has two voltage inputs, Vproc and Vsram. In some cases the two
  34. * voltage inputs need to be controlled under a hardware limitation:
  35. * 100mV < Vsram - Vproc < 200mV
  36. *
  37. * When scaling the clock frequency of a CPU clock domain, the clock source
  38. * needs to be switched to another stable PLL clock temporarily until
  39. * the original PLL becomes stable at target frequency.
  40. */
  41. struct mtk_cpu_dvfs_info {
  42. struct cpumask cpus;
  43. struct device *cpu_dev;
  44. struct regulator *proc_reg;
  45. struct regulator *sram_reg;
  46. struct clk *cpu_clk;
  47. struct clk *inter_clk;
  48. struct thermal_cooling_device *cdev;
  49. struct list_head list_head;
  50. int intermediate_voltage;
  51. bool need_voltage_tracking;
  52. };
  53. static LIST_HEAD(dvfs_info_list);
  54. static struct mtk_cpu_dvfs_info *mtk_cpu_dvfs_info_lookup(int cpu)
  55. {
  56. struct mtk_cpu_dvfs_info *info;
  57. list_for_each_entry(info, &dvfs_info_list, list_head) {
  58. if (cpumask_test_cpu(cpu, &info->cpus))
  59. return info;
  60. }
  61. return NULL;
  62. }
  63. static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
  64. int new_vproc)
  65. {
  66. struct regulator *proc_reg = info->proc_reg;
  67. struct regulator *sram_reg = info->sram_reg;
  68. int old_vproc, old_vsram, new_vsram, vsram, vproc, ret;
  69. old_vproc = regulator_get_voltage(proc_reg);
  70. if (old_vproc < 0) {
  71. pr_err("%s: invalid Vproc value: %d\n", __func__, old_vproc);
  72. return old_vproc;
  73. }
  74. /* Vsram should not exceed the maximum allowed voltage of SoC. */
  75. new_vsram = min(new_vproc + MIN_VOLT_SHIFT, MAX_VOLT_LIMIT);
  76. if (old_vproc < new_vproc) {
  77. /*
  78. * When scaling up voltages, Vsram and Vproc scale up step
  79. * by step. At each step, set Vsram to (Vproc + 200mV) first,
  80. * then set Vproc to (Vsram - 100mV).
  81. * Keep doing it until Vsram and Vproc hit target voltages.
  82. */
  83. do {
  84. old_vsram = regulator_get_voltage(sram_reg);
  85. if (old_vsram < 0) {
  86. pr_err("%s: invalid Vsram value: %d\n",
  87. __func__, old_vsram);
  88. return old_vsram;
  89. }
  90. old_vproc = regulator_get_voltage(proc_reg);
  91. if (old_vproc < 0) {
  92. pr_err("%s: invalid Vproc value: %d\n",
  93. __func__, old_vproc);
  94. return old_vproc;
  95. }
  96. vsram = min(new_vsram, old_vproc + MAX_VOLT_SHIFT);
  97. if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) {
  98. vsram = MAX_VOLT_LIMIT;
  99. /*
  100. * If the target Vsram hits the maximum voltage,
  101. * try to set the exact voltage value first.
  102. */
  103. ret = regulator_set_voltage(sram_reg, vsram,
  104. vsram);
  105. if (ret)
  106. ret = regulator_set_voltage(sram_reg,
  107. vsram - VOLT_TOL,
  108. vsram);
  109. vproc = new_vproc;
  110. } else {
  111. ret = regulator_set_voltage(sram_reg, vsram,
  112. vsram + VOLT_TOL);
  113. vproc = vsram - MIN_VOLT_SHIFT;
  114. }
  115. if (ret)
  116. return ret;
  117. ret = regulator_set_voltage(proc_reg, vproc,
  118. vproc + VOLT_TOL);
  119. if (ret) {
  120. regulator_set_voltage(sram_reg, old_vsram,
  121. old_vsram);
  122. return ret;
  123. }
  124. } while (vproc < new_vproc || vsram < new_vsram);
  125. } else if (old_vproc > new_vproc) {
  126. /*
  127. * When scaling down voltages, Vsram and Vproc scale down step
  128. * by step. At each step, set Vproc to (Vsram - 200mV) first,
  129. * then set Vproc to (Vproc + 100mV).
  130. * Keep doing it until Vsram and Vproc hit target voltages.
  131. */
  132. do {
  133. old_vproc = regulator_get_voltage(proc_reg);
  134. if (old_vproc < 0) {
  135. pr_err("%s: invalid Vproc value: %d\n",
  136. __func__, old_vproc);
  137. return old_vproc;
  138. }
  139. old_vsram = regulator_get_voltage(sram_reg);
  140. if (old_vsram < 0) {
  141. pr_err("%s: invalid Vsram value: %d\n",
  142. __func__, old_vsram);
  143. return old_vsram;
  144. }
  145. vproc = max(new_vproc, old_vsram - MAX_VOLT_SHIFT);
  146. ret = regulator_set_voltage(proc_reg, vproc,
  147. vproc + VOLT_TOL);
  148. if (ret)
  149. return ret;
  150. if (vproc == new_vproc)
  151. vsram = new_vsram;
  152. else
  153. vsram = max(new_vsram, vproc + MIN_VOLT_SHIFT);
  154. if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) {
  155. vsram = MAX_VOLT_LIMIT;
  156. /*
  157. * If the target Vsram hits the maximum voltage,
  158. * try to set the exact voltage value first.
  159. */
  160. ret = regulator_set_voltage(sram_reg, vsram,
  161. vsram);
  162. if (ret)
  163. ret = regulator_set_voltage(sram_reg,
  164. vsram - VOLT_TOL,
  165. vsram);
  166. } else {
  167. ret = regulator_set_voltage(sram_reg, vsram,
  168. vsram + VOLT_TOL);
  169. }
  170. if (ret) {
  171. regulator_set_voltage(proc_reg, old_vproc,
  172. old_vproc);
  173. return ret;
  174. }
  175. } while (vproc > new_vproc + VOLT_TOL ||
  176. vsram > new_vsram + VOLT_TOL);
  177. }
  178. return 0;
  179. }
  180. static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc)
  181. {
  182. if (info->need_voltage_tracking)
  183. return mtk_cpufreq_voltage_tracking(info, vproc);
  184. else
  185. return regulator_set_voltage(info->proc_reg, vproc,
  186. vproc + VOLT_TOL);
  187. }
  188. static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
  189. unsigned int index)
  190. {
  191. struct cpufreq_frequency_table *freq_table = policy->freq_table;
  192. struct clk *cpu_clk = policy->clk;
  193. struct clk *armpll = clk_get_parent(cpu_clk);
  194. struct mtk_cpu_dvfs_info *info = policy->driver_data;
  195. struct device *cpu_dev = info->cpu_dev;
  196. struct dev_pm_opp *opp;
  197. long freq_hz, old_freq_hz;
  198. int vproc, old_vproc, inter_vproc, target_vproc, ret;
  199. inter_vproc = info->intermediate_voltage;
  200. old_freq_hz = clk_get_rate(cpu_clk);
  201. old_vproc = regulator_get_voltage(info->proc_reg);
  202. if (old_vproc < 0) {
  203. pr_err("%s: invalid Vproc value: %d\n", __func__, old_vproc);
  204. return old_vproc;
  205. }
  206. freq_hz = freq_table[index].frequency * 1000;
  207. opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
  208. if (IS_ERR(opp)) {
  209. pr_err("cpu%d: failed to find OPP for %ld\n",
  210. policy->cpu, freq_hz);
  211. return PTR_ERR(opp);
  212. }
  213. vproc = dev_pm_opp_get_voltage(opp);
  214. dev_pm_opp_put(opp);
  215. /*
  216. * If the new voltage or the intermediate voltage is higher than the
  217. * current voltage, scale up voltage first.
  218. */
  219. target_vproc = (inter_vproc > vproc) ? inter_vproc : vproc;
  220. if (old_vproc < target_vproc) {
  221. ret = mtk_cpufreq_set_voltage(info, target_vproc);
  222. if (ret) {
  223. pr_err("cpu%d: failed to scale up voltage!\n",
  224. policy->cpu);
  225. mtk_cpufreq_set_voltage(info, old_vproc);
  226. return ret;
  227. }
  228. }
  229. /* Reparent the CPU clock to intermediate clock. */
  230. ret = clk_set_parent(cpu_clk, info->inter_clk);
  231. if (ret) {
  232. pr_err("cpu%d: failed to re-parent cpu clock!\n",
  233. policy->cpu);
  234. mtk_cpufreq_set_voltage(info, old_vproc);
  235. WARN_ON(1);
  236. return ret;
  237. }
  238. /* Set the original PLL to target rate. */
  239. ret = clk_set_rate(armpll, freq_hz);
  240. if (ret) {
  241. pr_err("cpu%d: failed to scale cpu clock rate!\n",
  242. policy->cpu);
  243. clk_set_parent(cpu_clk, armpll);
  244. mtk_cpufreq_set_voltage(info, old_vproc);
  245. return ret;
  246. }
  247. /* Set parent of CPU clock back to the original PLL. */
  248. ret = clk_set_parent(cpu_clk, armpll);
  249. if (ret) {
  250. pr_err("cpu%d: failed to re-parent cpu clock!\n",
  251. policy->cpu);
  252. mtk_cpufreq_set_voltage(info, inter_vproc);
  253. WARN_ON(1);
  254. return ret;
  255. }
  256. /*
  257. * If the new voltage is lower than the intermediate voltage or the
  258. * original voltage, scale down to the new voltage.
  259. */
  260. if (vproc < inter_vproc || vproc < old_vproc) {
  261. ret = mtk_cpufreq_set_voltage(info, vproc);
  262. if (ret) {
  263. pr_err("cpu%d: failed to scale down voltage!\n",
  264. policy->cpu);
  265. clk_set_parent(cpu_clk, info->inter_clk);
  266. clk_set_rate(armpll, old_freq_hz);
  267. clk_set_parent(cpu_clk, armpll);
  268. return ret;
  269. }
  270. }
  271. return 0;
  272. }
  273. #define DYNAMIC_POWER "dynamic-power-coefficient"
  274. static void mtk_cpufreq_ready(struct cpufreq_policy *policy)
  275. {
  276. struct mtk_cpu_dvfs_info *info = policy->driver_data;
  277. struct device_node *np = of_node_get(info->cpu_dev->of_node);
  278. u32 capacitance = 0;
  279. if (WARN_ON(!np))
  280. return;
  281. if (of_find_property(np, "#cooling-cells", NULL)) {
  282. of_property_read_u32(np, DYNAMIC_POWER, &capacitance);
  283. info->cdev = of_cpufreq_power_cooling_register(np,
  284. policy, capacitance, NULL);
  285. if (IS_ERR(info->cdev)) {
  286. dev_err(info->cpu_dev,
  287. "running cpufreq without cooling device: %ld\n",
  288. PTR_ERR(info->cdev));
  289. info->cdev = NULL;
  290. }
  291. }
  292. of_node_put(np);
  293. }
  294. static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
  295. {
  296. struct device *cpu_dev;
  297. struct regulator *proc_reg = ERR_PTR(-ENODEV);
  298. struct regulator *sram_reg = ERR_PTR(-ENODEV);
  299. struct clk *cpu_clk = ERR_PTR(-ENODEV);
  300. struct clk *inter_clk = ERR_PTR(-ENODEV);
  301. struct dev_pm_opp *opp;
  302. unsigned long rate;
  303. int ret;
  304. cpu_dev = get_cpu_device(cpu);
  305. if (!cpu_dev) {
  306. pr_err("failed to get cpu%d device\n", cpu);
  307. return -ENODEV;
  308. }
  309. cpu_clk = clk_get(cpu_dev, "cpu");
  310. if (IS_ERR(cpu_clk)) {
  311. if (PTR_ERR(cpu_clk) == -EPROBE_DEFER)
  312. pr_warn("cpu clk for cpu%d not ready, retry.\n", cpu);
  313. else
  314. pr_err("failed to get cpu clk for cpu%d\n", cpu);
  315. ret = PTR_ERR(cpu_clk);
  316. return ret;
  317. }
  318. inter_clk = clk_get(cpu_dev, "intermediate");
  319. if (IS_ERR(inter_clk)) {
  320. if (PTR_ERR(inter_clk) == -EPROBE_DEFER)
  321. pr_warn("intermediate clk for cpu%d not ready, retry.\n",
  322. cpu);
  323. else
  324. pr_err("failed to get intermediate clk for cpu%d\n",
  325. cpu);
  326. ret = PTR_ERR(inter_clk);
  327. goto out_free_resources;
  328. }
  329. proc_reg = regulator_get_exclusive(cpu_dev, "proc");
  330. if (IS_ERR(proc_reg)) {
  331. if (PTR_ERR(proc_reg) == -EPROBE_DEFER)
  332. pr_warn("proc regulator for cpu%d not ready, retry.\n",
  333. cpu);
  334. else
  335. pr_err("failed to get proc regulator for cpu%d\n",
  336. cpu);
  337. ret = PTR_ERR(proc_reg);
  338. goto out_free_resources;
  339. }
  340. /* Both presence and absence of sram regulator are valid cases. */
  341. sram_reg = regulator_get_exclusive(cpu_dev, "sram");
  342. /* Get OPP-sharing information from "operating-points-v2" bindings */
  343. ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, &info->cpus);
  344. if (ret) {
  345. pr_err("failed to get OPP-sharing information for cpu%d\n",
  346. cpu);
  347. goto out_free_resources;
  348. }
  349. ret = dev_pm_opp_of_cpumask_add_table(&info->cpus);
  350. if (ret) {
  351. pr_warn("no OPP table for cpu%d\n", cpu);
  352. goto out_free_resources;
  353. }
  354. /* Search a safe voltage for intermediate frequency. */
  355. rate = clk_get_rate(inter_clk);
  356. opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate);
  357. if (IS_ERR(opp)) {
  358. pr_err("failed to get intermediate opp for cpu%d\n", cpu);
  359. ret = PTR_ERR(opp);
  360. goto out_free_opp_table;
  361. }
  362. info->intermediate_voltage = dev_pm_opp_get_voltage(opp);
  363. dev_pm_opp_put(opp);
  364. info->cpu_dev = cpu_dev;
  365. info->proc_reg = proc_reg;
  366. info->sram_reg = IS_ERR(sram_reg) ? NULL : sram_reg;
  367. info->cpu_clk = cpu_clk;
  368. info->inter_clk = inter_clk;
  369. /*
  370. * If SRAM regulator is present, software "voltage tracking" is needed
  371. * for this CPU power domain.
  372. */
  373. info->need_voltage_tracking = !IS_ERR(sram_reg);
  374. return 0;
  375. out_free_opp_table:
  376. dev_pm_opp_of_cpumask_remove_table(&info->cpus);
  377. out_free_resources:
  378. if (!IS_ERR(proc_reg))
  379. regulator_put(proc_reg);
  380. if (!IS_ERR(sram_reg))
  381. regulator_put(sram_reg);
  382. if (!IS_ERR(cpu_clk))
  383. clk_put(cpu_clk);
  384. if (!IS_ERR(inter_clk))
  385. clk_put(inter_clk);
  386. return ret;
  387. }
  388. static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info)
  389. {
  390. if (!IS_ERR(info->proc_reg))
  391. regulator_put(info->proc_reg);
  392. if (!IS_ERR(info->sram_reg))
  393. regulator_put(info->sram_reg);
  394. if (!IS_ERR(info->cpu_clk))
  395. clk_put(info->cpu_clk);
  396. if (!IS_ERR(info->inter_clk))
  397. clk_put(info->inter_clk);
  398. dev_pm_opp_of_cpumask_remove_table(&info->cpus);
  399. }
  400. static int mtk_cpufreq_init(struct cpufreq_policy *policy)
  401. {
  402. struct mtk_cpu_dvfs_info *info;
  403. struct cpufreq_frequency_table *freq_table;
  404. int ret;
  405. info = mtk_cpu_dvfs_info_lookup(policy->cpu);
  406. if (!info) {
  407. pr_err("dvfs info for cpu%d is not initialized.\n",
  408. policy->cpu);
  409. return -EINVAL;
  410. }
  411. ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table);
  412. if (ret) {
  413. pr_err("failed to init cpufreq table for cpu%d: %d\n",
  414. policy->cpu, ret);
  415. return ret;
  416. }
  417. ret = cpufreq_table_validate_and_show(policy, freq_table);
  418. if (ret) {
  419. pr_err("%s: invalid frequency table: %d\n", __func__, ret);
  420. goto out_free_cpufreq_table;
  421. }
  422. cpumask_copy(policy->cpus, &info->cpus);
  423. policy->driver_data = info;
  424. policy->clk = info->cpu_clk;
  425. return 0;
  426. out_free_cpufreq_table:
  427. dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table);
  428. return ret;
  429. }
  430. static int mtk_cpufreq_exit(struct cpufreq_policy *policy)
  431. {
  432. struct mtk_cpu_dvfs_info *info = policy->driver_data;
  433. cpufreq_cooling_unregister(info->cdev);
  434. dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table);
  435. return 0;
  436. }
  437. static struct cpufreq_driver mtk_cpufreq_driver = {
  438. .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK |
  439. CPUFREQ_HAVE_GOVERNOR_PER_POLICY,
  440. .verify = cpufreq_generic_frequency_table_verify,
  441. .target_index = mtk_cpufreq_set_target,
  442. .get = cpufreq_generic_get,
  443. .init = mtk_cpufreq_init,
  444. .exit = mtk_cpufreq_exit,
  445. .ready = mtk_cpufreq_ready,
  446. .name = "mtk-cpufreq",
  447. .attr = cpufreq_generic_attr,
  448. };
  449. static int mtk_cpufreq_probe(struct platform_device *pdev)
  450. {
  451. struct mtk_cpu_dvfs_info *info, *tmp;
  452. int cpu, ret;
  453. for_each_possible_cpu(cpu) {
  454. info = mtk_cpu_dvfs_info_lookup(cpu);
  455. if (info)
  456. continue;
  457. info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
  458. if (!info) {
  459. ret = -ENOMEM;
  460. goto release_dvfs_info_list;
  461. }
  462. ret = mtk_cpu_dvfs_info_init(info, cpu);
  463. if (ret) {
  464. dev_err(&pdev->dev,
  465. "failed to initialize dvfs info for cpu%d\n",
  466. cpu);
  467. goto release_dvfs_info_list;
  468. }
  469. list_add(&info->list_head, &dvfs_info_list);
  470. }
  471. ret = cpufreq_register_driver(&mtk_cpufreq_driver);
  472. if (ret) {
  473. dev_err(&pdev->dev, "failed to register mtk cpufreq driver\n");
  474. goto release_dvfs_info_list;
  475. }
  476. return 0;
  477. release_dvfs_info_list:
  478. list_for_each_entry_safe(info, tmp, &dvfs_info_list, list_head) {
  479. mtk_cpu_dvfs_info_release(info);
  480. list_del(&info->list_head);
  481. }
  482. return ret;
  483. }
  484. static struct platform_driver mtk_cpufreq_platdrv = {
  485. .driver = {
  486. .name = "mtk-cpufreq",
  487. },
  488. .probe = mtk_cpufreq_probe,
  489. };
  490. /* List of machines supported by this driver */
  491. static const struct of_device_id mtk_cpufreq_machines[] __initconst = {
  492. { .compatible = "mediatek,mt2701", },
  493. { .compatible = "mediatek,mt7622", },
  494. { .compatible = "mediatek,mt7623", },
  495. { .compatible = "mediatek,mt817x", },
  496. { .compatible = "mediatek,mt8173", },
  497. { .compatible = "mediatek,mt8176", },
  498. { }
  499. };
  500. static int __init mtk_cpufreq_driver_init(void)
  501. {
  502. struct device_node *np;
  503. const struct of_device_id *match;
  504. struct platform_device *pdev;
  505. int err;
  506. np = of_find_node_by_path("/");
  507. if (!np)
  508. return -ENODEV;
  509. match = of_match_node(mtk_cpufreq_machines, np);
  510. of_node_put(np);
  511. if (!match) {
  512. pr_warn("Machine is not compatible with mtk-cpufreq\n");
  513. return -ENODEV;
  514. }
  515. err = platform_driver_register(&mtk_cpufreq_platdrv);
  516. if (err)
  517. return err;
  518. /*
  519. * Since there's no place to hold device registration code and no
  520. * device tree based way to match cpufreq driver yet, both the driver
  521. * and the device registration codes are put here to handle defer
  522. * probing.
  523. */
  524. pdev = platform_device_register_simple("mtk-cpufreq", -1, NULL, 0);
  525. if (IS_ERR(pdev)) {
  526. pr_err("failed to register mtk-cpufreq platform device\n");
  527. return PTR_ERR(pdev);
  528. }
  529. return 0;
  530. }
  531. device_initcall(mtk_cpufreq_driver_init);