Commit | Line | Data |
---|---|---|
6fa3eb70 S |
1 | /** |
2 | * This confidential and proprietary software may be used only as | |
3 | * authorised by a licensing agreement from ARM Limited | |
4 | * (C) COPYRIGHT 2012-2013 ARM Limited | |
5 | * ALL RIGHTS RESERVED | |
6 | * The entire notice above must be reproduced on all authorised | |
7 | * copies and copies may only be made to the extent permitted | |
8 | * by a licensing agreement from ARM Limited. | |
9 | */ | |
10 | ||
11 | #include "mali_osk.h" | |
12 | #include "mali_kernel_common.h" | |
13 | #include "mali_uk_types.h" | |
14 | #include "mali_user_settings_db.h" | |
15 | #include "mali_session.h" | |
16 | ||
17 | static u32 mali_user_settings[_MALI_UK_USER_SETTING_MAX]; | |
18 | const char *_mali_uk_user_setting_descriptions[] = _MALI_UK_USER_SETTING_DESCRIPTIONS; | |
19 | ||
20 | static void mali_user_settings_notify(_mali_uk_user_setting_t setting, u32 value) | |
21 | { | |
22 | mali_bool done = MALI_FALSE; | |
23 | ||
24 | /* | |
25 | * This function gets a bit complicated because we can't hold the session lock while | |
26 | * allocating notification objects. | |
27 | */ | |
28 | ||
29 | while (!done) { | |
30 | u32 i; | |
31 | u32 num_sessions_alloc; | |
32 | u32 num_sessions_with_lock; | |
33 | u32 used_notification_objects = 0; | |
34 | _mali_osk_notification_t **notobjs; | |
35 | ||
36 | /* Pre allocate the number of notifications objects we need right now (might change after lock has been taken) */ | |
37 | num_sessions_alloc = mali_session_get_count(); | |
38 | if (0 == num_sessions_alloc) { | |
39 | /* No sessions to report to */ | |
40 | return; | |
41 | } | |
42 | ||
43 | notobjs = (_mali_osk_notification_t **)_mali_osk_malloc(sizeof(_mali_osk_notification_t *) * num_sessions_alloc); | |
44 | if (NULL == notobjs) { | |
45 | MALI_PRINT_ERROR(("Failed to notify user space session about num PP core change (alloc failure)\n")); | |
46 | return; | |
47 | } | |
48 | ||
49 | for (i = 0; i < num_sessions_alloc; i++) { | |
50 | notobjs[i] = _mali_osk_notification_create(_MALI_NOTIFICATION_SETTINGS_CHANGED, | |
51 | sizeof(_mali_uk_settings_changed_s)); | |
52 | if (NULL != notobjs[i]) { | |
53 | _mali_uk_settings_changed_s *data; | |
54 | data = notobjs[i]->result_buffer; | |
55 | ||
56 | data->setting = setting; | |
57 | data->value = value; | |
58 | } else { | |
59 | MALI_PRINT_ERROR(("Failed to notify user space session about setting change (alloc failure %u)\n", i)); | |
60 | } | |
61 | } | |
62 | ||
63 | mali_session_lock(); | |
64 | ||
65 | /* number of sessions will not change while we hold the lock */ | |
66 | num_sessions_with_lock = mali_session_get_count(); | |
67 | ||
68 | if (num_sessions_alloc >= num_sessions_with_lock) { | |
69 | /* We have allocated enough notification objects for all the sessions atm */ | |
70 | struct mali_session_data *session, *tmp; | |
71 | MALI_SESSION_FOREACH(session, tmp, link) { | |
72 | MALI_DEBUG_ASSERT(used_notification_objects < num_sessions_alloc); | |
73 | if (NULL != notobjs[used_notification_objects]) { | |
74 | mali_session_send_notification(session, notobjs[used_notification_objects]); | |
75 | notobjs[used_notification_objects] = NULL; /* Don't track this notification object any more */ | |
76 | } | |
77 | used_notification_objects++; | |
78 | } | |
79 | done = MALI_TRUE; | |
80 | } | |
81 | ||
82 | mali_session_unlock(); | |
83 | ||
84 | /* Delete any remaining/unused notification objects */ | |
85 | for (; used_notification_objects < num_sessions_alloc; used_notification_objects++) { | |
86 | if (NULL != notobjs[used_notification_objects]) { | |
87 | _mali_osk_notification_delete(notobjs[used_notification_objects]); | |
88 | } | |
89 | } | |
90 | ||
91 | _mali_osk_free(notobjs); | |
92 | } | |
93 | } | |
94 | ||
95 | void mali_set_user_setting(_mali_uk_user_setting_t setting, u32 value) | |
96 | { | |
97 | mali_bool notify = MALI_FALSE; | |
98 | ||
99 | if (setting >= _MALI_UK_USER_SETTING_MAX) { | |
100 | MALI_DEBUG_PRINT_ERROR(("Invalid user setting %ud\n")); | |
101 | return; | |
102 | } | |
103 | ||
104 | if (mali_user_settings[setting] != value) { | |
105 | notify = MALI_TRUE; | |
106 | } | |
107 | ||
108 | mali_user_settings[setting] = value; | |
109 | ||
110 | if (notify) { | |
111 | mali_user_settings_notify(setting, value); | |
112 | } | |
113 | } | |
114 | ||
115 | u32 mali_get_user_setting(_mali_uk_user_setting_t setting) | |
116 | { | |
117 | if (setting >= _MALI_UK_USER_SETTING_MAX) { | |
118 | return 0; | |
119 | } | |
120 | ||
121 | return mali_user_settings[setting]; | |
122 | } | |
123 | ||
124 | _mali_osk_errcode_t _mali_ukk_get_user_setting(_mali_uk_get_user_setting_s *args) | |
125 | { | |
126 | _mali_uk_user_setting_t setting; | |
127 | MALI_DEBUG_ASSERT_POINTER(args); | |
128 | ||
129 | setting = args->setting; | |
130 | ||
131 | if (_MALI_UK_USER_SETTING_MAX > setting) { | |
132 | args->value = mali_user_settings[setting]; | |
133 | return _MALI_OSK_ERR_OK; | |
134 | } else { | |
135 | return _MALI_OSK_ERR_INVALID_ARGS; | |
136 | } | |
137 | } | |
138 | ||
139 | _mali_osk_errcode_t _mali_ukk_get_user_settings(_mali_uk_get_user_settings_s *args) | |
140 | { | |
141 | MALI_DEBUG_ASSERT_POINTER(args); | |
142 | ||
143 | _mali_osk_memcpy(args->settings, mali_user_settings, sizeof(mali_user_settings)); | |
144 | ||
145 | return _MALI_OSK_ERR_OK; | |
146 | } |