@@ -397,22 +397,14 @@ static void _local_event_enable(void *data)
sdei_cross_call_return(arg, err);
}
-int sdei_event_enable(u32 event_num)
+int sdei_event_enable(struct sdei_event *event)
{
int err = -EINVAL;
- struct sdei_internal_event *event_el;
- struct sdei_event *event;
+ struct sdei_internal_event *event_el =
+ container_of(event, struct sdei_internal_event, event);
mutex_lock(&sdei_events_lock);
- event_el = sdei_event_find(event_num);
- if (!event_el) {
- mutex_unlock(&sdei_events_lock);
- return -ENOENT;
- }
-
-
cpus_read_lock();
- event = &event_el->event;
if (event->type == SDEI_EVENT_TYPE_SHARED)
err = sdei_api_event_enable(event->event_num);
else
@@ -445,24 +437,17 @@ static void _ipi_event_disable(void *data)
sdei_cross_call_return(arg, err);
}
-int sdei_event_disable(u32 event_num)
+int sdei_event_disable(struct sdei_event *event)
{
int err = -EINVAL;
- struct sdei_internal_event *event_el;
- struct sdei_event *event;
+ struct sdei_internal_event *event_el =
+ container_of(event, struct sdei_internal_event, event);
mutex_lock(&sdei_events_lock);
- event_el = sdei_event_find(event_num);
- if (!event_el) {
- mutex_unlock(&sdei_events_lock);
- return -ENOENT;
- }
-
spin_lock(&sdei_list_lock);
event_el->reenable = false;
spin_unlock(&sdei_list_lock);
- event = &event_el->event;
if (event->type == SDEI_EVENT_TYPE_SHARED)
err = sdei_api_event_disable(event->event_num);
else
@@ -491,28 +476,20 @@ static void _local_event_unregister(void *data)
sdei_cross_call_return(arg, err);
}
-int sdei_event_unregister(u32 event_num)
+int sdei_event_unregister(struct sdei_event *event)
{
int err;
- struct sdei_internal_event *event_el;
- struct sdei_event *event;
+ struct sdei_internal_event *event_el =
+ container_of(event, struct sdei_internal_event, event);
WARN_ON(in_nmi());
mutex_lock(&sdei_events_lock);
- event_el = sdei_event_find(event_num);
- if (!event_el) {
- pr_warn("Event %u not registered\n", event_num);
- err = -ENOENT;
- goto unlock;
- }
-
spin_lock(&sdei_list_lock);
event_el->reregister = false;
event_el->reenable = false;
spin_unlock(&sdei_list_lock);
- event = &event_el->event;
if (event->type == SDEI_EVENT_TYPE_SHARED)
err = sdei_api_event_unregister(event->event_num);
else
@@ -579,7 +556,9 @@ static void _local_event_register(void *data)
sdei_cross_call_return(arg, err);
}
-int sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg)
+struct sdei_event *sdei_event_register(u32 event_num,
+ sdei_event_callback *cb,
+ void *arg)
{
int err;
struct sdei_internal_event *event_el;
@@ -590,13 +569,14 @@ int sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg)
mutex_lock(&sdei_events_lock);
if (sdei_event_find(event_num)) {
pr_warn("Event %u already registered\n", event_num);
- err = -EBUSY;
+ event = ERR_PTR(-EBUSY);
goto unlock;
}
event_el = sdei_event_create(event_num, cb, arg);
if (IS_ERR(event_el)) {
err = PTR_ERR(event_el);
+ event = ERR_PTR(err);
pr_warn("Failed to create event %u: %d\n", event_num, err);
goto unlock;
}
@@ -615,11 +595,13 @@ int sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg)
}
if (err) {
+ event = ERR_PTR(err);
sdei_event_destroy(event_el);
pr_warn("Failed to register event %u: %d\n", event_num, err);
goto cpu_unlock;
}
+ event = &event_el->event;
spin_lock(&sdei_list_lock);
event_el->reregister = true;
spin_unlock(&sdei_list_lock);
@@ -627,7 +609,7 @@ int sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg)
cpus_read_unlock();
unlock:
mutex_unlock(&sdei_events_lock);
- return err;
+ return event;
}
static int sdei_reregister_shared(void)
@@ -876,6 +858,7 @@ int sdei_register_ghes(struct ghes *ghes, sdei_event_callback *normal_cb,
u64 result;
u32 event_num;
sdei_event_callback *cb;
+ struct sdei_event *event;
if (!IS_ENABLED(CONFIG_ACPI_APEI_GHES))
return -EOPNOTSUPP;
@@ -899,9 +882,13 @@ int sdei_register_ghes(struct ghes *ghes, sdei_event_callback *normal_cb,
else
cb = normal_cb;
- err = sdei_event_register(event_num, cb, ghes);
- if (!err)
- err = sdei_event_enable(event_num);
+ event = sdei_event_register(event_num, cb, ghes);
+ if (IS_ERR(event)) {
+ err = PTR_ERR(event);
+ return err;
+ }
+
+ err = sdei_event_enable(event);
return err;
}
@@ -911,22 +898,31 @@ int sdei_unregister_ghes(struct ghes *ghes)
int i;
int err;
u32 event_num = ghes->generic->notify.vector;
+ struct sdei_internal_event *event_el;
+ struct sdei_event *event;
might_sleep();
if (!IS_ENABLED(CONFIG_ACPI_APEI_GHES))
return -EOPNOTSUPP;
+ mutex_lock(&sdei_events_lock);
+ event_el = sdei_event_find(event_num);
+ mutex_unlock(&sdei_events_lock);
+ if (!event_el)
+ return -ENOENT;
+
/*
* The event may be running on another CPU. Disable it
* to stop new events, then try to unregister a few times.
*/
- err = sdei_event_disable(event_num);
+ event = &event_el->event;
+ err = sdei_event_disable(event);
if (err)
return err;
for (i = 0; i < 3; i++) {
- err = sdei_event_unregister(event_num);
+ err = sdei_event_unregister(event);
if (err != -EINPROGRESS)
break;
@@ -32,16 +32,18 @@ struct sdei_event {
* Register your callback to claim an event. The event must be described
* by firmware.
*/
-int sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg);
+struct sdei_event *sdei_event_register(u32 event_num,
+ sdei_event_callback *cb,
+ void *arg);
/*
* Calls to sdei_event_unregister() may return EINPROGRESS. Keep calling
* it until it succeeds.
*/
-int sdei_event_unregister(u32 event_num);
+int sdei_event_unregister(struct sdei_event *event);
-int sdei_event_enable(u32 event_num);
-int sdei_event_disable(u32 event_num);
+int sdei_event_enable(struct sdei_event *event);
+int sdei_event_disable(struct sdei_event *event);
/* GHES register/unregister helpers */
int sdei_register_ghes(struct ghes *ghes, sdei_event_callback *normal_cb,