sec_argos.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. /*
  2. * argos.c
  3. *
  4. * Copyright (c) 2012-2023 Samsung Electronics Co., Ltd
  5. * http://www.samsung.com
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation; either version 2 of the License, or (at your
  10. * option) any later version.
  11. *
  12. */
  13. #define pr_fmt(fmt) KBUILD_MODNAME ":%s() " fmt, __func__
  14. #include <linux/kernel.h>
  15. #include <linux/module.h>
  16. #include <linux/device.h>
  17. #include <linux/pm_qos.h>
  18. #include <linux/reboot.h>
  19. #include <linux/of.h>
  20. #include <linux/gfp.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/delay.h>
  23. #include <linux/sched.h>
  24. #include <linux/slab.h>
  25. #include <linux/list.h>
  26. #include <linux/cpumask.h>
  27. #include <linux/interrupt.h>
  28. #ifdef CONFIG_ARGOS_THROUGHPUT
  29. #include <linux/miscdevice.h>
  30. #include <linux/fs.h>
  31. #include <linux/uaccess.h>
  32. #endif
  33. #if defined(CONFIG_ARCH_LAHAINA) || defined(CONFIG_ARGOS_VOTING_DDR)
  34. #define ARGOS_VOTING_DDR_CLK
  35. #include <linux/interconnect.h>
  36. #endif
  37. #if IS_ENABLED(CONFIG_CPU_FREQ_LIMIT)
  38. #include <linux/cpufreq.h>
  39. #include <linux/cpufreq_limit.h>
  40. #ifndef CONFIG_CPU_FREQ_LIMIT_USERSPACE
  41. #define DVFS_ARGOS_ID CFLM_ARGOS
  42. int set_freq_limit(unsigned long id, unsigned int freq);
  43. #endif
  44. #else
  45. #define DVFS_ARGOS_ID 0
  46. int set_freq_limit(unsigned long id, unsigned int freq)
  47. {
  48. pr_err("%s is not yet implemented\n", __func__);
  49. return 0;
  50. }
  51. #endif
  52. #define ARGOS_NAME "argos"
  53. #define TYPE_SHIFT 4
  54. #define TYPE_MASK_BIT ((1 << TYPE_SHIFT) - 1)
  55. #define LOCK_RELEASE 0
  56. #define FREQ_UNLOCK -1
  57. #define SKIP_FREQ_UPDATE 0
  58. #define FREQ_UPDATE 1
  59. #define CPU_UNLOCK_FREQ -1
  60. #ifdef ARGOS_VOTING_DDR_CLK
  61. #define DDR_UNLOCK_FREQ 0
  62. #endif
  63. //Refer to "include/dt-bindings/interconnect/qcom,lahaina.h"
  64. #define MASTER_APPSS_PROC 2
  65. #define SLAVE_EBI1 512
  66. #define BUS_W 4 /* SM8350 DDR Voting('w' for DDR is 4) */
  67. #define MHZ_TO_KBPS(mhz, w) ((uint64_t)mhz * 1000 * w)
  68. static DEFINE_SPINLOCK(argos_irq_lock);
  69. static DEFINE_SPINLOCK(argos_task_lock);
  70. static DEFINE_SPINLOCK(argos_boost_list_lock);
  71. enum {
  72. THRESHOLD,
  73. BIG_MIN_FREQ,
  74. BIG_MAX_FREQ,
  75. LITTLE_MIN_FREQ,
  76. LITTLE_MAX_FREQ,
  77. DDR_FREQ,
  78. RESERVED,
  79. TASK_AFFINITY_EN,
  80. IRQ_AFFINITY_EN,
  81. SCHED_BOOST_EN,
  82. ITEM_MAX,
  83. };
  84. enum {
  85. BOOST_CPU,
  86. #ifdef ARGOS_VOTING_DDR_CLK
  87. BOOST_DDR,
  88. #endif
  89. BOOST_MAX
  90. };
  91. struct boost_table {
  92. unsigned int items[ITEM_MAX];
  93. };
  94. struct argos_task_affinity {
  95. struct task_struct *p;
  96. struct cpumask *affinity_cpu_mask;
  97. struct cpumask *default_cpu_mask;
  98. struct list_head entry;
  99. };
  100. struct argos_irq_affinity {
  101. unsigned int irq;
  102. struct cpumask *affinity_cpu_mask;
  103. struct cpumask *default_cpu_mask;
  104. struct list_head entry;
  105. };
  106. struct argos {
  107. const char *desc;
  108. struct platform_device *pdev;
  109. struct boost_table *tables;
  110. int ntables;
  111. int prev_level;
  112. struct list_head task_affinity_list;
  113. bool task_hotplug_disable;
  114. struct list_head irq_affinity_list;
  115. bool irq_hotplug_disable;
  116. bool hmpboost_enable;
  117. bool argos_block;
  118. struct blocking_notifier_head argos_notifier;
  119. /* protect prev_level, qos, task/irq_hotplug_disable, hmpboost_enable */
  120. struct mutex level_mutex;
  121. };
  122. #ifdef CONFIG_ARGOS_THROUGHPUT
  123. #define TPUT_MAX 16
  124. char argos_throughput[TPUT_MAX];
  125. #endif
  126. struct argos_platform_data {
  127. struct argos *devices;
  128. struct device *dev;
  129. int ndevice;
  130. #ifndef CONFIG_ARGOS_THROUGHPUT
  131. struct notifier_block pm_qos_nfb;
  132. #endif
  133. int *boost_list[BOOST_MAX];
  134. int boost_max[BOOST_MAX];
  135. };
  136. static struct argos_platform_data *argos_pdata;
  137. static int boost_unlock_freq[BOOST_MAX] = {
  138. CPU_UNLOCK_FREQ
  139. #ifdef ARGOS_VOTING_DDR_CLK
  140. , DDR_UNLOCK_FREQ
  141. #endif
  142. };
  143. #ifdef ARGOS_VOTING_DDR_CLK
  144. struct icc_path *path_argos_bw;
  145. int argos_icc_register = 0;
  146. #endif
  147. static int argos_find_index(const char *label)
  148. {
  149. int i;
  150. int dev_num = -1;
  151. if (!argos_pdata) {
  152. pr_err("argos not initialized\n");
  153. return -1;
  154. }
  155. for (i = 0; i < argos_pdata->ndevice; i++)
  156. if (strcmp(argos_pdata->devices[i].desc, label) == 0)
  157. dev_num = i;
  158. return dev_num;
  159. }
  160. int sec_argos_register_notifier(struct notifier_block *n, char *label)
  161. {
  162. struct blocking_notifier_head *cnotifier;
  163. int dev_num;
  164. dev_num = argos_find_index(label);
  165. if (dev_num < 0) {
  166. pr_err("No match found for label: %d", dev_num);
  167. return -ENODEV;
  168. }
  169. cnotifier = &argos_pdata->devices[dev_num].argos_notifier;
  170. if (!cnotifier) {
  171. pr_err("argos notifier not found(dev_num:%d)\n", dev_num);
  172. return -ENXIO;
  173. }
  174. pr_info("%pf(dev_num:%d)\n", n->notifier_call, dev_num);
  175. return blocking_notifier_chain_register(cnotifier, n);
  176. }
  177. EXPORT_SYMBOL_GPL(sec_argos_register_notifier);
  178. int sec_argos_unregister_notifier(struct notifier_block *n, char *label)
  179. {
  180. struct blocking_notifier_head *cnotifier;
  181. int dev_num;
  182. dev_num = argos_find_index(label);
  183. if (dev_num < 0) {
  184. pr_err("No match found for label: %d", dev_num);
  185. return -ENODEV;
  186. }
  187. cnotifier = &argos_pdata->devices[dev_num].argos_notifier;
  188. if (!cnotifier) {
  189. pr_err("argos notifier not found(dev_num:%d)\n", dev_num);
  190. return -ENXIO;
  191. }
  192. pr_info("%pf(dev_num:%d)\n", n->notifier_call, dev_num);
  193. return blocking_notifier_chain_unregister(cnotifier, n);
  194. }
  195. EXPORT_SYMBOL_GPL(sec_argos_unregister_notifier);
  196. static int argos_task_affinity_setup(struct task_struct *p, int dev_num,
  197. struct cpumask *affinity_cpu_mask,
  198. struct cpumask *default_cpu_mask)
  199. {
  200. struct argos_task_affinity *this;
  201. struct list_head *head;
  202. if (!argos_pdata) {
  203. pr_err("argos not initialized\n");
  204. return -ENXIO;
  205. }
  206. if (dev_num < 0 || dev_num >= argos_pdata->ndevice) {
  207. pr_err("dev_num:%d should be dev_num:0 ~ %d in boundary\n",
  208. dev_num, argos_pdata->ndevice - 1);
  209. return -EINVAL;
  210. }
  211. head = &argos_pdata->devices[dev_num].task_affinity_list;
  212. this = kzalloc(sizeof(*this), GFP_ATOMIC);
  213. if (!this)
  214. return -ENOMEM;
  215. this->p = p;
  216. this->affinity_cpu_mask = affinity_cpu_mask;
  217. this->default_cpu_mask = default_cpu_mask;
  218. spin_lock(&argos_task_lock);
  219. list_add(&this->entry, head);
  220. spin_unlock(&argos_task_lock);
  221. return 0;
  222. }
  223. int argos_task_affinity_setup_label(struct task_struct *p, const char *label,
  224. struct cpumask *affinity_cpu_mask,
  225. struct cpumask *default_cpu_mask)
  226. {
  227. int dev_num;
  228. dev_num = argos_find_index(label);
  229. return argos_task_affinity_setup(p, dev_num, affinity_cpu_mask,
  230. default_cpu_mask);
  231. }
  232. static int argos_irq_affinity_setup(unsigned int irq, int dev_num,
  233. struct cpumask *affinity_cpu_mask,
  234. struct cpumask *default_cpu_mask)
  235. {
  236. struct argos_irq_affinity *this;
  237. struct list_head *head;
  238. if (!argos_pdata) {
  239. pr_err("argos not initialized\n");
  240. return -ENXIO;
  241. }
  242. if (dev_num < 0 || dev_num >= argos_pdata->ndevice) {
  243. pr_err("dev_num:%d should be dev_num:0 ~ %d in boundary\n",
  244. dev_num, argos_pdata->ndevice - 1);
  245. return -EINVAL;
  246. }
  247. head = &argos_pdata->devices[dev_num].irq_affinity_list;
  248. this = kzalloc(sizeof(*this), GFP_ATOMIC);
  249. if (!this)
  250. return -ENOMEM;
  251. this->irq = irq;
  252. this->affinity_cpu_mask = affinity_cpu_mask;
  253. this->default_cpu_mask = default_cpu_mask;
  254. spin_lock(&argos_irq_lock);
  255. list_add(&this->entry, head);
  256. spin_unlock(&argos_irq_lock);
  257. return 0;
  258. }
  259. int argos_irq_affinity_setup_label(unsigned int irq, const char *label,
  260. struct cpumask *affinity_cpu_mask,
  261. struct cpumask *default_cpu_mask)
  262. {
  263. int dev_num;
  264. dev_num = argos_find_index(label);
  265. return argos_irq_affinity_setup(irq, dev_num, affinity_cpu_mask,
  266. default_cpu_mask);
  267. }
  268. int argos_task_affinity_apply(int dev_num, bool enable)
  269. {
  270. struct argos_task_affinity *this;
  271. struct list_head *head;
  272. int result = 0;
  273. struct cpumask *mask;
  274. bool *hotplug_disable;
  275. head = &argos_pdata->devices[dev_num].task_affinity_list;
  276. hotplug_disable = &argos_pdata->devices[dev_num].task_hotplug_disable;
  277. if (list_empty(head)) {
  278. pr_debug("task_affinity_list is empty\n");
  279. return result;
  280. }
  281. list_for_each_entry(this, head, entry) {
  282. if (enable) {
  283. if (!*hotplug_disable)
  284. *hotplug_disable = true;
  285. mask = this->affinity_cpu_mask;
  286. } else {
  287. if (*hotplug_disable)
  288. *hotplug_disable = false;
  289. mask = this->default_cpu_mask;
  290. }
  291. result = set_cpus_allowed_ptr(this->p, mask);
  292. pr_info("%s affinity %s to cpu_mask:0x%X\n",
  293. this->p->comm,
  294. (enable ? "enable" : "disable"),
  295. (int)*mask->bits);
  296. }
  297. return result;
  298. }
  299. int argos_irq_affinity_apply(int dev_num, bool enable)
  300. {
  301. struct argos_irq_affinity *this;
  302. struct list_head *head;
  303. int result = 0;
  304. struct cpumask *mask;
  305. bool *hotplug_disable;
  306. head = &argos_pdata->devices[dev_num].irq_affinity_list;
  307. hotplug_disable = &argos_pdata->devices[dev_num].irq_hotplug_disable;
  308. if (list_empty(head)) {
  309. pr_debug("irq_affinity_list is empty\n");
  310. return result;
  311. }
  312. list_for_each_entry(this, head, entry) {
  313. if (enable) {
  314. if (!*hotplug_disable)
  315. *hotplug_disable = true;
  316. mask = this->affinity_cpu_mask;
  317. } else {
  318. if (*hotplug_disable)
  319. *hotplug_disable = false;
  320. mask = this->default_cpu_mask;
  321. }
  322. #ifndef CONFIG_ARGOS_THROUGHPUT
  323. result = irq_set_affinity(this->irq, mask);
  324. #endif
  325. pr_info("irq%d affinity %s to cpu_mask:0x%X\n",
  326. this->irq, (enable ? "enable" : "disable"),
  327. (int)*mask->bits);
  328. }
  329. return result;
  330. }
  331. int argos_hmpboost_apply(int dev_num, bool enable)
  332. {
  333. bool *hmpboost_enable;
  334. hmpboost_enable = &argos_pdata->devices[dev_num].hmpboost_enable;
  335. if (enable) {
  336. /* disable -> enable */
  337. if (!*hmpboost_enable) {
  338. *hmpboost_enable = true;
  339. pr_info("hmp boost enable [%d]\n", dev_num);
  340. }
  341. } else {
  342. /* enable -> disable */
  343. if (*hmpboost_enable) {
  344. *hmpboost_enable = false;
  345. pr_info("hmp boost disable [%d]\n", dev_num);
  346. }
  347. }
  348. return 0;
  349. }
  350. static int find_max(int dev_type, int *freq, int ndevice){
  351. int i, max = boost_unlock_freq[dev_type];
  352. for (i = 0; i < ndevice; i++){
  353. if(freq[i] > max) max = freq[i];
  354. }
  355. return max;
  356. }
  357. static int check_update_freq(int boost_type, int dev_type, int target)
  358. {
  359. int ret = SKIP_FREQ_UPDATE, new_max, prev;
  360. spin_lock(&argos_boost_list_lock);
  361. prev = argos_pdata->boost_list[boost_type][dev_type];
  362. argos_pdata->boost_list[boost_type][dev_type] = target;
  363. new_max = find_max(boost_type, argos_pdata->boost_list[boost_type], \
  364. argos_pdata->ndevice);
  365. spin_unlock(&argos_boost_list_lock);
  366. if(new_max > argos_pdata->boost_max[boost_type] \
  367. || (prev == argos_pdata->boost_max[boost_type] \
  368. && new_max != argos_pdata->boost_max[boost_type])){
  369. argos_pdata->boost_max[boost_type] = new_max;
  370. ret = FREQ_UPDATE;
  371. }
  372. return ret;
  373. }
  374. static void argos_freq_lock(int type, int level)
  375. {
  376. unsigned int big_min_freq, little_min_freq;
  377. int target_freq, need_update;
  378. struct boost_table *t = &argos_pdata->devices[type].tables[level];
  379. const char *cname;
  380. cname = argos_pdata->devices[type].desc;
  381. if(level != FREQ_UNLOCK){
  382. t = &argos_pdata->devices[type].tables[level];
  383. big_min_freq = t->items[BIG_MIN_FREQ];
  384. little_min_freq = t->items[LITTLE_MIN_FREQ];
  385. }
  386. if(level != FREQ_UNLOCK)
  387. target_freq = (big_min_freq > little_min_freq) ?
  388. big_min_freq : little_min_freq;
  389. else
  390. target_freq = boost_unlock_freq[BOOST_CPU];
  391. need_update = check_update_freq(BOOST_CPU, type, target_freq);
  392. if(need_update != SKIP_FREQ_UPDATE){
  393. pr_info("update cpu freq %d\n", argos_pdata->boost_max[BOOST_CPU]);
  394. set_freq_limit(DVFS_ARGOS_ID, argos_pdata->boost_max[BOOST_CPU]);
  395. }
  396. #ifdef ARGOS_VOTING_DDR_CLK
  397. if(level != FREQ_UNLOCK)
  398. target_freq = t->items[DDR_FREQ];
  399. else
  400. target_freq = boost_unlock_freq[BOOST_DDR];
  401. need_update = check_update_freq(BOOST_DDR, type, target_freq);
  402. if(need_update != SKIP_FREQ_UPDATE){
  403. pr_info("update ddr freq %d\n", argos_pdata->boost_max[BOOST_DDR]);
  404. icc_set_bw(path_argos_bw, 0, MHZ_TO_KBPS(argos_pdata->boost_max[BOOST_DDR], BUS_W));
  405. }
  406. #endif
  407. }
  408. void argos_block_enable(char *req_name, bool set)
  409. {
  410. int dev_num;
  411. struct argos *cnode;
  412. dev_num = argos_find_index(req_name);
  413. if (dev_num < 0) {
  414. pr_err("No match found for label: %s", req_name);
  415. return;
  416. }
  417. cnode = &argos_pdata->devices[dev_num];
  418. if (set) {
  419. cnode->argos_block = true;
  420. mutex_lock(&cnode->level_mutex);
  421. argos_freq_lock(dev_num, FREQ_UNLOCK);
  422. argos_task_affinity_apply(dev_num, 0);
  423. argos_irq_affinity_apply(dev_num, 0);
  424. argos_hmpboost_apply(dev_num, 0);
  425. cnode->prev_level = -1;
  426. mutex_unlock(&cnode->level_mutex);
  427. } else {
  428. cnode->argos_block = false;
  429. }
  430. pr_info("req_name:%s block:%d\n",
  431. req_name, cnode->argos_block);
  432. }
  433. #ifndef CONFIG_ARGOS_THROUGHPUT
  434. static int argos_cpuidle_reboot_notifier(struct notifier_block *this,
  435. unsigned long event, void *_cmd)
  436. {
  437. switch (event) {
  438. case SYSTEM_POWER_OFF:
  439. case SYS_RESTART:
  440. pr_info("called\n");
  441. pm_qos_remove_notifier(PM_QOS_NETWORK_THROUGHPUT,
  442. &argos_pdata->pm_qos_nfb);
  443. break;
  444. }
  445. return NOTIFY_OK;
  446. }
  447. static struct notifier_block argos_cpuidle_reboot_nb = {
  448. .notifier_call = argos_cpuidle_reboot_notifier,
  449. };
  450. #endif
  451. #ifdef ARGOS_VOTING_DDR_CLK
  452. static void get_icc_path(void)
  453. {
  454. struct device *dev = argos_pdata->dev;
  455. int bus_ret = 0;
  456. path_argos_bw = icc_get(dev, MASTER_APPSS_PROC, SLAVE_EBI1);
  457. if (IS_ERR(path_argos_bw)) {
  458. bus_ret = PTR_ERR(path_argos_bw);
  459. dev_err(dev, "Failed to get path_argos_bw. ret=%d\n", bus_ret);
  460. if (bus_ret != -EPROBE_DEFER)
  461. dev_err(dev, "Failed to get icc path. ret=%d\n", bus_ret);
  462. } else {
  463. dev_info(dev, "Success to get path_argos_bw.\n");
  464. argos_icc_register = 1;
  465. }
  466. }
  467. #endif
  468. #if defined (CONFIG_ARGOS_THROUGHPUT)
  469. static int argos_pm_qos_notify(unsigned long speedtype)
  470. #else
  471. static int argos_pm_qos_notify(struct notifier_block *nfb,
  472. unsigned long speedtype, void *arg)
  473. #endif
  474. {
  475. int type, level, prev_level;
  476. unsigned long speed;
  477. bool argos_blocked;
  478. struct argos *cnode;
  479. type = (speedtype & TYPE_MASK_BIT) - 1;
  480. if (type < 0 || type > argos_pdata->ndevice) {
  481. pr_err("There is no type for devices type[%d], ndevice[%d]\n",
  482. type, argos_pdata->ndevice);
  483. return NOTIFY_BAD;
  484. }
  485. #ifdef ARGOS_VOTING_DDR_CLK
  486. if (argos_icc_register == 0){
  487. get_icc_path();
  488. }
  489. #endif
  490. speed = speedtype >> TYPE_SHIFT;
  491. cnode = &argos_pdata->devices[type];
  492. prev_level = cnode->prev_level;
  493. argos_blocked = cnode->argos_block;
  494. if (cnode->tables[0].items[THRESHOLD] == 0) {
  495. pr_debug("skip not used name:%s, speed:%ldMbps\n",\
  496. cnode->desc, speed);
  497. goto out;
  498. }
  499. /* Find proper level */
  500. for (level = 0; level < cnode->ntables; level++) {
  501. struct boost_table *t = &cnode->tables[level];
  502. if (speed < t->items[THRESHOLD]) {
  503. break;
  504. } else if (argos_pdata->devices[type].ntables == level) {
  505. level++;
  506. break;
  507. }
  508. }
  509. /* decrease 1 level to match proper table */
  510. level--;
  511. if (!argos_blocked) {
  512. if (level != prev_level) {
  513. if (mutex_trylock(&cnode->level_mutex) == 0) {
  514. /*
  515. * If the mutex is already locked, it means this argos
  516. * is being blocked or is handling another change.
  517. * We don't need to wait.
  518. */
  519. pr_warn("skip name:%s, speed:%ldMbps, prev level:%d, request level:%d\n",
  520. cnode->desc, speed, prev_level, level);
  521. goto out;
  522. }
  523. pr_info("name:%s, speed:%ldMbps, prev level:%d, request level:%d\n",
  524. cnode->desc, speed, prev_level, level);
  525. if (level == FREQ_UNLOCK) {
  526. if (cnode->argos_notifier.head) {
  527. pr_debug("Call argos notifier(%s lev:%d)\n",
  528. cnode->desc, level);
  529. blocking_notifier_call_chain(&cnode->argos_notifier,
  530. speed, NULL);
  531. }
  532. argos_freq_lock(type, FREQ_UNLOCK);
  533. argos_task_affinity_apply(type, 0);
  534. argos_irq_affinity_apply(type, 0);
  535. argos_hmpboost_apply(type, 0);
  536. } else {
  537. unsigned int enable_flag;
  538. argos_freq_lock(type, level);
  539. /* FIXME should control affinity and hmp boost */
  540. enable_flag = argos_pdata->devices[type].tables[level].items[TASK_AFFINITY_EN];
  541. argos_task_affinity_apply(type, enable_flag);
  542. enable_flag = argos_pdata->devices[type].tables[level].items[IRQ_AFFINITY_EN];
  543. argos_irq_affinity_apply(type, enable_flag);
  544. enable_flag =
  545. argos_pdata->devices[type].tables[level].items[SCHED_BOOST_EN];
  546. argos_hmpboost_apply(type, enable_flag);
  547. if (cnode->argos_notifier.head) {
  548. pr_debug("Call argos notifier(%s lev:%d)\n",
  549. cnode->desc, level);
  550. blocking_notifier_call_chain(&cnode->argos_notifier,
  551. speed, NULL);
  552. }
  553. }
  554. cnode->prev_level = level;
  555. mutex_unlock(&cnode->level_mutex);
  556. } else {
  557. pr_debug("same level (%d) is requested", level);
  558. }
  559. }
  560. out:
  561. return NOTIFY_OK;
  562. }
  563. #ifdef CONFIG_OF
  564. static int argos_parse_dt(struct device *dev)
  565. {
  566. struct argos_platform_data *pdata = dev->platform_data;
  567. struct argos *cnode;
  568. struct device_node *np, *cnp;
  569. int device_count = 0, num_level = 0;
  570. int retval = 0, i, j;
  571. np = dev->of_node;
  572. pdata->ndevice = of_get_child_count(np);
  573. if (!pdata->ndevice)
  574. return -ENODEV;
  575. pdata->devices = devm_kzalloc(dev, sizeof(struct argos) * pdata->ndevice, GFP_KERNEL);
  576. if (!pdata->devices)
  577. return -ENOMEM;
  578. for_each_child_of_node(np, cnp) {
  579. cnode = &pdata->devices[device_count];
  580. cnode->desc = of_get_property(cnp, "net_boost,label", NULL);
  581. if (of_property_read_u32(cnp, "net_boost,table_size", &num_level)) {
  582. dev_err(dev, "Failed to get table size: node not exist\n");
  583. retval = -EINVAL;
  584. goto err_out;
  585. }
  586. cnode->ntables = num_level;
  587. /* Allocation for freq and time table */
  588. if (!cnode->tables) {
  589. cnode->tables = devm_kzalloc(dev,
  590. sizeof(struct boost_table) * cnode->ntables, GFP_KERNEL);
  591. if (!cnode->tables) {
  592. retval = -ENOMEM;
  593. goto err_out;
  594. }
  595. }
  596. /* Get and add frequency and time table */
  597. for (i = 0; i < num_level; i++) {
  598. for (j = 0; j < ITEM_MAX; j++) {
  599. retval = of_property_read_u32_index(cnp, "net_boost,table",
  600. i * ITEM_MAX + j, &cnode->tables[i].items[j]);
  601. if (retval) {
  602. dev_err(dev, "Failed to get property\n");
  603. retval = -EINVAL;
  604. goto err_out;
  605. }
  606. }
  607. }
  608. INIT_LIST_HEAD(&cnode->task_affinity_list);
  609. INIT_LIST_HEAD(&cnode->irq_affinity_list);
  610. cnode->task_hotplug_disable = false;
  611. cnode->irq_hotplug_disable = false;
  612. cnode->hmpboost_enable = false;
  613. cnode->argos_block = false;
  614. cnode->prev_level = -1;
  615. mutex_init(&cnode->level_mutex);
  616. BLOCKING_INIT_NOTIFIER_HEAD(&cnode->argos_notifier);
  617. device_count++;
  618. }
  619. return 0;
  620. err_out:
  621. return retval;
  622. }
  623. #endif
  624. static int argos_probe(struct platform_device *pdev)
  625. {
  626. int i, j, ret = 0;
  627. struct argos_platform_data *pdata;
  628. pr_info("Start probe\n");
  629. if (pdev->dev.of_node) {
  630. pdata = devm_kzalloc(&pdev->dev,
  631. sizeof(struct argos_platform_data),
  632. GFP_KERNEL);
  633. if (!pdata) {
  634. dev_err(&pdev->dev, "Failed to allocate platform data\n");
  635. return -ENOMEM;
  636. }
  637. pdev->dev.platform_data = pdata;
  638. ret = argos_parse_dt(&pdev->dev);
  639. if (ret) {
  640. dev_err(&pdev->dev, "Failed to parse dt data\n");
  641. return ret;
  642. }
  643. pr_info("parse dt done\n");
  644. for(i = 0; i < BOOST_MAX; i++){
  645. pdata->boost_list[i] = devm_kzalloc(&pdev->dev, sizeof(int) * pdata->ndevice, GFP_KERNEL);
  646. if (!pdata->boost_list[i]) {
  647. dev_err(&pdev->dev, "Failed to allocate boosting frequency list\n");
  648. return -ENOMEM;
  649. }
  650. for (j = 0; j < pdata->ndevice; j++){
  651. pdata->boost_list[i][j] = boost_unlock_freq[i];
  652. }
  653. pdata->boost_max[i] = boost_unlock_freq[i];
  654. }
  655. } else {
  656. pdata = pdev->dev.platform_data;
  657. }
  658. if (!pdata) {
  659. dev_err(&pdev->dev, "There are no platform data\n");
  660. return -EINVAL;
  661. }
  662. if (!pdata->ndevice || !pdata->devices) {
  663. dev_err(&pdev->dev, "There are no devices\n");
  664. return -EINVAL;
  665. }
  666. #ifndef CONFIG_ARGOS_THROUGHPUT
  667. pdata->pm_qos_nfb.notifier_call = argos_pm_qos_notify;
  668. pm_qos_add_notifier(PM_QOS_NETWORK_THROUGHPUT, &pdata->pm_qos_nfb);
  669. register_reboot_notifier(&argos_cpuidle_reboot_nb);
  670. #endif
  671. argos_pdata = pdata;
  672. argos_pdata->dev = &pdev->dev;
  673. platform_set_drvdata(pdev, pdata);
  674. return 0;
  675. }
  676. static int argos_remove(struct platform_device *pdev)
  677. {
  678. struct argos_platform_data *pdata = platform_get_drvdata(pdev);
  679. if (!pdata || !argos_pdata)
  680. return 0;
  681. #ifndef CONFIG_ARGOS_THROUGHPUT
  682. pm_qos_remove_notifier(PM_QOS_NETWORK_THROUGHPUT, &pdata->pm_qos_nfb);
  683. unregister_reboot_notifier(&argos_cpuidle_reboot_nb);
  684. #endif
  685. #ifdef ARGOS_VOTING_DDR_CLK
  686. if (argos_icc_register == 1)
  687. icc_put(path_argos_bw);
  688. #endif
  689. return 0;
  690. }
  691. #ifdef CONFIG_OF
  692. static const struct of_device_id argos_dt_ids[] = {
  693. { .compatible = "samsung,argos"},
  694. { }
  695. };
  696. #endif
  697. static struct platform_driver argos_driver = {
  698. .driver = {
  699. .name = ARGOS_NAME,
  700. .owner = THIS_MODULE,
  701. #ifdef CONFIG_OF
  702. .of_match_table = of_match_ptr(argos_dt_ids),
  703. #endif
  704. },
  705. .probe = argos_probe,
  706. .remove = argos_remove
  707. };
  708. #ifdef CONFIG_ARGOS_THROUGHPUT
  709. static ssize_t argos_tput_read(struct file *filep, char __user *buf,
  710. size_t count, loff_t *ppos)
  711. {
  712. int ret;
  713. //pr_info("argos_throughput %s\n", argos_throughput);
  714. ret = copy_to_user(buf, (void *)argos_throughput, TPUT_MAX);
  715. if (ret < 0) {
  716. pr_err("fail to copy argos throughput value.\n");
  717. return -EINVAL;
  718. }
  719. return ret;
  720. }
  721. static ssize_t argos_tput_write(struct file *filep, const char __user *buf,
  722. size_t count, loff_t *ppos)
  723. {
  724. int ret;
  725. unsigned long val;
  726. ret = copy_from_user(argos_throughput, buf, TPUT_MAX);
  727. if (ret < 0) {
  728. pr_err("fail to get argos throughput value.\n");
  729. return -EINVAL;
  730. }
  731. ret = kstrtoul(argos_throughput, 16, &val);
  732. if (ret < 0) {
  733. pr_err("fail to convertet throughput unsigned long.\n");
  734. return -EINVAL;
  735. }
  736. argos_pm_qos_notify(val);
  737. //pr_info("tput : %s\n", argos_throughput);
  738. return count;
  739. }
  740. static const struct file_operations argos_tput_fops = {
  741. .owner = THIS_MODULE,
  742. .open = NULL,
  743. .read = argos_tput_read,
  744. .write = argos_tput_write,
  745. .llseek = NULL,
  746. };
  747. static struct miscdevice argos_tput_miscdev = {
  748. .minor = MISC_DYNAMIC_MINOR,
  749. .name = "network_throughput",
  750. .fops = &argos_tput_fops,
  751. };
  752. #endif
  753. static int __init argos_init(void)
  754. {
  755. int ret;
  756. #ifdef CONFIG_ARGOS_THROUGHPUT
  757. ret = misc_register(&argos_tput_miscdev);
  758. if (ret) {
  759. pr_err("Failed to register miscdevice");
  760. goto err;
  761. }
  762. #endif
  763. ret = platform_driver_register(&argos_driver);
  764. if (ret) {
  765. pr_err("Failed to register platform driver");
  766. goto err;
  767. }
  768. err:
  769. return ret;
  770. }
  771. static void __exit argos_exit(void)
  772. {
  773. return platform_driver_unregister(&argos_driver);
  774. }
  775. late_initcall(argos_init);
  776. module_exit(argos_exit);
  777. MODULE_LICENSE("GPL");
  778. MODULE_AUTHOR("SAMSUNG Electronics");
  779. MODULE_DESCRIPTION("ARGOS DEVICE");