PageRenderTime 34ms CodeModel.GetById 25ms app.highlight 8ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/gpu/mali/ump/common/ump_kernel_descriptor_mapping.c

https://bitbucket.org/ndreys/linux-sunxi
C | 166 lines | 123 code | 23 blank | 20 comment | 23 complexity | db49387a5d7423c9f2495cf2256cefeb MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1/*
  2 * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
  3 * 
  4 * This program is free software and is provided to you under the terms of the GNU General Public License version 2
  5 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
  6 * 
  7 * A copy of the licence is included with the program, and can also be obtained from Free Software
  8 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  9 */
 10
 11#include "mali_kernel_common.h"
 12#include "mali_osk.h"
 13#include "mali_osk_bitops.h"
 14#include "ump_kernel_common.h"
 15#include "ump_kernel_descriptor_mapping.h"
 16
 17#define MALI_PAD_INT(x) (((x) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1))
 18
 19/**
 20 * Allocate a descriptor table capable of holding 'count' mappings
 21 * @param count Number of mappings in the table
 22 * @return Pointer to a new table, NULL on error
 23 */
 24static ump_descriptor_table * descriptor_table_alloc(int count);
 25
 26/**
 27 * Free a descriptor table
 28 * @param table The table to free
 29 */
 30static void descriptor_table_free(ump_descriptor_table * table);
 31
 32ump_descriptor_mapping * ump_descriptor_mapping_create(int init_entries, int max_entries)
 33{
 34	ump_descriptor_mapping * map = _mali_osk_calloc(1, sizeof(ump_descriptor_mapping) );
 35
 36	init_entries = MALI_PAD_INT(init_entries);
 37	max_entries = MALI_PAD_INT(max_entries);
 38
 39	if (NULL != map)
 40	{
 41		map->table = descriptor_table_alloc(init_entries);
 42		if (NULL != map->table)
 43		{
 44			map->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_READERWRITER, 0 , 0);
 45			if ( NULL != map->lock )
 46			{
 47				_mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */
 48				map->max_nr_mappings_allowed = max_entries;
 49				map->current_nr_mappings = init_entries;
 50				return map;
 51			}
 52			descriptor_table_free(map->table);
 53		}
 54		_mali_osk_free(map);
 55	}
 56	return NULL;
 57}
 58
 59void ump_descriptor_mapping_destroy(ump_descriptor_mapping * map)
 60{
 61	descriptor_table_free(map->table);
 62	_mali_osk_lock_term( map->lock );
 63	_mali_osk_free(map);
 64}
 65
 66int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void * target)
 67{
 68 	int descriptor = -1;/*-EFAULT;*/
 69 	_mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
 70 	descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings);
 71	if (descriptor == map->current_nr_mappings)
 72	{
 73		int nr_mappings_new;
 74		/* no free descriptor, try to expand the table */
 75		ump_descriptor_table * new_table;
 76		ump_descriptor_table * old_table = map->table;
 77		nr_mappings_new= map->current_nr_mappings *2;
 78
 79		if (map->current_nr_mappings >= map->max_nr_mappings_allowed)
 80		{
 81			descriptor = -1;
 82			goto unlock_and_exit;
 83		}
 84
 85		new_table = descriptor_table_alloc(nr_mappings_new);
 86		if (NULL == new_table)
 87		{
 88			descriptor = -1;
 89			goto unlock_and_exit;
 90		}
 91
 92 		_mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG);
 93 		_mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*));
 94		map->table = new_table;
 95		map->current_nr_mappings = nr_mappings_new;
 96		descriptor_table_free(old_table);
 97	}
 98
 99	/* we have found a valid descriptor, set the value and usage bit */
100	_mali_osk_set_nonatomic_bit(descriptor, map->table->usage);
101	map->table->mappings[descriptor] = target;
102
103unlock_and_exit:
104	_mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
105	return descriptor;
106}
107
108int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, void** target)
109{
110 	int result = -1;/*-EFAULT;*/
111 	DEBUG_ASSERT(map);
112 	_mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
113 	if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
114	{
115		*target = map->table->mappings[descriptor];
116		result = 0;
117	}
118	else *target = NULL;
119	_mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
120	return result;
121}
122
123int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, void * target)
124{
125 	int result = -1;/*-EFAULT;*/
126 	_mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
127 	if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
128	{
129		map->table->mappings[descriptor] = target;
130		result = 0;
131	}
132	_mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
133	return result;
134}
135
136void ump_descriptor_mapping_free(ump_descriptor_mapping * map, int descriptor)
137{
138 	_mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
139 	if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
140	{
141		map->table->mappings[descriptor] = NULL;
142		_mali_osk_clear_nonatomic_bit(descriptor, map->table->usage);
143	}
144	_mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
145}
146
147static ump_descriptor_table * descriptor_table_alloc(int count)
148{
149	ump_descriptor_table * table;
150
151	table = _mali_osk_calloc(1, sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG) + (sizeof(void*) * count) );
152
153	if (NULL != table)
154	{
155		table->usage = (u32*)((u8*)table + sizeof(ump_descriptor_table));
156		table->mappings = (void**)((u8*)table + sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG));
157	}
158
159	return table;
160}
161
162static void descriptor_table_free(ump_descriptor_table * table)
163{
164	_mali_osk_free(table);
165}
166