summaryrefslogtreecommitdiff
path: root/gxp-mb-notification.c
diff options
context:
space:
mode:
Diffstat (limited to 'gxp-mb-notification.c')
-rw-r--r--gxp-mb-notification.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/gxp-mb-notification.c b/gxp-mb-notification.c
new file mode 100644
index 0000000..3198984
--- /dev/null
+++ b/gxp-mb-notification.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * GXP notification implementation on top of the mailbox driver.
+ *
+ * Copyright (C) 2021 Google LLC
+ */
+
+#include <linux/bitops.h>
+
+#include "gxp-mailbox.h"
+#include "gxp-mailbox-driver.h"
+#include "gxp-notification.h"
+
+int gxp_notification_register_handler(struct gxp_dev *gxp, uint core,
+ enum gxp_notification_to_host_type type,
+ struct work_struct *handler)
+{
+ struct gxp_mailbox *mailbox;
+
+ if (core >= GXP_NUM_CORES || type >= HOST_NOTIF_MAX)
+ return -EINVAL;
+
+ mailbox = gxp->mailbox_mgr->mailboxes[core];
+ if (!mailbox)
+ return -ENODEV;
+
+ return gxp_mailbox_register_interrupt_handler(mailbox, type, handler);
+}
+
+int gxp_notification_unregister_handler(struct gxp_dev *gxp, uint core,
+ enum gxp_notification_to_host_type type)
+{
+ struct gxp_mailbox *mailbox;
+
+ if (core >= GXP_NUM_CORES || type >= HOST_NOTIF_MAX)
+ return -EINVAL;
+
+ mailbox = gxp->mailbox_mgr->mailboxes[core];
+ if (!mailbox)
+ return-ENODEV;
+
+ return gxp_mailbox_unregister_interrupt_handler(mailbox, type);
+}
+
+int gxp_notification_send(struct gxp_dev *gxp, uint core,
+ enum gxp_notification_to_core_type type)
+{
+ struct gxp_mailbox *mailbox;
+
+ /*
+ * The mailbox submodule handles outgoing command interrupts directly
+ * so `CORE_NOTIF_MAILBOX_COMMAND` is not a valid input for this
+ * implementation.
+ */
+ if (core >= GXP_NUM_CORES || type == CORE_NOTIF_MAILBOX_COMMAND ||
+ type >= GXP_MAILBOX_INT_BIT_COUNT || type >= CORE_NOTIF_MAX)
+ return -EINVAL;
+
+ mailbox = gxp->mailbox_mgr->mailboxes[core];
+ if (!mailbox)
+ return -ENODEV;
+
+ gxp_mailbox_generate_device_interrupt(mailbox, BIT(type));
+
+ return 0;
+}