@@ -395,19 +395,13 @@ 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 *se)
{
int err = -EINVAL;
- struct sdei_internal_event *event;
+ struct sdei_internal_event *event =
+ container_of(se, struct sdei_internal_event, event);
mutex_lock(&sdei_events_lock);
- event = sdei_event_find(event_num);
- if (!event) {
- mutex_unlock(&sdei_events_lock);
- return -ENOENT;
- }
-
-
cpus_read_lock();
if (event->event.type == SDEI_EVENT_TYPE_SHARED)
err = sdei_api_event_enable(event->event.event_num);
@@ -441,18 +435,13 @@ 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 *se)
{
int err = -EINVAL;
- struct sdei_internal_event *event;
+ struct sdei_internal_event *event =
+ container_of(se, struct sdei_internal_event, event);
mutex_lock(&sdei_events_lock);
- event = sdei_event_find(event_num);
- if (!event) {
- mutex_unlock(&sdei_events_lock);
- return -ENOENT;
- }
-
spin_lock(&sdei_list_lock);
event->reenable = false;
spin_unlock(&sdei_list_lock);
@@ -485,21 +474,15 @@ 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 *se)
{
int err;
- struct sdei_internal_event *event;
+ struct sdei_internal_event *event =
+ container_of(se, struct sdei_internal_event, event);
WARN_ON(in_nmi());
mutex_lock(&sdei_events_lock);
- event = sdei_event_find(event_num);
- if (!event) {
- pr_warn("Event %u not registered\n", event_num);
- err = -ENOENT;
- goto unlock;
- }
-
spin_lock(&sdei_list_lock);
event->reregister = false;
event->reenable = false;
@@ -569,23 +552,27 @@ 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;
+ struct sdei_event *se;
WARN_ON(in_nmi());
mutex_lock(&sdei_events_lock);
if (sdei_event_find(event_num)) {
pr_warn("Event %u already registered\n", event_num);
- err = -EBUSY;
+ se = ERR_PTR(-EBUSY);
goto unlock;
}
event = sdei_event_create(event_num, cb, arg);
if (IS_ERR(event)) {
err = PTR_ERR(event);
+ se = ERR_PTR(err);
pr_warn("Failed to create event %u: %d\n", event_num, err);
goto unlock;
}
@@ -603,11 +590,13 @@ int sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg)
}
if (err) {
+ se = ERR_PTR(err);
sdei_event_destroy(event);
pr_warn("Failed to register event %u: %d\n", event_num, err);
goto cpu_unlock;
}
+ se = &event->event;
spin_lock(&sdei_list_lock);
event->reregister = true;
spin_unlock(&sdei_list_lock);
@@ -615,7 +604,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 se;
}
static int sdei_reregister_shared(void)
@@ -858,6 +847,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 *se;
if (!IS_ENABLED(CONFIG_ACPI_APEI_GHES))
return -EOPNOTSUPP;
@@ -881,9 +871,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);
+ se = sdei_event_register(event_num, cb, ghes);
+ if (IS_ERR(se)) {
+ err = PTR_ERR(se);
+ return err;
+ }
+
+ err = sdei_event_enable(se);
return err;
}
@@ -893,22 +887,29 @@ int sdei_unregister_ghes(struct ghes *ghes)
int i;
int err;
u32 event_num = ghes->generic->notify.vector;
+ struct sdei_internal_event *event;
might_sleep();
if (!IS_ENABLED(CONFIG_ACPI_APEI_GHES))
return -EOPNOTSUPP;
+ mutex_lock(&sdei_events_lock);
+ event = sdei_event_find(event_num);
+ mutex_unlock(&sdei_events_lock);
+ if (!event)
+ 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);
+ err = sdei_event_disable(&event->event);
if (err)
return err;
for (i = 0; i < 3; i++) {
- err = sdei_event_unregister(event_num);
+ err = sdei_event_unregister(&event->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 *se);
-int sdei_event_enable(u32 event_num);
-int sdei_event_disable(u32 event_num);
+int sdei_event_enable(struct sdei_event *se);
+int sdei_event_disable(struct sdei_event *se);
/* GHES register/unregister helpers */
int sdei_register_ghes(struct ghes *ghes, sdei_event_callback *normal_cb,