halapi: power: Remove duplicate code
[platform/hal/api/power.git] / src / hal-api-power.c
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdint.h>
19 #include <dlfcn.h>
20 #include <dlog.h>
21
22 #include <hal/hal-common.h>
23
24 #include "hal-power-interface.h"
25 #include "hal-power.h"
26 #include "common.h"
27
28 #ifndef EXPORT
29 #define EXPORT __attribute__ ((visibility("default")))
30 #endif
31
32 #define ARRAY_SIZE(name)        (sizeof(name)/sizeof(name[0]))
33 #define FAULT_AROUND_BYTES_4K   4096
34
35 static hal_backend_power_funcs *g_power_funcs = NULL;
36 static unsigned int g_power_funcs_count = 0;
37
38 static int is_supported_from_backend(hal_backend_power_funcs *funcs, int res_type)
39 {
40         switch (res_type) {
41         case PASS_RESOURCE_CPU_ID:
42                 if (funcs && funcs->cpu)
43                         return 1;
44                 break;
45         case PASS_RESOURCE_BUS_ID:
46                 if (funcs && funcs->bus)
47                         return 1;
48                 break;
49         case PASS_RESOURCE_GPU_ID:
50                 if (funcs && funcs->gpu)
51                         return 1;
52                 break;
53         case PASS_RESOURCE_MEMORY_ID:
54                 if (funcs && funcs->memory)
55                         return 1;
56                 break;
57         case PASS_RESOURCE_BATTERY_ID:
58                 if (funcs && funcs->battery)
59                         return 1;
60                 break;
61         case PASS_RESOURCE_NONSTANDARD_ID:
62                 if (funcs && funcs->nonstandard)
63                         return 1;
64                 break;
65         case PASS_RESOURCE_PROCESS_ID:
66         case PASS_RESOURCE_DISPLAY_ID:
67         case PASS_RESOURCE_SYSTEM_ID:
68         case PASS_RESOURCE_PROCESS_GROUP_ID:
69         case PASS_RESOURCE_DISK_ID:
70         case PASS_RESOURCE_NETWORK_ID:
71                 /*
72                  * These resource types have not yet needed any hal backend.
73                  * But, these resource types might need the resource
74                  * configuration according to hardware device.
75                  */
76                 return 1;
77         }
78
79         return 0;
80 }
81
82 static int get_dvfs(hal_backend_power_funcs *funcs, int res_type, char *res_name,
83                                         struct pass_resource_dvfs_ops **dvfs)
84 {
85         if (!funcs)
86                 return -ENOTSUP;
87         else if (!res_name)
88                 return -EINVAL;
89
90         switch (res_type) {
91         case PASS_RESOURCE_CPU_ID:
92                 if (funcs && funcs->cpu)
93                         *dvfs = &(funcs->cpu->dvfs);
94                 break;
95         case PASS_RESOURCE_BUS_ID:
96                 if (funcs && funcs->bus)
97                         *dvfs = &(funcs->bus->dvfs);
98                 break;
99         case PASS_RESOURCE_GPU_ID:
100                 if (funcs && funcs->gpu)
101                         *dvfs = &(funcs->gpu->dvfs);
102                 break;
103         default:
104                 return -EPERM;
105         }
106
107         return 0;
108 }
109
110 static int get_tmu(hal_backend_power_funcs *funcs, int res_type, char *res_name,
111                                         struct pass_resource_tmu_ops **tmu)
112 {
113         if (!funcs)
114                 return -ENOTSUP;
115         else if (!res_name)
116                 return -EINVAL;
117
118         switch (res_type) {
119         case PASS_RESOURCE_CPU_ID:
120                 if (funcs && funcs->cpu)
121                         *tmu = &(funcs->cpu->tmu);
122                 break;
123         case PASS_RESOURCE_BUS_ID:
124                 if (funcs && funcs->bus)
125                         *tmu = &(funcs->bus->tmu);
126                 break;
127         case PASS_RESOURCE_GPU_ID:
128                 if (funcs && funcs->gpu)
129                         *tmu = &(funcs->gpu->tmu);
130                 break;
131         case PASS_RESOURCE_BATTERY_ID:
132                 if (funcs && funcs->battery)
133                         *tmu = &(funcs->battery->tmu);
134                 break;
135         case PASS_RESOURCE_NONSTANDARD_ID:
136                 if (funcs && funcs->nonstandard)
137                         *tmu = &(funcs->nonstandard->tmu);
138                 break;
139         default:
140                 return -EPERM;
141         }
142
143         return 0;
144 }
145
146 static int get_hotplug(hal_backend_power_funcs *funcs, int res_type, char *res_name,
147                                 struct pass_resource_hotplug_ops **hotplug)
148 {
149         if (!funcs)
150                 return -ENOTSUP;
151         else if (!res_name)
152                 return -EINVAL;
153
154         switch (res_type) {
155         case PASS_RESOURCE_CPU_ID:
156                 if (funcs && funcs->cpu)
157                         *hotplug = &(funcs->cpu->hotplug);
158                 break;
159         default:
160                 return -EPERM;
161         }
162
163         return 0;
164 }
165
166 static int get_charging(hal_backend_power_funcs *funcs, int res_type, char *res_name,
167                                 struct pass_resource_battery_ops **charging)
168 {
169         if (!funcs)
170                 return -ENOTSUP;
171         else if (!res_name)
172                 return -EINVAL;
173
174         switch (res_type) {
175         case PASS_RESOURCE_BATTERY_ID:
176                 if (funcs && funcs->battery)
177                         *charging = &(funcs->battery->battery);
178                 break;
179         case PASS_RESOURCE_NONSTANDARD_ID:
180                 if (funcs && funcs->nonstandard)
181                         *charging = &(funcs->nonstandard->battery);
182                 break;
183         default:
184                 return -EPERM;
185         }
186
187         return 0;
188 }
189
190 EXPORT int hal_power_get_backend(unsigned int res_type)
191 {
192         g_power_funcs_count++;
193
194         if (!g_power_funcs) {
195                 int ret;
196
197                 ret = hal_common_get_backend(HAL_MODULE_POWER,
198                                         (void **)&g_power_funcs);
199                 if (ret < 0) {
200                         _E("Failed to get backend of HAL_MODULE_POWER\n");
201                         return ret;
202                 }
203         }
204
205         if (!is_supported_from_backend(g_power_funcs, res_type)) {
206                 _E("Don't support resource(%d) from HAL_MODULE_POWER backend\n",
207                                 res_type);
208                 return -ENOTSUP;
209         }
210
211         return 0;
212 }
213
214 EXPORT int hal_power_put_backend(void)
215 {
216         if (!g_power_funcs_count)
217                 return 0;
218
219         if (--g_power_funcs_count > 0)
220                 return 0;
221
222         hal_common_put_backend(HAL_MODULE_POWER, (void *)g_power_funcs);
223         g_power_funcs = NULL;
224
225         return 0;
226 }
227
228 static int is_valid_param_with_str(char *res_name, char *str)
229 {
230         if (!g_power_funcs)
231                 return -ENOTSUP;
232         else if (!res_name || !str)
233                 return -EINVAL;
234         return 0;
235 }
236
237 static int is_valid_param_with_int(char *res_name, int val)
238 {
239         if (!g_power_funcs)
240                 return -ENOTSUP;
241         else if (!res_name || val < 0)
242                 return -EINVAL;
243         return 0;
244 }
245
246 static inline int exec_func(int (*func)(char *res_name), char *res_name)
247 {
248         if (!func)
249                 return -ENOTSUP;
250         return func(res_name);
251 }
252
253 static inline int exec_func_with_str(int (*func)(char *res_name, char *str),
254                            char *res_name, char *str)
255 {
256         if (!func)
257                 return -ENOTSUP;
258         return func(res_name, str);
259 }
260
261 static inline int exec_func_with_int(int (*func)(char *res_name, int val),
262                            char *res_name, int val)
263 {
264         if (!func)
265                 return -ENOTSUP;
266         return func(res_name, val);
267 }
268
269 /* Get and set the current governor. */
270 EXPORT int hal_power_dvfs_get_curr_governor(unsigned int res_type,
271                                                 char *res_name, char *governor)
272 {
273         struct pass_resource_dvfs_ops *dvfs;
274         int ret;
275
276         if (!governor)
277                 return -EINVAL;
278
279         ret = get_dvfs(g_power_funcs, res_type, res_name, &dvfs);
280         if (ret < 0 || !dvfs)
281                 return ret;
282
283         return exec_func_with_str(dvfs->get_curr_governor, res_name, governor);
284 }
285
286 EXPORT int hal_power_dvfs_set_curr_governor(unsigned int res_type, char *res_name, char *governor)
287 {
288         struct pass_resource_dvfs_ops *dvfs;
289         int ret;
290
291         if (!governor)
292                 return -EINVAL;
293
294         ret = get_dvfs(g_power_funcs, res_type, res_name, &dvfs);
295         if (ret < 0 || !dvfs)
296                 return ret;
297
298         return exec_func_with_str(dvfs->set_curr_governor, res_name, governor);
299 }
300
301 EXPORT int hal_power_dvfs_get_avail_governor(unsigned int res_type, char *res_name, char **avail_governor)
302 {
303         struct pass_resource_dvfs_ops *dvfs;
304         int ret;
305
306         ret = get_dvfs(g_power_funcs, res_type, res_name, &dvfs);
307         if (ret < 0 || !dvfs)
308                 return ret;
309
310         if (!dvfs->get_avail_governor)
311                 return -ENOTSUP;
312
313         return dvfs->get_avail_governor(res_name, avail_governor);
314 }
315
316 /* Get the current frequency. */
317 EXPORT int hal_power_dvfs_get_curr_freq(unsigned int res_type, char *res_name)
318 {
319         struct pass_resource_dvfs_ops *dvfs;
320         int ret;
321
322         ret = get_dvfs(g_power_funcs, res_type, res_name, &dvfs);
323         if (ret < 0 || !dvfs)
324                 return ret;
325
326         return exec_func(dvfs->get_curr_freq, res_name);
327 }
328
329 /* Get and set the minimum frequency. */
330 EXPORT int hal_power_dvfs_get_min_freq(unsigned int res_type, char *res_name)
331 {
332         struct pass_resource_dvfs_ops *dvfs;
333         int ret;
334
335         ret = get_dvfs(g_power_funcs, res_type, res_name, &dvfs);
336         if (ret < 0 || !dvfs)
337                 return ret;
338
339         return exec_func(dvfs->get_min_freq, res_name);
340 }
341
342 EXPORT int hal_power_dvfs_set_min_freq(unsigned int res_type, char *res_name, int freq)
343 {
344         struct pass_resource_dvfs_ops *dvfs;
345         int ret;
346
347         if (freq < 0)
348                 return -EINVAL;
349
350         ret = get_dvfs(g_power_funcs, res_type, res_name, &dvfs);
351         if (ret < 0 || !dvfs)
352                 return ret;
353
354         return exec_func_with_int(dvfs->set_min_freq, res_name, freq);
355 }
356
357 /* Get and set the maximum frequency. */
358 EXPORT int hal_power_dvfs_get_max_freq(unsigned int res_type, char *res_name)
359 {
360         struct pass_resource_dvfs_ops *dvfs;
361         int ret;
362
363         ret = get_dvfs(g_power_funcs, res_type, res_name, &dvfs);
364         if (ret < 0 || !dvfs)
365                 return ret;
366
367         return exec_func(dvfs->get_max_freq, res_name);
368 }
369
370 EXPORT int hal_power_dvfs_set_max_freq(unsigned int res_type, char *res_name, int freq)
371 {
372         struct pass_resource_dvfs_ops *dvfs;
373         int ret;
374
375         if (freq < 0)
376                 return -EINVAL;
377
378         ret = get_dvfs(g_power_funcs, res_type, res_name, &dvfs);
379         if (ret < 0 || !dvfs)
380                 return ret;
381
382         return exec_func_with_int(dvfs->set_max_freq, res_name, freq);
383 }
384
385 /* Get the minimum/maximum frequency which can be set to resource. */
386 EXPORT int hal_power_dvfs_get_available_min_freq(unsigned int res_type, char *res_name)
387 {
388         struct pass_resource_dvfs_ops *dvfs;
389         int ret;
390
391         ret = get_dvfs(g_power_funcs, res_type, res_name, &dvfs);
392         if (ret < 0 || !dvfs)
393                 return ret;
394
395         return exec_func(dvfs->get_available_min_freq, res_name);
396 }
397
398 EXPORT int hal_power_dvfs_get_available_max_freq(unsigned int res_type, char *res_name)
399 {
400         struct pass_resource_dvfs_ops *dvfs;
401         int ret;
402
403         ret = get_dvfs(g_power_funcs, res_type, res_name, &dvfs);
404         if (ret < 0 || !dvfs)
405                 return ret;
406
407         return exec_func(dvfs->get_available_max_freq, res_name);
408 }
409
410 /* Get and set the up_threshold to support boosting. */
411 EXPORT int hal_power_dvfs_get_up_threshold(unsigned int res_type, char *res_name)
412 {
413         struct pass_resource_dvfs_ops *dvfs;
414         int ret;
415
416         ret = get_dvfs(g_power_funcs, res_type, res_name, &dvfs);
417         if (ret < 0 || !dvfs)
418                 return ret;
419
420         return exec_func(dvfs->get_up_threshold, res_name);
421 }
422
423 EXPORT int hal_power_dvfs_set_up_threshold(unsigned int res_type, char *res_name, int up_threshold)
424 {
425         struct pass_resource_dvfs_ops *dvfs;
426         int ret;
427
428         if (up_threshold < 0)
429                 return -EINVAL;
430
431         ret = get_dvfs(g_power_funcs, res_type, res_name, &dvfs);
432         if (ret < 0 || !dvfs)
433                 return ret;
434
435         return exec_func_with_int(dvfs->set_up_threshold, res_name, up_threshold);
436 }
437
438 /* Get the load_table of each resource to estimate the system load. */
439 EXPORT int hal_power_dvfs_get_load_table(unsigned int res_type, char *res_name, void *pass_cpu_load_table)
440 {
441         struct pass_resource_dvfs_ops *dvfs;
442         int ret;
443
444         ret = get_dvfs(g_power_funcs, res_type, res_name, &dvfs);
445         if (ret < 0 || !dvfs)
446                 return ret;
447
448         if (!dvfs->get_load_table)
449                 return -ENOTSUP;
450
451         return dvfs->get_load_table(res_name, pass_cpu_load_table);
452 }
453
454 /**
455  * CPU Hotplug Operation for CPU H/W
456  */
457 /* Get and set the online status of resource. */
458 EXPORT int hal_power_hotplug_get_online_state(unsigned int res_type, char *res_name, int cpu)
459 {
460         struct pass_resource_hotplug_ops *hotplug;
461         int ret;
462
463         if (cpu < 0)
464                 return -EINVAL;
465
466         ret = get_hotplug(g_power_funcs, res_type, res_name, &hotplug);
467         if (ret < 0 || !hotplug)
468                 return ret;
469
470         return exec_func_with_int(hotplug->get_online_state, res_name, cpu);
471 }
472
473 EXPORT int hal_power_hotplug_set_online_state(unsigned int res_type, char *res_name, int cpu, int on)
474 {
475         struct pass_resource_hotplug_ops *hotplug;
476         int ret;
477
478         if (cpu < 0 || on < 0)
479                 return -EINVAL;
480
481         ret = get_hotplug(g_power_funcs, res_type, res_name, &hotplug);
482         if (ret < 0 || !hotplug)
483                 return ret;
484
485         if (!hotplug->set_online_state)
486                 return -ENOTSUP;
487
488         return hotplug->set_online_state(res_name, cpu, on);
489 }
490
491 /* Get and set the minimum number of online CPUs */
492 EXPORT int hal_power_hotplug_get_online_min_num(unsigned int res_type, char *res_name)
493 {
494         struct pass_resource_hotplug_ops *hotplug;
495         int ret;
496
497         ret = get_hotplug(g_power_funcs, res_type, res_name, &hotplug);
498         if (ret < 0 || !hotplug)
499                 return ret;
500
501         return exec_func(hotplug->get_online_min_num, res_name);
502 }
503
504 EXPORT int hal_power_hotplug_set_online_min_num(unsigned int res_type,
505                                                 char *res_name, int min_num)
506 {
507         struct pass_resource_hotplug_ops *hotplug;
508         int ret;
509
510         if (min_num < 0)
511                 return -EINVAL;
512
513         ret = get_hotplug(g_power_funcs, res_type, res_name, &hotplug);
514         if (ret < 0 || !hotplug)
515                 return ret;
516
517         return exec_func_with_int(hotplug->set_online_min_num, res_name, min_num);
518 }
519
520 /* Get and set the maximum number of online CPUs */
521 EXPORT int hal_power_hotplug_get_online_max_num(unsigned int res_type,
522                                                 char *res_name)
523 {
524         struct pass_resource_hotplug_ops *hotplug;
525         int ret;
526
527         ret = get_hotplug(g_power_funcs, res_type, res_name, &hotplug);
528         if (ret < 0 || !hotplug)
529                 return ret;
530
531         return exec_func(hotplug->get_online_max_num, res_name);
532 }
533
534 EXPORT int hal_power_hotplug_set_online_max_num(unsigned int res_type,
535                                                 char *res_name, int max_num)
536 {
537         struct pass_resource_hotplug_ops *hotplug;
538         int ret;
539
540         if (max_num < 0)
541                 return -EINVAL;
542
543         ret = get_hotplug(g_power_funcs, res_type, res_name, &hotplug);
544         if (ret < 0 || !hotplug)
545                 return ret;
546
547         return exec_func_with_int(hotplug->set_online_max_num, res_name, max_num);
548 }
549
550 /**
551  * Thermal Operation for CPU/BUS/GPU H/W
552  */
553 /* Get the current temperature of resource. */
554 EXPORT int hal_power_thermal_get_temp(unsigned int res_type,
555                                                 char *res_thermal_name)
556 {
557         struct pass_resource_tmu_ops *tmu;
558         int ret;
559
560         ret = get_tmu(g_power_funcs, res_type, res_thermal_name, &tmu);
561         if (ret < 0 || !tmu)
562                 return ret;
563
564         /*
565          * In the case of the HAL TMU ops, res_thermal_name is used
566          * as the first argument instead of res_name.
567          */
568         return exec_func(tmu->get_temp, res_thermal_name);
569 }
570
571 /* Get the policy of thermal management unit. */
572 EXPORT int hal_power_thermal_get_policy(unsigned int res_type,
573                                                 char *res_thermal_name,
574                                                 char *policy)
575 {
576         struct pass_resource_tmu_ops *tmu;
577         int ret;
578
579         if (!policy)
580                 return -EINVAL;
581
582         ret = get_tmu(g_power_funcs, res_type, res_thermal_name, &tmu);
583         if (ret < 0 || !tmu)
584                 return ret;
585
586         /*
587          * In the case of the HAL TMU ops, res_thermal_name is used
588          * as the first argument instead of res_name.
589          */
590         return exec_func_with_str(tmu->get_policy, res_thermal_name, policy);
591 }
592
593 /* Get and set the state of thermal cooling-device */
594 EXPORT int hal_power_thermal_set_cooling_device_state(unsigned int device_type,
595                                                         char *cooling_device_name,
596                                                         int state)
597 {
598         struct pass_resource_tmu_ops *tmu;
599         int ret;
600
601         if (state < 0)
602                 return -EINVAL;
603
604         ret = get_tmu(g_power_funcs, device_type, cooling_device_name, &tmu);
605         if (ret < 0 || !tmu)
606                 return ret;
607
608         /*
609          * In the case of the HAL TMU ops, cooling_device_name is used
610          * as the first argument instead of res_name.
611          */
612         return exec_func_with_int(tmu->set_cooling_device_state, cooling_device_name, state);
613 }
614
615 EXPORT int hal_power_thermal_get_cooling_device_state(unsigned int device_type,
616                                                         char *cooling_device_name)
617 {
618         struct pass_resource_tmu_ops *tmu;
619         int ret;
620
621         ret= get_tmu(g_power_funcs, device_type, cooling_device_name, &tmu);
622         if (ret < 0 || !tmu)
623                 return ret;
624
625         /*
626          * In the case of the HAL TMU ops, cooling_device_name is used
627          * as the first argument instead of res_name.
628          */
629         return exec_func(tmu->get_cooling_device_state, cooling_device_name);
630 }
631
632 EXPORT int hal_power_thermal_get_cooling_device_max_state(unsigned int device_type,
633                                                         char *cooling_device_name)
634 {
635         struct pass_resource_tmu_ops *tmu;
636         int ret;
637
638         ret = get_tmu(g_power_funcs, device_type, cooling_device_name, &tmu);
639         if (ret < 0 || !tmu)
640                 return ret;
641
642         /*
643          * In the case of the HAL TMU ops, cooling_device_name is used
644          * as the first argument instead of res_name.
645          */
646         return exec_func(tmu->get_cooling_device_max_state, cooling_device_name);
647 }
648
649 EXPORT int hal_power_battery_set_charging_status(unsigned int device_type,
650                                                         char *res_name,
651                                                         int state)
652 {
653         struct pass_resource_battery_ops *charging;
654         int ret;
655
656         if (state < 0)
657                 return -EINVAL;
658
659         ret = get_charging(g_power_funcs, device_type, res_name, &charging);
660         if (ret < 0 || !charging)
661                 return ret;
662
663         return exec_func_with_int(charging->set_charging_status, res_name, state);
664 }
665
666 EXPORT int hal_power_battery_get_charging_status(unsigned int device_type,
667                                                         char *res_name)
668 {
669         struct pass_resource_battery_ops *charging;
670         int ret;
671
672         ret = get_charging(g_power_funcs, device_type, res_name, &charging);
673         if (ret < 0 || !charging)
674                 return ret;
675
676         return exec_func(charging->get_charging_status, res_name);
677 }
678
679 EXPORT int hal_power_battery_set_charging_current(unsigned int device_type,
680                                                         char *res_name,
681                                                         int charing_current_uA)
682 {
683         struct pass_resource_battery_ops *charging;
684         int ret;
685
686         if (charing_current_uA < 0)
687                 return -EINVAL;
688
689         ret = get_charging(g_power_funcs, device_type, res_name, &charging);
690         if (ret < 0 || !charging)
691                 return ret;
692
693         return exec_func_with_int(charging->set_charging_current, res_name, charing_current_uA);
694 }
695
696 EXPORT int hal_power_battery_get_charging_current(unsigned int device_type,
697                                                         char *res_name)
698 {
699         struct pass_resource_battery_ops *charging;
700         int ret;
701
702         ret = get_charging(g_power_funcs, device_type, res_name, &charging);
703         if (ret < 0 || !charging)
704                 return ret;
705
706         return exec_func(charging->get_charging_current, res_name);
707 }
708
709 /**
710  * Memory Operation for Memory H/W
711  */
712 /* Get and set the /sys/kernel/debug/fault_around_bytes */
713 EXPORT int hal_power_memory_get_fault_around_bytes(unsigned int res_type,
714                                                 char *res_name)
715 {
716         struct pass_resource_memory *memory;
717         int ret;
718
719         if (!res_name)
720                 return -EINVAL;
721
722         switch (res_type) {
723         case PASS_RESOURCE_MEMORY_ID:
724                 memory = g_power_funcs->memory;
725                 break;
726         default:
727                 return -EPERM;
728         }
729
730         return exec_func(memory->get_fault_around_bytes, res_name);
731 }
732
733 EXPORT int hal_power_memory_set_fault_around_bytes(unsigned int res_type,
734                                                 char *res_name,
735                                                 int fault_around_bytes)
736 {
737         struct pass_resource_memory *memory;
738         int ret;
739
740         ret = is_valid_param_with_int(res_name, fault_around_bytes);
741         if (ret < 0)
742                 return ret;
743
744         /*
745          * fault_around_bytes should be multiply of page size in order to
746          * prevent the confusion of user. Even if user uses any integer value,
747          * the entered fauled_around_bytes value is rounded by kernel and then
748          * use it. In order to clarify the usage of fauld_around_bytes,
749          * limit the range of value.
750          */
751         if (fault_around_bytes == 0 || (fault_around_bytes % FAULT_AROUND_BYTES_4K))
752                 return -EINVAL;
753
754         switch (res_type) {
755         case PASS_RESOURCE_MEMORY_ID:
756                 memory = g_power_funcs->memory;
757                 break;
758         default:
759                 return -EPERM;
760         }
761
762         return exec_func_with_int(memory->set_fault_around_bytes, res_name, fault_around_bytes);
763 }
764
765 /**
766  * Miscellaneous Operation for CPU/BUS/GPU H/W
767  */
768 /*
769  * NOTE: It is not propper method. But PASS must need to keep
770  * the backwards compatibility, set the PMQoS's data from
771  * platform to hal. So, It is not recommended to use it.
772  *
773  * This function will be removed after finding the proper method.
774  */
775 EXPORT int hal_power_misc_set_pmqos_data(unsigned int res_type,
776                                                 char *res_name, void *data)
777 {
778         struct pass_resource_nonstandard *nonstandard = NULL;
779
780         if (!g_power_funcs)
781                 return -ENOTSUP;
782
783         if (!res_name || !data)
784                 return -EINVAL;
785
786         switch (res_type) {
787         case PASS_RESOURCE_NONSTANDARD_ID:
788                 nonstandard = g_power_funcs->nonstandard;
789                 break;
790         default:
791                 return -EPERM;
792         }
793
794         if (!nonstandard->set_pmqos_data)
795                 return -ENOTSUP;
796
797         return nonstandard->set_pmqos_data(res_name, data);
798 }