]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blobdiff - linux/src/api/gates/GateHWSpinlock.c
Linux: GateHWSpinlock: Fix Compiler Warnings
[ipc/ipcdev.git] / linux / src / api / gates / GateHWSpinlock.c
index b57016a99cfd2aa4ec83f2d220b4248e1885af9d..5e4538c9a5ca799cfc9b3264be4c6d7ff20e306a 100644 (file)
@@ -61,17 +61,22 @@ typedef UInt32            Error_Block;
 #include <fcntl.h>
 #include <string.h>
 #include <stdlib.h>
+#include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
 
+#include <linux/hwspinlock_user.h>
+
 /* =============================================================================
  * Structures & Enums
  * =============================================================================
  */
 /* GateHWSpinlock Module Local State */
 typedef struct {
+    Int32                           fd;         /* spinlock device handle */
     UInt32 *                        baseAddr;   /* base addr lock registers */
     GateMutex_Handle                gmHandle;   /* handle to gate mutex */
+    Bool                            useHwlockDrv; /* use the hwspinlock driver */
 } GateHWSpinlock_Module_State;
 
 /* GateHWSpinlock instance object */
@@ -92,8 +97,10 @@ GateHWSpinlock_Config _GateHWSpinlock_cfgParams;
 
 static GateHWSpinlock_Module_State GateHWSpinlock_state =
 {
+    .fd = -1,
     .baseAddr = NULL,
-    .gmHandle = NULL
+    .gmHandle = NULL,
+    .useHwlockDrv = false,
 };
 
 static GateHWSpinlock_Module_State *Mod = &GateHWSpinlock_state;
