2009-06-10 17:20:19 +04:00
/**************************************************************************
*
* Copyright 2008 - 2009 VMware , Inc . , Palo Alto , CA . , USA
* All Rights Reserved .
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the
* " Software " ) , to deal in the Software without restriction , including
* without limitation the rights to use , copy , modify , merge , publish ,
* distribute , sub license , and / or sell copies of the Software , and to
* permit persons to whom the Software is furnished to do so , subject to
* the following conditions :
*
* The above copyright notice and this permission notice ( including the
* next paragraph ) shall be included in all copies or substantial portions
* of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NON - INFRINGEMENT . IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS , AUTHORS AND / OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM ,
* DAMAGES OR OTHER LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR
* OTHERWISE , ARISING FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Authors : Thomas Hellstrom < thellstrom - at - vmware - dot - com >
*/
# include <linux/mutex.h>
# include <linux/slab.h>
# include <linux/module.h>
2012-10-02 21:01:07 +04:00
# include <drm/drm_global.h>
2009-06-10 17:20:19 +04:00
2010-03-09 03:56:52 +03:00
struct drm_global_item {
2009-06-10 17:20:19 +04:00
struct mutex mutex ;
void * object ;
int refcount ;
} ;
2010-03-09 03:56:52 +03:00
static struct drm_global_item glob [ DRM_GLOBAL_NUM ] ;
2009-06-10 17:20:19 +04:00
2010-03-09 03:56:52 +03:00
void drm_global_init ( void )
2009-06-10 17:20:19 +04:00
{
int i ;
2010-03-09 03:56:52 +03:00
for ( i = 0 ; i < DRM_GLOBAL_NUM ; + + i ) {
struct drm_global_item * item = & glob [ i ] ;
2009-06-10 17:20:19 +04:00
mutex_init ( & item - > mutex ) ;
item - > object = NULL ;
item - > refcount = 0 ;
}
}
2010-03-09 03:56:52 +03:00
void drm_global_release ( void )
2009-06-10 17:20:19 +04:00
{
int i ;
2010-03-09 03:56:52 +03:00
for ( i = 0 ; i < DRM_GLOBAL_NUM ; + + i ) {
struct drm_global_item * item = & glob [ i ] ;
2009-06-10 17:20:19 +04:00
BUG_ON ( item - > object ! = NULL ) ;
BUG_ON ( item - > refcount ! = 0 ) ;
}
}
2010-03-09 03:56:52 +03:00
int drm_global_item_ref ( struct drm_global_reference * ref )
2009-06-10 17:20:19 +04:00
{
2016-09-07 08:24:31 +03:00
int ret = 0 ;
2010-03-09 03:56:52 +03:00
struct drm_global_item * item = & glob [ ref - > global_type ] ;
2009-06-10 17:20:19 +04:00
mutex_lock ( & item - > mutex ) ;
if ( item - > refcount = = 0 ) {
2016-09-07 08:24:31 +03:00
ref - > object = kzalloc ( ref - > size , GFP_KERNEL ) ;
if ( unlikely ( ref - > object = = NULL ) ) {
2009-06-10 17:20:19 +04:00
ret = - ENOMEM ;
2016-09-07 08:24:31 +03:00
goto error_unlock ;
2009-06-10 17:20:19 +04:00
}
ret = ref - > init ( ref ) ;
if ( unlikely ( ret ! = 0 ) )
2016-09-07 08:24:31 +03:00
goto error_free ;
2009-06-10 17:20:19 +04:00
2016-09-07 08:24:31 +03:00
item - > object = ref - > object ;
} else {
ref - > object = item - > object ;
2009-06-10 17:20:19 +04:00
}
2016-09-07 08:24:31 +03:00
2009-09-29 07:56:38 +04:00
+ + item - > refcount ;
2009-06-10 17:20:19 +04:00
mutex_unlock ( & item - > mutex ) ;
return 0 ;
2016-09-07 08:24:31 +03:00
error_free :
kfree ( ref - > object ) ;
ref - > object = NULL ;
error_unlock :
2009-06-10 17:20:19 +04:00
mutex_unlock ( & item - > mutex ) ;
return ret ;
}
2010-03-09 03:56:52 +03:00
EXPORT_SYMBOL ( drm_global_item_ref ) ;
2009-06-10 17:20:19 +04:00
2010-03-09 03:56:52 +03:00
void drm_global_item_unref ( struct drm_global_reference * ref )
2009-06-10 17:20:19 +04:00
{
2010-03-09 03:56:52 +03:00
struct drm_global_item * item = & glob [ ref - > global_type ] ;
2009-06-10 17:20:19 +04:00
mutex_lock ( & item - > mutex ) ;
BUG_ON ( item - > refcount = = 0 ) ;
BUG_ON ( ref - > object ! = item - > object ) ;
if ( - - item - > refcount = = 0 ) {
ref - > release ( ref ) ;
item - > object = NULL ;
}
mutex_unlock ( & item - > mutex ) ;
}
2010-03-09 03:56:52 +03:00
EXPORT_SYMBOL ( drm_global_item_unref ) ;
2009-06-10 17:20:19 +04:00