Skip to content

Commit b5daf93

Browse files
cris-masudeep-holla
authored andcommitted
firmware: arm_scmi: Avoid notifier registration for unsupported events
Some platforms may be configured to not support notification events from certain sources. This scenario is already handled gracefully by avoiding any attempt to send a notification enable request for those sources, as such requests would inevitably fail. However, in a more extreme case, a platform might not support even a single source for a given event type. In this situation, allowing notifier registration is meaningless. Attempting to register a notifier would serve no purpose and only result in unnecessary overhead. To address this, we now detect such conditions during the protocol initialization. When identified, we flag the unsupported event types and reject any subsequent notifier registration attempts for them with -ENOTSUPP. This early rejection avoids redundant processing and simplifies runtime logic. Signed-off-by: Cristian Marussi <cristian.marussi@arm.com> Message-Id: <20250707144220.485365-1-cristian.marussi@arm.com> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
1 parent 9a0658d commit b5daf93

1 file changed

Lines changed: 30 additions & 9 deletions

File tree

drivers/firmware/arm_scmi/notify.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,9 @@ struct scmi_registered_events_desc {
318318
* customized event report
319319
* @num_sources: The number of possible sources for this event as stated at
320320
* events' registration time
321+
* @not_supported_by_platform: A flag to indicate that not even one source was
322+
* found to be supported by the platform for this
323+
* event
321324
* @sources: A reference to a dynamically allocated array used to refcount the
322325
* events' enable requests for all the existing sources
323326
* @sources_mtx: A mutex to serialize the access to @sources
@@ -334,6 +337,7 @@ struct scmi_registered_event {
334337
const struct scmi_event *evt;
335338
void *report;
336339
u32 num_sources;
340+
bool not_supported_by_platform;
337341
refcount_t *sources;
338342
/* locking to serialize the access to sources */
339343
struct mutex sources_mtx;
@@ -811,10 +815,19 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id,
811815
if (!r_evt->report)
812816
return -ENOMEM;
813817

814-
for (id = 0; id < r_evt->num_sources; id++)
815-
if (ee->ops->is_notify_supported &&
816-
!ee->ops->is_notify_supported(ph, r_evt->evt->id, id))
817-
refcount_set(&r_evt->sources[id], NOTIF_UNSUPP);
818+
if (ee->ops->is_notify_supported) {
819+
int supported = 0;
820+
821+
for (id = 0; id < r_evt->num_sources; id++) {
822+
if (!ee->ops->is_notify_supported(ph, r_evt->evt->id, id))
823+
refcount_set(&r_evt->sources[id], NOTIF_UNSUPP);
824+
else
825+
supported++;
826+
}
827+
828+
/* Not even one source has been found to be supported */
829+
r_evt->not_supported_by_platform = !supported;
830+
}
818831

819832
pd->registered_events[i] = r_evt;
820833
/* Ensure events are updated */
@@ -936,6 +949,11 @@ static inline int scmi_bind_event_handler(struct scmi_notify_instance *ni,
936949
* of protocol instance.
937950
*/
938951
hash_del(&hndl->hash);
952+
953+
/* Bailout if event is not supported at all */
954+
if (r_evt->not_supported_by_platform)
955+
return -EOPNOTSUPP;
956+
939957
/*
940958
* Acquire protocols only for NON pending handlers, so as NOT to trigger
941959
* protocol initialization when a notifier is registered against a still
@@ -1060,6 +1078,9 @@ __scmi_event_handler_get_ops(struct scmi_notify_instance *ni,
10601078
r_evt = SCMI_GET_REVT(ni, KEY_XTRACT_PROTO_ID(evt_key),
10611079
KEY_XTRACT_EVT_ID(evt_key));
10621080

1081+
if (r_evt && r_evt->not_supported_by_platform)
1082+
return ERR_PTR(-EOPNOTSUPP);
1083+
10631084
mutex_lock(&ni->pending_mtx);
10641085
/* Search registered events at first ... if possible at all */
10651086
if (r_evt) {
@@ -1087,7 +1108,7 @@ __scmi_event_handler_get_ops(struct scmi_notify_instance *ni,
10871108
hndl->key);
10881109
/* this hndl can be only a pending one */
10891110
scmi_put_handler_unlocked(ni, hndl);
1090-
hndl = NULL;
1111+
hndl = ERR_PTR(-EINVAL);
10911112
}
10921113
}
10931114
mutex_unlock(&ni->pending_mtx);
@@ -1370,8 +1391,8 @@ static int scmi_notifier_register(const struct scmi_handle *handle,
13701391
evt_key = MAKE_HASH_KEY(proto_id, evt_id,
13711392
src_id ? *src_id : SRC_ID_MASK);
13721393
hndl = scmi_get_or_create_handler(ni, evt_key);
1373-
if (!hndl)
1374-
return -EINVAL;
1394+
if (IS_ERR(hndl))
1395+
return PTR_ERR(hndl);
13751396

13761397
blocking_notifier_chain_register(&hndl->chain, nb);
13771398

@@ -1416,8 +1437,8 @@ static int scmi_notifier_unregister(const struct scmi_handle *handle,
14161437
evt_key = MAKE_HASH_KEY(proto_id, evt_id,
14171438
src_id ? *src_id : SRC_ID_MASK);
14181439
hndl = scmi_get_handler(ni, evt_key);
1419-
if (!hndl)
1420-
return -EINVAL;
1440+
if (IS_ERR(hndl))
1441+
return PTR_ERR(hndl);
14211442

14221443
/*
14231444
* Note that this chain unregistration call is safe on its own

0 commit comments

Comments
 (0)