diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp
index 1a6007bf..566f8ce1 100644
--- a/src/core/libraries/gnmdriver/gnmdriver.cpp
+++ b/src/core/libraries/gnmdriver/gnmdriver.cpp
@@ -29,7 +29,7 @@ namespace Libraries::GnmDriver {
 
 using namespace AmdGpu;
 
-enum GnmEventIdents : u64 {
+enum GnmEventType : u64 {
     Compute0RelMem = 0x00,
     Compute1RelMem = 0x01,
     Compute2RelMem = 0x02,
@@ -337,6 +337,12 @@ static inline u32* ClearContextState(u32* cmdbuf) {
     return cmdbuf + ClearStateSequence.size();
 }
 
+static inline bool IsValidEventType(Platform::InterruptId id) {
+    return (static_cast<u32>(id) >= static_cast<u32>(Platform::InterruptId::Compute0RelMem) &&
+            static_cast<u32>(id) <= static_cast<u32>(Platform::InterruptId::Compute6RelMem)) ||
+           static_cast<u32>(id) == static_cast<u32>(Platform::InterruptId::GfxEop);
+}
+
 s32 PS4_SYSV_ABI sceGnmAddEqEvent(SceKernelEqueue eq, u64 id, void* udata) {
     LOG_TRACE(Lib_GnmDriver, "called");
 
@@ -347,8 +353,7 @@ s32 PS4_SYSV_ABI sceGnmAddEqEvent(SceKernelEqueue eq, u64 id, void* udata) {
     EqueueEvent kernel_event{};
     kernel_event.event.ident = id;
     kernel_event.event.filter = SceKernelEvent::Filter::GraphicsCore;
-    // The library only sets EV_ADD but it is suspected the kernel driver forces EV_CLEAR
-    kernel_event.event.flags = SceKernelEvent::Flags::Clear;
+    kernel_event.event.flags = SceKernelEvent::Flags::Add;
     kernel_event.event.fflags = 0;
     kernel_event.event.data = id;
     kernel_event.event.udata = udata;
@@ -357,11 +362,15 @@ s32 PS4_SYSV_ABI sceGnmAddEqEvent(SceKernelEqueue eq, u64 id, void* udata) {
     Platform::IrqC::Instance()->Register(
         static_cast<Platform::InterruptId>(id),
         [=](Platform::InterruptId irq) {
-            ASSERT_MSG(irq == static_cast<Platform::InterruptId>(id),
-                       "An unexpected IRQ occured"); // We need to convert IRQ# to event id and do
-                                                     // proper filtering in trigger function
-            eq->TriggerEvent(static_cast<GnmEventIdents>(id), SceKernelEvent::Filter::GraphicsCore,
-                             nullptr);
+            ASSERT_MSG(irq == static_cast<Platform::InterruptId>(id), "An unexpected IRQ occured");
+
+            // We need to convert IRQ# to event id
+            if (!IsValidEventType(irq))
+                return;
+
+            // Event data is expected to be an event type as per sceGnmGetEqEventType.
+            eq->TriggerEvent(static_cast<GnmEventType>(id), SceKernelEvent::Filter::GraphicsCore,
+                             reinterpret_cast<void*>(id));
         },
         eq);
     return ORBIS_OK;
@@ -476,7 +485,7 @@ s32 PS4_SYSV_ABI sceGnmDeleteEqEvent(SceKernelEqueue eq, u64 id) {
         return ORBIS_KERNEL_ERROR_EBADF;
     }
 
-    eq->RemoveEvent(id);
+    eq->RemoveEvent(id, SceKernelEvent::Filter::GraphicsCore);
 
     Platform::IrqC::Instance()->Unregister(static_cast<Platform::InterruptId>(id), eq);
     return ORBIS_OK;
@@ -1000,9 +1009,13 @@ int PS4_SYSV_ABI sceGnmGetDebugTimestamp() {
     return ORBIS_OK;
 }
 
-int PS4_SYSV_ABI sceGnmGetEqEventType() {
-    LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
-    return ORBIS_OK;
+int PS4_SYSV_ABI sceGnmGetEqEventType(const SceKernelEvent* ev) {
+    LOG_TRACE(Lib_GnmDriver, "called");
+
+    auto data = sceKernelGetEventData(ev);
+    ASSERT(static_cast<GnmEventType>(data) == GnmEventType::GfxEop);
+
+    return data;
 }
 
 int PS4_SYSV_ABI sceGnmGetEqTimeStamp() {
diff --git a/src/core/libraries/gnmdriver/gnmdriver.h b/src/core/libraries/gnmdriver/gnmdriver.h
index 017dbe3a..d1548332 100644
--- a/src/core/libraries/gnmdriver/gnmdriver.h
+++ b/src/core/libraries/gnmdriver/gnmdriver.h
@@ -85,7 +85,7 @@ int PS4_SYSV_ABI sceGnmGetCoredumpMode();
 int PS4_SYSV_ABI sceGnmGetCoredumpProtectionFaultTimestamp();
 int PS4_SYSV_ABI sceGnmGetDbgGcHandle();
 int PS4_SYSV_ABI sceGnmGetDebugTimestamp();
-int PS4_SYSV_ABI sceGnmGetEqEventType();
+int PS4_SYSV_ABI sceGnmGetEqEventType(const SceKernelEvent* ev);
 int PS4_SYSV_ABI sceGnmGetEqTimeStamp();
 int PS4_SYSV_ABI sceGnmGetGpuBlockStatus();
 u32 PS4_SYSV_ABI sceGnmGetGpuCoreClockFrequency();
diff --git a/src/core/libraries/kernel/equeue.cpp b/src/core/libraries/kernel/equeue.cpp
index 42a8eed8..3ae77e46 100644
--- a/src/core/libraries/kernel/equeue.cpp
+++ b/src/core/libraries/kernel/equeue.cpp
@@ -12,6 +12,8 @@
 
 namespace Libraries::Kernel {
 
+// Events are uniquely identified by id and filter.
+
 bool EqueueInternal::AddEvent(EqueueEvent& event) {
     std::scoped_lock lock{m_mutex};
 
@@ -27,12 +29,13 @@ bool EqueueInternal::AddEvent(EqueueEvent& event) {
     return true;
 }
 
-bool EqueueInternal::RemoveEvent(u64 id) {
+bool EqueueInternal::RemoveEvent(u64 id, s16 filter) {
     bool has_found = false;
     std::scoped_lock lock{m_mutex};
 
-    const auto& it =
-        std::ranges::find_if(m_events, [id](auto& ev) { return ev.event.ident == id; });
+    const auto& it = std::ranges::find_if(m_events, [id, filter](auto& ev) {
+        return ev.event.ident == id && ev.event.filter == filter;
+    });
     if (it != m_events.cend()) {
         m_events.erase(it);
         has_found = true;
@@ -68,7 +71,7 @@ int EqueueInternal::WaitForEvents(SceKernelEvent* ev, int num, u32 micros) {
 
     if (ev->flags & SceKernelEvent::Flags::OneShot) {
         for (auto ev_id = 0u; ev_id < count; ++ev_id) {
-            RemoveEvent(ev->ident);
+            RemoveEvent(ev->ident, ev->filter);
         }
     }
 
@@ -94,8 +97,11 @@ int EqueueInternal::GetTriggeredEvents(SceKernelEvent* ev, int num) {
     int count = 0;
     for (auto& event : m_events) {
         if (event.IsTriggered()) {
+            // Event should not trigger again
+            event.ResetTriggerState();
+
             if (event.event.flags & SceKernelEvent::Flags::Clear) {
-                event.Reset();
+                event.Clear();
             }
             ev[count++] = event.event;
             if (count == num) {
@@ -334,7 +340,7 @@ int PS4_SYSV_ABI sceKernelDeleteUserEvent(SceKernelEqueue eq, int id) {
         return ORBIS_KERNEL_ERROR_EBADF;
     }
 
-    if (!eq->RemoveEvent(id)) {
+    if (!eq->RemoveEvent(id, SceKernelEvent::Filter::User)) {
         return ORBIS_KERNEL_ERROR_ENOENT;
     }
     return ORBIS_OK;
@@ -344,6 +350,10 @@ s16 PS4_SYSV_ABI sceKernelGetEventFilter(const SceKernelEvent* ev) {
     return ev->filter;
 }
 
+u64 PS4_SYSV_ABI sceKernelGetEventData(const SceKernelEvent* ev) {
+    return ev->data;
+}
+
 void RegisterEventQueue(Core::Loader::SymbolsResolver* sym) {
     LIB_FUNCTION("D0OdFMjp46I", "libkernel", 1, "libkernel", 1, 1, sceKernelCreateEqueue);
     LIB_FUNCTION("jpFjmgAC5AE", "libkernel", 1, "libkernel", 1, 1, sceKernelDeleteEqueue);
@@ -356,6 +366,7 @@ void RegisterEventQueue(Core::Loader::SymbolsResolver* sym) {
     LIB_FUNCTION("LJDwdSNTnDg", "libkernel", 1, "libkernel", 1, 1, sceKernelDeleteUserEvent);
     LIB_FUNCTION("mJ7aghmgvfc", "libkernel", 1, "libkernel", 1, 1, sceKernelGetEventId);
     LIB_FUNCTION("23CPPI1tyBY", "libkernel", 1, "libkernel", 1, 1, sceKernelGetEventFilter);
+    LIB_FUNCTION("kwGyyjohI50", "libkernel", 1, "libkernel", 1, 1, sceKernelGetEventData);
 }
 
 } // namespace Libraries::Kernel
diff --git a/src/core/libraries/kernel/equeue.h b/src/core/libraries/kernel/equeue.h
index 5a13bdec..f8759137 100644
--- a/src/core/libraries/kernel/equeue.h
+++ b/src/core/libraries/kernel/equeue.h
@@ -66,8 +66,11 @@ struct EqueueEvent {
     std::chrono::steady_clock::time_point time_added;
     std::unique_ptr<boost::asio::steady_timer> timer;
 
-    void Reset() {
+    void ResetTriggerState() {
         is_triggered = false;
+    }
+
+    void Clear() {
         event.fflags = 0;
         event.data = 0;
     }
@@ -83,7 +86,7 @@ struct EqueueEvent {
     }
 
     bool operator==(const EqueueEvent& ev) const {
-        return ev.event.ident == event.ident;
+        return ev.event.ident == event.ident && ev.event.filter == event.filter;
     }
 
 private:
@@ -99,7 +102,7 @@ public:
     }
 
     bool AddEvent(EqueueEvent& event);
-    bool RemoveEvent(u64 id);
+    bool RemoveEvent(u64 id, s16 filter);
     int WaitForEvents(SceKernelEvent* ev, int num, u32 micros);
     bool TriggerEvent(u64 ident, s16 filter, void* trigger_data);
     int GetTriggeredEvents(SceKernelEvent* ev, int num);
@@ -122,6 +125,8 @@ private:
 using SceKernelUseconds = u32;
 using SceKernelEqueue = EqueueInternal*;
 
+u64 PS4_SYSV_ABI sceKernelGetEventData(const SceKernelEvent* ev);
+
 void RegisterEventQueue(Core::Loader::SymbolsResolver* sym);
 
 } // namespace Libraries::Kernel