firmware: arm_scmi: Make notify_priv really private

Notification private data is currently accessible via handle->notify_priv,
this data was indeed meant to be private to the notification core support
and not to be accessible by SCMI drivers. Make it private hiding it
inside instance descriptor struct scmi_info and accessible only via
dedicated helpers.

Link: https://lore.kernel.org/r/20210316124903.35011-36-cristian.marussi@arm.com
Tested-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
This commit is contained in:
Cristian Marussi 2021-03-16 12:49:00 +00:00 committed by Sudeep Holla
parent 3cb8c95f4b
commit a02d7c93c1
4 changed files with 40 additions and 33 deletions

View File

@ -343,4 +343,8 @@ void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem);
bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem,
struct scmi_xfer *xfer);
void scmi_notification_instance_data_set(const struct scmi_handle *handle,
void *priv);
void *scmi_notification_instance_data_get(const struct scmi_handle *handle);
#endif /* _SCMI_COMMON_H */

View File

@ -113,6 +113,7 @@ struct scmi_protocol_instance {
* @protocols_mtx: A mutex to protect protocols instances initialization.
* @protocols_imp: List of protocols implemented, currently maximum of
* MAX_PROTOCOLS_IMP elements allocated by the base protocol
* @notify_priv: Pointer to private data structure specific to notifications.
* @node: List head
* @users: Number of users of this instance
*/
@ -129,6 +130,7 @@ struct scmi_info {
/* Ensure mutual exclusive access to protocols instance array */
struct mutex protocols_mtx;
u8 *protocols_imp;
void *notify_priv;
struct list_head node;
int users;
};
@ -170,6 +172,25 @@ static inline void scmi_dump_header_dbg(struct device *dev,
hdr->id, hdr->seq, hdr->protocol_id);
}
void scmi_notification_instance_data_set(const struct scmi_handle *handle,
void *priv)
{
struct scmi_info *info = handle_to_scmi_info(handle);
info->notify_priv = priv;
/* Ensure updated protocol private date are visible */
smp_wmb();
}
void *scmi_notification_instance_data_get(const struct scmi_handle *handle)
{
struct scmi_info *info = handle_to_scmi_info(handle);
/* Ensure protocols_private_data has been updated */
smp_rmb();
return info->notify_priv;
}
/**
* scmi_xfer_get() - Allocate one message
*

View File

@ -582,11 +582,9 @@ int scmi_notify(const struct scmi_handle *handle, u8 proto_id, u8 evt_id,
struct scmi_event_header eh;
struct scmi_notify_instance *ni;
/* Ensure notify_priv is updated */
smp_rmb();
if (!handle->notify_priv)
ni = scmi_notification_instance_data_get(handle);
if (!ni)
return 0;
ni = handle->notify_priv;
r_evt = SCMI_GET_REVT(ni, proto_id, evt_id);
if (!r_evt)
@ -762,11 +760,9 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id,
(!ee->num_sources && !ee->ops->get_num_sources))
return -EINVAL;
/* Ensure notify_priv is updated */
smp_rmb();
if (!handle->notify_priv)
ni = scmi_notification_instance_data_get(handle);
if (!ni)
return -ENOMEM;
ni = handle->notify_priv;
/* num_sources cannot be <= 0 */
if (ee->num_sources) {
@ -846,12 +842,10 @@ void scmi_deregister_protocol_events(const struct scmi_handle *handle,
struct scmi_notify_instance *ni;
struct scmi_registered_events_desc *pd;
/* Ensure notify_priv is updated */
smp_rmb();
if (!handle->notify_priv)
ni = scmi_notification_instance_data_get(handle);
if (!ni)
return;
ni = handle->notify_priv;
pd = ni->registered_protocols[proto_id];
if (!pd)
return;
@ -1354,11 +1348,9 @@ static int scmi_register_notifier(const struct scmi_handle *handle,
struct scmi_event_handler *hndl;
struct scmi_notify_instance *ni;
/* Ensure notify_priv is updated */
smp_rmb();
if (!handle->notify_priv)
ni = scmi_notification_instance_data_get(handle);
if (!ni)
return -ENODEV;
ni = handle->notify_priv;
evt_key = MAKE_HASH_KEY(proto_id, evt_id,
src_id ? *src_id : SRC_ID_MASK);
@ -1402,11 +1394,9 @@ static int scmi_unregister_notifier(const struct scmi_handle *handle,
struct scmi_event_handler *hndl;
struct scmi_notify_instance *ni;
/* Ensure notify_priv is updated */
smp_rmb();
if (!handle->notify_priv)
ni = scmi_notification_instance_data_get(handle);
if (!ni)
return -ENODEV;
ni = handle->notify_priv;
evt_key = MAKE_HASH_KEY(proto_id, evt_id,
src_id ? *src_id : SRC_ID_MASK);
@ -1681,8 +1671,8 @@ int scmi_notification_init(struct scmi_handle *handle)
INIT_WORK(&ni->init_work, scmi_protocols_late_init);
scmi_notification_instance_data_set(handle, ni);
handle->notify_ops = &notify_ops;
handle->notify_priv = ni;
/* Ensure handle is up to date */
smp_wmb();
@ -1694,7 +1684,7 @@ int scmi_notification_init(struct scmi_handle *handle)
err:
dev_warn(handle->dev, "Initialization Failed.\n");
devres_release_group(handle->dev, NULL);
devres_release_group(handle->dev, gid);
return -ENOMEM;
}
@ -1706,15 +1696,10 @@ void scmi_notification_exit(struct scmi_handle *handle)
{
struct scmi_notify_instance *ni;
/* Ensure notify_priv is updated */
smp_rmb();
if (!handle->notify_priv)
ni = scmi_notification_instance_data_get(handle);
if (!ni)
return;
ni = handle->notify_priv;
handle->notify_priv = NULL;
/* Ensure handle is up to date */
smp_wmb();
scmi_notification_instance_data_set(handle, NULL);
/* Destroy while letting pending work complete */
destroy_workqueue(ni->notify_wq);

View File

@ -609,8 +609,6 @@ struct scmi_notify_ops {
* operations and a dedicated protocol handler
* @devm_protocol_put: devres managed method to release a protocol
* @notify_ops: pointer to set of notifications related operations
* @notify_priv: pointer to private data structure specific to notifications
* (for internal use only)
*/
struct scmi_handle {
struct device *dev;
@ -622,7 +620,6 @@ struct scmi_handle {
void (*devm_protocol_put)(struct scmi_device *sdev, u8 proto);
const struct scmi_notify_ops *notify_ops;
void *notify_priv;
};
enum scmi_std_protocol {