summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorGary King <gking@nvidia.com>2010-02-16 18:58:52 -0800
committerGerrit Code Review <gerrit2@git-master-01.nvidia.com>2010-02-16 18:58:52 -0800
commit394a0d7ec6c9ea1d7d19f2e8e81b055fdfd8cf9e (patch)
treea90be2f6d27881dc47df7c255cbf197d00c17fb7 /arch
parent67ce6dc0dabf87dc03f0b95789a7c51adb5f186b (diff)
parent06c6c96baa909c9ccf1102c5bda0cb33b8749190 (diff)
Merge "tegra: Added spinlock primitives to NvOs." into android-tegra-2.6.29
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/include/nvos.h32
-rw-r--r--arch/arm/mach-tegra/nvos/nvos.c36
-rw-r--r--arch/arm/mach-tegra/nvos/nvos_exports.c4
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_power_oalintf.c36
4 files changed, 92 insertions, 16 deletions
diff --git a/arch/arm/mach-tegra/include/nvos.h b/arch/arm/mach-tegra/include/nvos.h
index c40d7ef6f854..450bb0e21857 100644
--- a/arch/arm/mach-tegra/include/nvos.h
+++ b/arch/arm/mach-tegra/include/nvos.h
@@ -1213,6 +1213,7 @@ NvOsLibraryUnload(NvOsLibraryHandle library);
typedef struct NvOsMutexRec *NvOsMutexHandle;
typedef struct NvOsIntrMutexRec *NvOsIntrMutexHandle;
+typedef struct NvOsSpinMutexRec *NvOsSpinMutexHandle;
typedef struct NvOsSemaphoreRec *NvOsSemaphoreHandle;
typedef struct NvOsThreadRec *NvOsThreadHandle;
@@ -1309,6 +1310,37 @@ void NvOsIntrMutexUnlock(NvOsIntrMutexHandle mutex);
void NvOsIntrMutexDestroy(NvOsIntrMutexHandle mutex);
/**
+ * Creates a spin mutex.
+ * This mutex is SMP safe, but it is not ISR-safe.
+ *
+ * @param mutex A pointer to the mutex is stored here on success.
+ */
+NvError NvOsSpinMutexCreate(NvOsSpinMutexHandle *mutex);
+
+/**
+ * Acquire a spin mutex.
+ * Spins until mutex is acquired; when acquired disables kernel preemption.
+ *
+ * @param mutex The mutex handle to lock.
+ */
+void NvOsSpinMutexLock(NvOsSpinMutexHandle mutex);
+
+/**
+ * Releases a spin mutex.
+ *
+ * @param mutex The mutex handle to unlock.
+ */
+void NvOsSpinMutexUnlock(NvOsSpinMutexHandle mutex);
+
+/**
+ * Destroys a spin mutex.
+ *
+ * @param mutex The mutex to destroy. If \a mutex is NULL, this API has no
+ * effect.
+ */
+void NvOsSpinMutexDestroy(NvOsSpinMutexHandle mutex);
+
+/**
* Creates a counting semaphore.
*
* @param semaphore A pointer to the semaphore to initialize.
diff --git a/arch/arm/mach-tegra/nvos/nvos.c b/arch/arm/mach-tegra/nvos/nvos.c
index 14f531f76f13..3e98dfc03063 100644
--- a/arch/arm/mach-tegra/nvos/nvos.c
+++ b/arch/arm/mach-tegra/nvos/nvos.c
@@ -772,6 +772,42 @@ void NvOsIntrMutexDestroy(NvOsIntrMutexHandle mutex)
kfree(mutex);
}
+typedef struct NvOsSpinMutexRec
+{
+ spinlock_t lock;
+} NvOsSpinMutex;
+
+NvError NvOsSpinMutexCreate(NvOsSpinMutexHandle *mutex)
+{
+ NvOsSpinMutex *m;
+
+ m = kzalloc( sizeof(NvOsSpinMutex), GFP_KERNEL );
+ if( !m )
+ return NvError_InsufficientMemory;
+
+ spin_lock_init( &m->lock );
+ *mutex = m;
+ return NvSuccess;
+}
+
+void NvOsSpinMutexLock(NvOsSpinMutexHandle mutex)
+{
+ NV_ASSERT( mutex );
+ spin_lock( &mutex->lock );
+}
+
+void NvOsSpinMutexUnlock(NvOsSpinMutexHandle mutex)
+{
+ NV_ASSERT( mutex );
+ spin_unlock( &mutex->lock );
+}
+
+void NvOsSpinMutexDestroy(NvOsSpinMutexHandle mutex)
+{
+ if (mutex)
+ kfree(mutex);
+}
+
typedef struct NvOsSemaphoreRec
{
struct semaphore sem;
diff --git a/arch/arm/mach-tegra/nvos/nvos_exports.c b/arch/arm/mach-tegra/nvos/nvos_exports.c
index 6e39f50ffde1..916daca3ec28 100644
--- a/arch/arm/mach-tegra/nvos/nvos_exports.c
+++ b/arch/arm/mach-tegra/nvos/nvos_exports.c
@@ -112,6 +112,10 @@ EXPORT_SYMBOL(NvOsIntrMutexCreate);
EXPORT_SYMBOL(NvOsIntrMutexLock);
EXPORT_SYMBOL(NvOsIntrMutexUnlock);
EXPORT_SYMBOL(NvOsIntrMutexDestroy);
+EXPORT_SYMBOL(NvOsSpinMutexCreate);
+EXPORT_SYMBOL(NvOsSpinMutexLock);
+EXPORT_SYMBOL(NvOsSpinMutexUnlock);
+EXPORT_SYMBOL(NvOsSpinMutexDestroy);
EXPORT_SYMBOL(NvOsSemaphoreCreate);
EXPORT_SYMBOL(NvOsSemaphoreClone);
EXPORT_SYMBOL(NvOsSemaphoreUnmarshal);
diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_power_oalintf.c b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_power_oalintf.c
index b5518380f259..e26d5b6e8376 100644
--- a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_power_oalintf.c
+++ b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_power_oalintf.c
@@ -66,12 +66,12 @@
{\
NvU32 RegValue; \
NvU32 RegOffset = APBDEV_PMC_SCRATCH0_0; \
- NvOsMutexLock(s_hPmcScratchMutex); \
+ NvOsSpinMutexLock(s_hPmcScratchMutex); \
RegValue = NV_REGR(rm, NvRmModuleID_Pmif, 0, RegOffset); \
RegValue = NV_FLD_SET_DRF_NUM(\
APBDEV_PMC, SCRATCH0, FieldName, FieldValue, RegValue); \
NV_REGW(rm, NvRmModuleID_Pmif, 0, RegOffset, RegValue); \
- NvOsMutexUnlock(s_hPmcScratchMutex); \
+ NvOsSpinMutexUnlock(s_hPmcScratchMutex); \
}\
} while (0)
@@ -82,7 +82,7 @@
/*****************************************************************************/
// Mutex for thread-safe access to PMC scratch fields
-static NvOsMutexHandle s_hPmcScratchMutex = NULL;
+static NvOsSpinMutexHandle s_hPmcScratchMutex = NULL;
// Pointer to LP2 Time storage
static NvUPtr s_pLp2Time = 0;
@@ -95,7 +95,7 @@ NvError NvRmPrivOalIntfInit(NvRmDeviceHandle hRmDeviceHandle)
// Create PMC scratch register access mutex
s_pLp2Time = 0;
s_hPmcScratchMutex = NULL;
- NV_CHECK_ERROR_CLEANUP(NvOsMutexCreate(&s_hPmcScratchMutex));
+ NV_CHECK_ERROR_CLEANUP(NvOsSpinMutexCreate(&s_hPmcScratchMutex));
// Clear DFS flags; other fields initialized by OAL and preserved by RM
SET_POWER_FLD_AP15(hRmDeviceHandle, RM_DFS_FLAG, 0);
@@ -108,7 +108,7 @@ fail:
void NvRmPrivOalIntfDeinit(NvRmDeviceHandle hRmDeviceHandle)
{
- NvOsMutexDestroy(s_hPmcScratchMutex);
+ NvOsSpinMutexDestroy(s_hPmcScratchMutex);
s_hPmcScratchMutex = NULL;
}
@@ -169,7 +169,7 @@ NvRmPrivUpdateDfsPauseFlag(
NvU32 mask = (NvRmDfsStatusFlags_Pause <<
NV_FIELD_SHIFT(APBDEV_PMC_SCRATCH0_0_RM_DFS_FLAG_RANGE));
- NvOsMutexLock(s_hPmcScratchMutex);
+ NvOsSpinMutexLock(s_hPmcScratchMutex);
RegValue = NV_REGR(hRmDeviceHandle, NvRmModuleID_Pmif, 0, RegOffset);
if (Pause)
@@ -178,7 +178,7 @@ NvRmPrivUpdateDfsPauseFlag(
RegValue &= ~mask;
NV_REGW(hRmDeviceHandle, NvRmModuleID_Pmif, 0, RegOffset, RegValue);
- NvOsMutexUnlock(s_hPmcScratchMutex);
+ NvOsSpinMutexUnlock(s_hPmcScratchMutex);
}
}
@@ -202,7 +202,7 @@ NvRmPrivPllRefUpdate(
mask = (pPllRef->StopFlag <<
NV_FIELD_SHIFT(APBDEV_PMC_SCRATCH0_0_RM_DFS_FLAG_RANGE));
- NvOsMutexLock(s_hPmcScratchMutex);
+ NvOsSpinMutexLock(s_hPmcScratchMutex);
if (Increment)
{
@@ -217,15 +217,19 @@ NvRmPrivPllRefUpdate(
else
{
NV_ASSERT(pPllRef->ReferenceCnt);
- pPllRef->ReferenceCnt--;
- if (pPllRef->ReferenceCnt == 0)
+ if (pPllRef->ReferenceCnt)
{
- RegValue = mask |
- (NV_REGR(hRmDeviceHandle, NvRmModuleID_Pmif, 0, RegOffset));
- NV_REGW(hRmDeviceHandle, NvRmModuleID_Pmif, 0, RegOffset, RegValue);
+ pPllRef->ReferenceCnt--;
+ if (pPllRef->ReferenceCnt == 0)
+ {
+ RegValue = mask |
+ (NV_REGR(hRmDeviceHandle, NvRmModuleID_Pmif, 0, RegOffset));
+ NV_REGW(
+ hRmDeviceHandle, NvRmModuleID_Pmif, 0, RegOffset, RegValue);
+ }
}
}
- NvOsMutexUnlock(s_hPmcScratchMutex);
+ NvOsSpinMutexUnlock(s_hPmcScratchMutex);
#endif
}
@@ -264,7 +268,7 @@ void NvRmPrivAp15IoPowerDetectReset(NvRmDeviceHandle hRmDeviceHandle)
{
NvU32 RegValue;
NvU32 RegOffset = APBDEV_PMC_SCRATCH0_0;
- NvOsMutexLock(s_hPmcScratchMutex);
+ NvOsSpinMutexLock(s_hPmcScratchMutex);
RegValue =
NV_REGR(hRmDeviceHandle, NvRmModuleID_Pmif, 0, RegOffset);
@@ -277,7 +281,7 @@ void NvRmPrivAp15IoPowerDetectReset(NvRmDeviceHandle hRmDeviceHandle)
NV_REGW(hRmDeviceHandle,
NvRmModuleID_Pmif, 0, RegOffset, RegValue);
- NvOsMutexUnlock(s_hPmcScratchMutex);
+ NvOsSpinMutexUnlock(s_hPmcScratchMutex);
}
}