summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/shared
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-02-21 15:25:03 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-02-23 07:27:39 +0100
commit33986022af8f5389370cb012ba0e73e032774cab (patch)
tree378acbd1600783b5ff8d8fb84c533c14c5015b91 /c/src/lib/libbsp/shared
parentbsp/xilinx-zynq: Add interrupt support to UART (diff)
downloadrtems-33986022af8f5389370cb012ba0e73e032774cab.tar.bz2
Add rtems_interrupt_server_request_submit()
This function may be used to do a two-step interrupt processing. The first step is done in interrupt context which calls this function. The second step is then done in the context of the interrupt server.
Diffstat (limited to 'c/src/lib/libbsp/shared')
-rw-r--r--c/src/lib/libbsp/shared/src/irq-server.c148
1 files changed, 116 insertions, 32 deletions
diff --git a/c/src/lib/libbsp/shared/src/irq-server.c b/c/src/lib/libbsp/shared/src/irq-server.c
index 4f127af7ba..905c26198b 100644
--- a/c/src/lib/libbsp/shared/src/irq-server.c
+++ b/c/src/lib/libbsp/shared/src/irq-server.c
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (c) 2009, 2016 embedded brains GmbH. All rights reserved.
+ * Copyright (c) 2009, 2017 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -28,24 +28,14 @@
#include <bsp/irq-generic.h>
+#define BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR (BSP_INTERRUPT_VECTOR_MAX + 1)
+
RTEMS_INTERRUPT_LOCK_DEFINE(
static,
bsp_interrupt_server_lock,
"Interrupt Server"
)
-typedef struct bsp_interrupt_server_action {
- struct bsp_interrupt_server_action *next;
- rtems_interrupt_handler handler;
- void *arg;
-} bsp_interrupt_server_action;
-
-typedef struct {
- rtems_chain_node node;
- rtems_vector_number vector;
- bsp_interrupt_server_action *actions;
-} bsp_interrupt_server_entry;
-
static rtems_id bsp_interrupt_server_id = RTEMS_ID_NONE;
static RTEMS_CHAIN_DEFINE_EMPTY(bsp_interrupt_server_chain);
@@ -64,7 +54,7 @@ static unsigned bsp_interrupt_server_errors;
static void bsp_interrupt_server_trigger(void *arg)
{
rtems_interrupt_lock_context lock_context;
- bsp_interrupt_server_entry *e = arg;
+ rtems_interrupt_server_entry *e = arg;
bsp_interrupt_vector_disable(e->vector);
@@ -82,7 +72,7 @@ static void bsp_interrupt_server_trigger(void *arg)
}
typedef struct {
- bsp_interrupt_server_entry *entry;
+ rtems_interrupt_server_entry *entry;
rtems_option *options;
} bsp_interrupt_server_iterate_entry;
@@ -102,7 +92,7 @@ static void bsp_interrupt_server_per_handler_routine(
}
}
-static bsp_interrupt_server_entry *bsp_interrupt_server_query_entry(
+static rtems_interrupt_server_entry *bsp_interrupt_server_query_entry(
rtems_vector_number vector,
rtems_option *trigger_options
)
@@ -134,8 +124,8 @@ static void bsp_interrupt_server_install_helper(void *arg)
{
bsp_interrupt_server_helper_data *hd = arg;
rtems_status_code sc;
- bsp_interrupt_server_entry *e;
- bsp_interrupt_server_action *a;
+ rtems_interrupt_server_entry *e;
+ rtems_interrupt_server_action *a;
rtems_option trigger_options;
a = calloc(1, sizeof(*a));
@@ -176,8 +166,8 @@ static void bsp_interrupt_server_install_helper(void *arg)
) {
sc = RTEMS_RESOURCE_IN_USE;
} else {
- bsp_interrupt_server_action **link = &e->actions;
- bsp_interrupt_server_action *c;
+ rtems_interrupt_server_action **link = &e->actions;
+ rtems_interrupt_server_action *c;
sc = RTEMS_SUCCESSFUL;
@@ -209,15 +199,15 @@ static void bsp_interrupt_server_remove_helper(void *arg)
{
bsp_interrupt_server_helper_data *hd = arg;
rtems_status_code sc;
- bsp_interrupt_server_entry *e;
+ rtems_interrupt_server_entry *e;
rtems_option trigger_options;
bsp_interrupt_lock();
e = bsp_interrupt_server_query_entry(hd->vector, &trigger_options);
if (e != NULL) {
- bsp_interrupt_server_action **link = &e->actions;
- bsp_interrupt_server_action *c;
+ rtems_interrupt_server_action **link = &e->actions;
+ rtems_interrupt_server_action *c;
while ((c = *link) != NULL) {
if (c->handler == hd->handler && c->arg == hd->arg) {
@@ -274,12 +264,12 @@ static rtems_status_code bsp_interrupt_server_call_helper(
.arg = arg,
.task = rtems_task_self()
};
- bsp_interrupt_server_action a = {
+ rtems_interrupt_server_action a = {
.handler = helper,
.arg = &hd
};
- bsp_interrupt_server_entry e = {
- .vector = BSP_INTERRUPT_VECTOR_MAX + 1,
+ rtems_interrupt_server_entry e = {
+ .vector = BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
.actions = &a
};
@@ -289,17 +279,17 @@ static rtems_status_code bsp_interrupt_server_call_helper(
return hd.sc;
}
-static bsp_interrupt_server_entry *bsp_interrupt_server_get_entry(void)
+static rtems_interrupt_server_entry *bsp_interrupt_server_get_entry(void)
{
rtems_interrupt_lock_context lock_context;
- bsp_interrupt_server_entry *e;
+ rtems_interrupt_server_entry *e;
rtems_chain_control *chain;
rtems_interrupt_lock_acquire(&bsp_interrupt_server_lock, &lock_context);
chain = &bsp_interrupt_server_chain;
if (!rtems_chain_is_empty(chain)) {
- e = (bsp_interrupt_server_entry *)
+ e = (rtems_interrupt_server_entry *)
rtems_chain_get_first_unprotected(chain);
rtems_chain_set_off_chain(&e->node);
} else {
@@ -315,7 +305,7 @@ static void bsp_interrupt_server_task(rtems_task_argument arg)
{
while (true) {
rtems_event_set events;
- bsp_interrupt_server_entry *e;
+ rtems_interrupt_server_entry *e;
rtems_event_system_receive(
RTEMS_EVENT_SYSTEM_SERVER,
@@ -325,11 +315,11 @@ static void bsp_interrupt_server_task(rtems_task_argument arg)
);
while ((e = bsp_interrupt_server_get_entry()) != NULL) {
- bsp_interrupt_server_action *action = e->actions;
+ rtems_interrupt_server_action *action = e->actions;
rtems_vector_number vector = e->vector;
do {
- bsp_interrupt_server_action *current = action;
+ rtems_interrupt_server_action *current = action;
action = action->next;
(*current->handler)(current->arg);
} while (action != NULL);
@@ -430,3 +420,97 @@ rtems_status_code rtems_interrupt_server_initialize(
return RTEMS_SUCCESSFUL;
}
+
+static void bsp_interrupt_server_entry_initialize(
+ rtems_interrupt_server_entry *entry
+)
+{
+ rtems_chain_set_off_chain(&entry->node);
+ entry->vector = BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR;
+ entry->actions = NULL;
+}
+
+static void bsp_interrupt_server_action_prepend(
+ rtems_interrupt_server_entry *entry,
+ rtems_interrupt_server_action *action,
+ rtems_interrupt_handler handler,
+ void *arg
+)
+{
+ action->handler = handler;
+ action->arg = arg;
+ action->next = entry->actions;
+ entry->actions = action;
+}
+
+void rtems_interrupt_server_entry_initialize(
+ rtems_interrupt_server_entry *entry
+)
+{
+ bsp_interrupt_server_entry_initialize(entry);
+}
+
+void rtems_interrupt_server_action_prepend(
+ rtems_interrupt_server_entry *entry,
+ rtems_interrupt_server_action *action,
+ rtems_interrupt_handler handler,
+ void *arg
+)
+{
+ bsp_interrupt_server_action_prepend(entry, action, handler, arg);
+}
+
+void rtems_interrupt_server_entry_submit(
+ rtems_id server,
+ rtems_interrupt_server_entry *entry
+)
+{
+ bsp_interrupt_server_trigger(entry);
+}
+
+static void bsp_interrupt_server_entry_destroy_helper(void *arg)
+{
+ bsp_interrupt_server_helper_data *hd = arg;
+
+ rtems_event_transient_send(hd->task);
+}
+
+void rtems_interrupt_server_entry_destroy(
+ rtems_id server,
+ rtems_interrupt_server_entry *entry
+)
+{
+ rtems_interrupt_lock_context lock_context;
+
+ rtems_interrupt_lock_acquire(&bsp_interrupt_server_lock, &lock_context);
+
+ if (!rtems_chain_is_node_off_chain(&entry->node)) {
+ rtems_chain_extract_unprotected(&entry->node);
+ rtems_chain_set_off_chain(&entry->node);
+ }
+
+ rtems_interrupt_lock_release(&bsp_interrupt_server_lock, &lock_context);
+
+ bsp_interrupt_server_call_helper(
+ BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
+ 0,
+ NULL,
+ NULL,
+ bsp_interrupt_server_entry_destroy_helper
+ );
+}
+
+void rtems_interrupt_server_request_initialize(
+ rtems_interrupt_server_request *request,
+ rtems_interrupt_handler handler,
+ void *arg
+)
+{
+ bsp_interrupt_server_entry_initialize(&request->entry);
+ bsp_interrupt_server_action_prepend(
+ &request->entry,
+ &request->action,
+ handler,
+ arg
+ );
+}