mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-07-06 05:45:29 +02:00
firmware: arm_scmi: Check for notification support
When registering protocol events, use the optional .is_notify_supported callback provided by the protocol to check if that specific notification type is available for that particular resource on the running system, marking it as unsupported otherwise. Then, when a notification enable request is received, return an error if it was previously marked as unsuppported, so avoiding to send a needless notification enable command and check the returned value for failure. Signed-off-by: Cristian Marussi <cristian.marussi@arm.com> Link: https://lore.kernel.org/r/20240212123233.1230090-2-cristian.marussi@arm.com Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
This commit is contained in:
parent
961745b2c4
commit
8733e86a80
|
@ -99,6 +99,7 @@
|
||||||
#define PROTO_ID_MASK GENMASK(31, 24)
|
#define PROTO_ID_MASK GENMASK(31, 24)
|
||||||
#define EVT_ID_MASK GENMASK(23, 16)
|
#define EVT_ID_MASK GENMASK(23, 16)
|
||||||
#define SRC_ID_MASK GENMASK(15, 0)
|
#define SRC_ID_MASK GENMASK(15, 0)
|
||||||
|
#define NOTIF_UNSUPP -1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Builds an unsigned 32bit key from the given input tuple to be used
|
* Builds an unsigned 32bit key from the given input tuple to be used
|
||||||
|
@ -788,6 +789,7 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id,
|
||||||
|
|
||||||
pd->ph = ph;
|
pd->ph = ph;
|
||||||
for (i = 0; i < ee->num_events; i++, evt++) {
|
for (i = 0; i < ee->num_events; i++, evt++) {
|
||||||
|
int id;
|
||||||
struct scmi_registered_event *r_evt;
|
struct scmi_registered_event *r_evt;
|
||||||
|
|
||||||
r_evt = devm_kzalloc(ni->handle->dev, sizeof(*r_evt),
|
r_evt = devm_kzalloc(ni->handle->dev, sizeof(*r_evt),
|
||||||
|
@ -809,6 +811,11 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id,
|
||||||
if (!r_evt->report)
|
if (!r_evt->report)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
for (id = 0; id < r_evt->num_sources; id++)
|
||||||
|
if (ee->ops->is_notify_supported &&
|
||||||
|
!ee->ops->is_notify_supported(ph, r_evt->evt->id, id))
|
||||||
|
refcount_set(&r_evt->sources[id], NOTIF_UNSUPP);
|
||||||
|
|
||||||
pd->registered_events[i] = r_evt;
|
pd->registered_events[i] = r_evt;
|
||||||
/* Ensure events are updated */
|
/* Ensure events are updated */
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
|
@ -1166,7 +1173,13 @@ static inline int __scmi_enable_evt(struct scmi_registered_event *r_evt,
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
sid = &r_evt->sources[src_id];
|
sid = &r_evt->sources[src_id];
|
||||||
if (refcount_read(sid) == 0) {
|
if (refcount_read(sid) == NOTIF_UNSUPP) {
|
||||||
|
dev_dbg(r_evt->proto->ph->dev,
|
||||||
|
"Notification NOT supported - proto_id:%d evt_id:%d src_id:%d",
|
||||||
|
r_evt->proto->id, r_evt->evt->id,
|
||||||
|
src_id);
|
||||||
|
ret = -EOPNOTSUPP;
|
||||||
|
} else if (refcount_read(sid) == 0) {
|
||||||
ret = REVT_NOTIFY_ENABLE(r_evt, r_evt->evt->id,
|
ret = REVT_NOTIFY_ENABLE(r_evt, r_evt->evt->id,
|
||||||
src_id);
|
src_id);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
@ -1179,6 +1192,8 @@ static inline int __scmi_enable_evt(struct scmi_registered_event *r_evt,
|
||||||
} else {
|
} else {
|
||||||
for (; num_sources; src_id++, num_sources--) {
|
for (; num_sources; src_id++, num_sources--) {
|
||||||
sid = &r_evt->sources[src_id];
|
sid = &r_evt->sources[src_id];
|
||||||
|
if (refcount_read(sid) == NOTIF_UNSUPP)
|
||||||
|
continue;
|
||||||
if (refcount_dec_and_test(sid))
|
if (refcount_dec_and_test(sid))
|
||||||
REVT_NOTIFY_DISABLE(r_evt,
|
REVT_NOTIFY_DISABLE(r_evt,
|
||||||
r_evt->evt->id, src_id);
|
r_evt->evt->id, src_id);
|
||||||
|
|
|
@ -35,6 +35,8 @@ struct scmi_protocol_handle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct scmi_event_ops - Protocol helpers called by the notification core.
|
* struct scmi_event_ops - Protocol helpers called by the notification core.
|
||||||
|
* @is_notify_supported: Return 0 if the specified notification for the
|
||||||
|
* specified resource (src_id) is supported.
|
||||||
* @get_num_sources: Returns the number of possible events' sources for this
|
* @get_num_sources: Returns the number of possible events' sources for this
|
||||||
* protocol
|
* protocol
|
||||||
* @set_notify_enabled: Enable/disable the required evt_id/src_id notifications
|
* @set_notify_enabled: Enable/disable the required evt_id/src_id notifications
|
||||||
|
@ -50,6 +52,8 @@ struct scmi_protocol_handle;
|
||||||
* process context.
|
* process context.
|
||||||
*/
|
*/
|
||||||
struct scmi_event_ops {
|
struct scmi_event_ops {
|
||||||
|
bool (*is_notify_supported)(const struct scmi_protocol_handle *ph,
|
||||||
|
u8 evt_id, u32 src_id);
|
||||||
int (*get_num_sources)(const struct scmi_protocol_handle *ph);
|
int (*get_num_sources)(const struct scmi_protocol_handle *ph);
|
||||||
int (*set_notify_enabled)(const struct scmi_protocol_handle *ph,
|
int (*set_notify_enabled)(const struct scmi_protocol_handle *ph,
|
||||||
u8 evt_id, u32 src_id, bool enabled);
|
u8 evt_id, u32 src_id, bool enabled);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user