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
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.
12 #include "mali_kernel_common.h"
13 #include "mali_uk_types.h"
14 #include "mali_user_settings_db.h"
15 #include "mali_session.h"
17 static u32 mali_user_settings
[_MALI_UK_USER_SETTING_MAX
];
18 const char *_mali_uk_user_setting_descriptions
[] = _MALI_UK_USER_SETTING_DESCRIPTIONS
;
20 static void mali_user_settings_notify(_mali_uk_user_setting_t setting
, u32 value
)
22 mali_bool done
= MALI_FALSE
;
25 * This function gets a bit complicated because we can't hold the session lock while
26 * allocating notification objects.
31 u32 num_sessions_alloc
;
32 u32 num_sessions_with_lock
;
33 u32 used_notification_objects
= 0;
34 _mali_osk_notification_t
**notobjs
;
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 */
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"));
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
;
56 data
->setting
= setting
;
59 MALI_PRINT_ERROR(("Failed to notify user space session about setting change (alloc failure %u)\n", i
));
65 /* number of sessions will not change while we hold the lock */
66 num_sessions_with_lock
= mali_session_get_count();
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 */
77 used_notification_objects
++;
82 mali_session_unlock();
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
]);
91 _mali_osk_free(notobjs
);
95 void mali_set_user_setting(_mali_uk_user_setting_t setting
, u32 value
)
97 mali_bool notify
= MALI_FALSE
;
99 if (setting
>= _MALI_UK_USER_SETTING_MAX
) {
100 MALI_DEBUG_PRINT_ERROR(("Invalid user setting %ud\n"));
104 if (mali_user_settings
[setting
] != value
) {
108 mali_user_settings
[setting
] = value
;
111 mali_user_settings_notify(setting
, value
);
115 u32
mali_get_user_setting(_mali_uk_user_setting_t setting
)
117 if (setting
>= _MALI_UK_USER_SETTING_MAX
) {
121 return mali_user_settings
[setting
];
124 _mali_osk_errcode_t
_mali_ukk_get_user_setting(_mali_uk_get_user_setting_s
*args
)
126 _mali_uk_user_setting_t setting
;
127 MALI_DEBUG_ASSERT_POINTER(args
);
129 setting
= args
->setting
;
131 if (_MALI_UK_USER_SETTING_MAX
> setting
) {
132 args
->value
= mali_user_settings
[setting
];
133 return _MALI_OSK_ERR_OK
;
135 return _MALI_OSK_ERR_INVALID_ARGS
;
139 _mali_osk_errcode_t
_mali_ukk_get_user_settings(_mali_uk_get_user_settings_s
*args
)
141 MALI_DEBUG_ASSERT_POINTER(args
);
143 _mali_osk_memcpy(args
->settings
, mali_user_settings
, sizeof(mali_user_settings
));
145 return _MALI_OSK_ERR_OK
;