@@ -170,36 +177,46 @@ Int32 GateHWSpinlock_start(Void)
 {
     Int32               status = GateHWSpinlock_S_SUCCESS;
     UInt32              dst;
-    Int32               fdMem;
     int                 flags;
 
-    fdMem = open ("/dev/mem", O_RDWR | O_SYNC);
-
-    if (fdMem < 0){
-        PRINTVERBOSE0("GateHWSpinlock_start: failed to open the /dev/mem");
-        status = GateHWSpinlock_E_OSFAILURE;
+    /* Fall back to /dev/mem if hwspinlock_user driver is not supported */
+    Mod->fd = open("/dev/hwspinlock", O_RDWR);
+    if (Mod->fd < 0) {
+        Mod->fd = open ("/dev/mem", O_RDWR | O_SYNC);
+    }
+    else {
+        Mod->useHwlockDrv = true;
     }
 
-    /* make sure /dev/mem fd doesn't exist for 'fork() -> exec*()'ed child */
-    flags = fcntl(fdMem, F_GETFD);
-    if (flags != -1) {
-        fcntl(fdMem, F_SETFD, flags | FD_CLOEXEC);
+    if (Mod->fd < 0){
+        PRINTVERBOSE0("GateHWSpinlock_start: failed to open the spinlock device");
+        status = GateHWSpinlock_E_OSFAILURE;
     }
 
-    /* map the hardware lock registers into the local address space */
-    if (status == GateHWSpinlock_S_SUCCESS) {
-        dst = (UInt32)mmap(NULL, _GateHWSpinlock_cfgParams.size,
-                            (PROT_READ | PROT_WRITE),
-                            (MAP_SHARED), fdMem,
-                            (off_t)_GateHWSpinlock_cfgParams.baseAddr);
-
-        if (dst == (UInt32)MAP_FAILED) {
-            PRINTVERBOSE0("GateHWSpinlock_start: Memory map failed")
-            status = GateHWSpinlock_E_OSFAILURE;
+    if (!Mod->useHwlockDrv) {
+        /* make sure /dev/mem fd doesn't exist for 'fork() -> exec*()'ed child */
+        flags = fcntl(Mod->fd, F_GETFD);
+        if (flags != -1) {
+            fcntl(Mod->fd, F_SETFD, flags | FD_CLOEXEC);
         }
-        else {
-            Mod->baseAddr = (UInt32 *)(dst + _GateHWSpinlock_cfgParams.offset);
-            status = GateHWSpinlock_S_SUCCESS;
+
+        /* map the hardware lock registers into the local address space */
+        if (status == GateHWSpinlock_S_SUCCESS) {
+            dst = (UInt32)mmap(NULL, _GateHWSpinlock_cfgParams.size,
+                               (PROT_READ | PROT_WRITE),
+                               (MAP_SHARED), Mod->fd,
+                               (off_t)_GateHWSpinlock_cfgParams.baseAddr);
+
+            if (dst == (UInt32)MAP_FAILED) {
+                PRINTVERBOSE0("GateHWSpinlock_start: Memory map failed")
+                    status = GateHWSpinlock_E_OSFAILURE;
+                close(Mod->fd);
+                Mod->fd = -1;
+            }
+            else {
+                Mod->baseAddr = (UInt32 *)(dst + _GateHWSpinlock_cfgParams.offset);
+                status = GateHWSpinlock_S_SUCCESS;
+            }
         }
     }
 
@@ -230,11 +247,17 @@ Int GateHWSpinlock_stop(Void)
     }
 
     /* release lock register mapping */
-    if (Mod->baseAddr != NULL) {
+    if (!Mod->useHwlockDrv && (Mod->baseAddr != NULL)) {
         munmap((void *)_GateHWSpinlock_cfgParams.baseAddr,
            _GateHWSpinlock_cfgParams.size);
     }
 
+    /* close the spinlock device file */
+    if (Mod->fd >= 0) {
+        close(Mod->fd);
+        Mod->fd = -1;
+    }
+
     return(status);
 }
 
@@ -302,7 +325,12 @@ Int GateHWSpinlock_delete (GateHWSpinlock_Handle * handle)
 IArg GateHWSpinlock_enter(GateHWSpinlock_Object *obj)
 {
     volatile UInt32 *baseAddr = Mod->baseAddr;
+    struct hwspinlock_user_lock data = {
+        .id = obj->lockNum,
+        .timeout = 10,
+    };
     IArg key;
+    Bool locked;
 
     key = IGateProvider_enter(obj->localGate);
 
@@ -314,10 +342,18 @@ IArg GateHWSpinlock_enter(GateHWSpinlock_Object *obj)
 
     /* enter the spinlock */
     while (1) {
-        /* read the spinlock, returns non-zero when we get it */
-        if (baseAddr[obj->lockNum] == 0) {
+        if (Mod->useHwlockDrv) {
+            locked = !ioctl(Mod->fd, HWSPINLOCK_USER_LOCK, &data);
+        }
+        else {
+            /* read the spinlock, returns non-zero when we get it */
+            locked = (baseAddr[obj->lockNum] == 0);
+        }
+
+        if (locked) {
             break;
         }
+
         obj->nested--;
         IGateProvider_leave(obj->localGate, key);
         key = IGateProvider_enter(obj->localGate);
@@ -333,12 +369,20 @@ IArg GateHWSpinlock_enter(GateHWSpinlock_Object *obj)
 Int GateHWSpinlock_leave(GateHWSpinlock_Object *obj, IArg key)
 {
     volatile UInt32 *baseAddr = Mod->baseAddr;
+    struct hwspinlock_user_unlock data = {
+        .id = obj->lockNum,
+    };
 
     obj->nested--;
 
     /* release the spinlock if not nested */
     if (obj->nested == 0) {
-        baseAddr[obj->lockNum] = 0;
+        if (Mod->useHwlockDrv) {
+            ioctl(Mod->fd, HWSPINLOCK_USER_UNLOCK, &data);
+        }
+        else {
+            baseAddr[obj->lockNum] = 0;
+        }
     }
 
     IGateProvider_leave(obj->localGate, key);