summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGowtham Tammana2016-11-07 11:37:18 -0600
committerGowtham Tammana2016-12-14 12:09:03 -0600
commit65887c911db495fb66c6847c8b6eadc76c7470f4 (patch)
treefb590e98f8116c509ff7fd94177f69e7213deb7c
parent7a2b06ad1df46a274336f7ae0e24a9d67e72cd66 (diff)
downloadti-gc320-driver-65887c911db495fb66c6847c8b6eadc76c7470f4.tar.gz
ti-gc320-driver-65887c911db495fb66c6847c8b6eadc76c7470f4.tar.xz
ti-gc320-driver-65887c911db495fb66c6847c8b6eadc76c7470f4.zip
Add support for RT kernel
The `gckOS_WaitSignal` API in the driver is same as `wait_for_completion_interruptible_timeout` kernel completion API except for the additional `manualReset`. In the case of RT kernel, `wait_for_completion` API is updated to use raw spinlocks and swait instead of spinlock and waitqueue. Update the `gckOS_WaitSignal` to use correct completion mechanism for RT kernels. The presence of RT kernel is determined by the presence of the `CONFIG_PREEMPT_RT_BASE` kernel config option. Signed-off-by: Gowtham Tammana <g-tammana@ti.com>
-rwxr-xr-xsrc/Kbuild6
-rwxr-xr-xsrc/hal/os/linux/kernel/gc_hal_kernel_os.c38
2 files changed, 42 insertions, 2 deletions
diff --git a/src/Kbuild b/src/Kbuild
index f952b62..574a107 100755
--- a/src/Kbuild
+++ b/src/Kbuild
@@ -244,6 +244,12 @@ else
244EXTRA_CFLAGS += -DgcdENABLE_OUTER_CACHE_PATCH=0 244EXTRA_CFLAGS += -DgcdENABLE_OUTER_CACHE_PATCH=0
245endif 245endif
246 246
247ifneq ($(CONFIG_PREEMPT_RT_BASE),)
248EXTRA_CFLAGS += -DgcdRT_KERNEL=1
249else
250EXTRA_CFLAGS += -DgcdRT_KERNEL=0
251endif
252
247ifeq ($(USE_BANK_ALIGNMENT), 1) 253ifeq ($(USE_BANK_ALIGNMENT), 1)
248 EXTRA_CFLAGS += -DgcdENABLE_BANK_ALIGNMENT=1 254 EXTRA_CFLAGS += -DgcdENABLE_BANK_ALIGNMENT=1
249 ifneq ($(BANK_BIT_START), 0) 255 ifneq ($(BANK_BIT_START), 0)
diff --git a/src/hal/os/linux/kernel/gc_hal_kernel_os.c b/src/hal/os/linux/kernel/gc_hal_kernel_os.c
index 5b97898..354a272 100755
--- a/src/hal/os/linux/kernel/gc_hal_kernel_os.c
+++ b/src/hal/os/linux/kernel/gc_hal_kernel_os.c
@@ -6983,7 +6983,11 @@ gckOS_WaitSignal(
6983 6983
6984 might_sleep(); 6984 might_sleep();
6985 6985
6986#if gcdRT_KERNEL
6987 raw_spin_lock_irq(&signal->obj.wait.lock);
6988#else
6986 spin_lock_irq(&signal->obj.wait.lock); 6989 spin_lock_irq(&signal->obj.wait.lock);
6990#endif
6987 6991
6988 if (signal->obj.done) 6992 if (signal->obj.done)
6989 { 6993 {
@@ -7005,9 +7009,19 @@ gckOS_WaitSignal(
7005 ? MAX_SCHEDULE_TIMEOUT 7009 ? MAX_SCHEDULE_TIMEOUT
7006 : Wait * HZ / 1000; 7010 : Wait * HZ / 1000;
7007 7011
7012#if gcdRT_KERNEL
7013 DECLARE_SWAITQUEUE(wait);
7014 /* using __prepare_to_swait definition, as its not exported. This
7015 * is same as `wait_for_completion()` except for the manualReset.
7016 */
7017 wait.task = current;
7018 if (list_empty(&wait.task_list))
7019 list_add(&wait.task_list, &signal->obj.wait.task_list);
7020#else
7008 DECLARE_WAITQUEUE(wait, current); 7021 DECLARE_WAITQUEUE(wait, current);
7009 wait.flags |= WQ_FLAG_EXCLUSIVE; 7022 wait.flags |= WQ_FLAG_EXCLUSIVE;
7010 __add_wait_queue_tail(&signal->obj.wait, &wait); 7023 __add_wait_queue_tail(&signal->obj.wait, &wait);
7024#endif
7011 7025
7012 while (gcvTRUE) 7026 while (gcvTRUE)
7013 { 7027 {
@@ -7019,9 +7033,20 @@ gckOS_WaitSignal(
7019 } 7033 }
7020 7034
7021 __set_current_state(TASK_INTERRUPTIBLE); 7035 __set_current_state(TASK_INTERRUPTIBLE);
7036
7037#if gcdRT_KERNEL
7038 raw_spin_unlock_irq(&signal->obj.wait.lock);
7039#else
7022 spin_unlock_irq(&signal->obj.wait.lock); 7040 spin_unlock_irq(&signal->obj.wait.lock);
7041#endif
7042
7023 timeout = schedule_timeout(timeout); 7043 timeout = schedule_timeout(timeout);
7044
7045#if gcdRT_KERNEL
7046 raw_spin_lock_irq(&signal->obj.wait.lock);
7047#else
7024 spin_lock_irq(&signal->obj.wait.lock); 7048 spin_lock_irq(&signal->obj.wait.lock);
7049#endif
7025 7050
7026 if (signal->obj.done) 7051 if (signal->obj.done)
7027 { 7052 {
@@ -7036,17 +7061,26 @@ gckOS_WaitSignal(
7036 7061
7037 if (timeout == 0) 7062 if (timeout == 0)
7038 { 7063 {
7039
7040 status = gcvSTATUS_TIMEOUT; 7064 status = gcvSTATUS_TIMEOUT;
7041 break; 7065 break;
7042 } 7066 }
7043 } 7067 }
7044 7068
7069#if gcdRT_KERNEL
7070 /* using __finish_swait definition, as its not exported */
7071 __set_current_state(TASK_RUNNING);
7072 if (!list_empty(&wait.task_list))
7073 list_del_init(&wait.task_list);
7074#else
7045 __remove_wait_queue(&signal->obj.wait, &wait); 7075 __remove_wait_queue(&signal->obj.wait, &wait);
7076#endif
7046 } 7077 }
7047 7078
7079#if gcdRT_KERNEL
7080 raw_spin_unlock_irq(&signal->obj.wait.lock);
7081#else
7048 spin_unlock_irq(&signal->obj.wait.lock); 7082 spin_unlock_irq(&signal->obj.wait.lock);
7049 7083#endif
7050OnError: 7084OnError:
7051 /* Return status. */ 7085 /* Return status. */
7052 gcmkFOOTER_ARG("Signal=0x%X status=%d", Signal, status); 7086 gcmkFOOTER_ARG("Signal=0x%X status=%d", Signal, status);