/**************************************************************************1*2* Copyright 2008-2009 VMware, Inc., Palo Alto, CA., USA3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR18* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,19* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL20* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,21* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR22* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE23* USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/26/*27* Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>28*/2930#include <linux/mutex.h>31#include <linux/slab.h>32#include <linux/module.h>33#include "drm_global.h"3435struct drm_global_item {36struct mutex mutex;37void *object;38int refcount;39};4041static struct drm_global_item glob[DRM_GLOBAL_NUM];4243void drm_global_init(void)44{45int i;4647for (i = 0; i < DRM_GLOBAL_NUM; ++i) {48struct drm_global_item *item = &glob[i];49mutex_init(&item->mutex);50item->object = NULL;51item->refcount = 0;52}53}5455void drm_global_release(void)56{57int i;58for (i = 0; i < DRM_GLOBAL_NUM; ++i) {59struct drm_global_item *item = &glob[i];60BUG_ON(item->object != NULL);61BUG_ON(item->refcount != 0);62}63}6465int drm_global_item_ref(struct drm_global_reference *ref)66{67int ret;68struct drm_global_item *item = &glob[ref->global_type];69void *object;7071mutex_lock(&item->mutex);72if (item->refcount == 0) {73item->object = kzalloc(ref->size, GFP_KERNEL);74if (unlikely(item->object == NULL)) {75ret = -ENOMEM;76goto out_err;77}7879ref->object = item->object;80ret = ref->init(ref);81if (unlikely(ret != 0))82goto out_err;8384}85++item->refcount;86ref->object = item->object;87object = item->object;88mutex_unlock(&item->mutex);89return 0;90out_err:91mutex_unlock(&item->mutex);92item->object = NULL;93return ret;94}95EXPORT_SYMBOL(drm_global_item_ref);9697void drm_global_item_unref(struct drm_global_reference *ref)98{99struct drm_global_item *item = &glob[ref->global_type];100101mutex_lock(&item->mutex);102BUG_ON(item->refcount == 0);103BUG_ON(ref->object != item->object);104if (--item->refcount == 0) {105ref->release(ref);106item->object = NULL;107}108mutex_unlock(&item->mutex);109}110EXPORT_SYMBOL(drm_global_item_unref);111112113114