Commit a02d7c93 authored by Cristian Marussi's avatar Cristian Marussi Committed by Sudeep Holla

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.comTested-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarCristian Marussi <cristian.marussi@arm.com>
Signed-off-by: default avatarSudeep Holla <sudeep.holla@arm.com>
parent 3cb8c95f
...@@ -343,4 +343,8 @@ void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem); ...@@ -343,4 +343,8 @@ void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem);
bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem, bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem,
struct scmi_xfer *xfer); 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 */ #endif /* _SCMI_COMMON_H */
...@@ -113,6 +113,7 @@ struct scmi_protocol_instance { ...@@ -113,6 +113,7 @@ struct scmi_protocol_instance {
* @protocols_mtx: A mutex to protect protocols instances initialization. * @protocols_mtx: A mutex to protect protocols instances initialization.
* @protocols_imp: List of protocols implemented, currently maximum of * @protocols_imp: List of protocols implemented, currently maximum of
* MAX_PROTOCOLS_IMP elements allocated by the base protocol * MAX_PROTOCOLS_IMP elements allocated by the base protocol
* @notify_priv: Pointer to private data structure specific to notifications.
* @node: List head * @node: List head
* @users: Number of users of this instance * @users: Number of users of this instance
*/ */
...@@ -129,6 +130,7 @@ struct scmi_info { ...@@ -129,6 +130,7 @@ struct scmi_info {
/* Ensure mutual exclusive access to protocols instance array */ /* Ensure mutual exclusive access to protocols instance array */
struct mutex protocols_mtx; struct mutex protocols_mtx;
u8 *protocols_imp; u8 *protocols_imp;
void *notify_priv;
struct list_head node; struct list_head node;
int users; int users;
}; };
...@@ -170,6 +172,25 @@ static inline void scmi_dump_header_dbg(struct device *dev, ...@@ -170,6 +172,25 @@ static inline void scmi_dump_header_dbg(struct device *dev,
hdr->id, hdr->seq, hdr->protocol_id); 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 * scmi_xfer_get() - Allocate one message
* *
......
...@@ -582,11 +582,9 @@ int scmi_notify(const struct scmi_handle *handle, u8 proto_id, u8 evt_id, ...@@ -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_event_header eh;
struct scmi_notify_instance *ni; struct scmi_notify_instance *ni;
/* Ensure notify_priv is updated */ ni = scmi_notification_instance_data_get(handle);
smp_rmb(); if (!ni)
if (!handle->notify_priv)
return 0; return 0;
ni = handle->notify_priv;
r_evt = SCMI_GET_REVT(ni, proto_id, evt_id); r_evt = SCMI_GET_REVT(ni, proto_id, evt_id);
if (!r_evt) if (!r_evt)
...@@ -762,11 +760,9 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id, ...@@ -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)) (!ee->num_sources && !ee->ops->get_num_sources))
return -EINVAL; return -EINVAL;
/* Ensure notify_priv is updated */ ni = scmi_notification_instance_data_get(handle);
smp_rmb(); if (!ni)
if (!handle->notify_priv)
return -ENOMEM; return -ENOMEM;
ni = handle->notify_priv;
/* num_sources cannot be <= 0 */ /* num_sources cannot be <= 0 */
if (ee->num_sources) { if (ee->num_sources) {
...@@ -846,12 +842,10 @@ void scmi_deregister_protocol_events(const struct scmi_handle *handle, ...@@ -846,12 +842,10 @@ void scmi_deregister_protocol_events(const struct scmi_handle *handle,
struct scmi_notify_instance *ni; struct scmi_notify_instance *ni;
struct scmi_registered_events_desc *pd; struct scmi_registered_events_desc *pd;
/* Ensure notify_priv is updated */ ni = scmi_notification_instance_data_get(handle);
smp_rmb(); if (!ni)
if (!handle->notify_priv)
return; return;
ni = handle->notify_priv;
pd = ni->registered_protocols[proto_id]; pd = ni->registered_protocols[proto_id];
if (!pd) if (!pd)
return; return;
...@@ -1354,11 +1348,9 @@ static int scmi_register_notifier(const struct scmi_handle *handle, ...@@ -1354,11 +1348,9 @@ static int scmi_register_notifier(const struct scmi_handle *handle,
struct scmi_event_handler *hndl; struct scmi_event_handler *hndl;
struct scmi_notify_instance *ni; struct scmi_notify_instance *ni;
/* Ensure notify_priv is updated */ ni = scmi_notification_instance_data_get(handle);
smp_rmb(); if (!ni)
if (!handle->notify_priv)
return -ENODEV; return -ENODEV;
ni = handle->notify_priv;
evt_key = MAKE_HASH_KEY(proto_id, evt_id, evt_key = MAKE_HASH_KEY(proto_id, evt_id,
src_id ? *src_id : SRC_ID_MASK); src_id ? *src_id : SRC_ID_MASK);
...@@ -1402,11 +1394,9 @@ static int scmi_unregister_notifier(const struct scmi_handle *handle, ...@@ -1402,11 +1394,9 @@ static int scmi_unregister_notifier(const struct scmi_handle *handle,
struct scmi_event_handler *hndl; struct scmi_event_handler *hndl;
struct scmi_notify_instance *ni; struct scmi_notify_instance *ni;
/* Ensure notify_priv is updated */ ni = scmi_notification_instance_data_get(handle);
smp_rmb(); if (!ni)
if (!handle->notify_priv)
return -ENODEV; return -ENODEV;
ni = handle->notify_priv;
evt_key = MAKE_HASH_KEY(proto_id, evt_id, evt_key = MAKE_HASH_KEY(proto_id, evt_id,
src_id ? *src_id : SRC_ID_MASK); src_id ? *src_id : SRC_ID_MASK);
...@@ -1681,8 +1671,8 @@ int scmi_notification_init(struct scmi_handle *handle) ...@@ -1681,8 +1671,8 @@ int scmi_notification_init(struct scmi_handle *handle)
INIT_WORK(&ni->init_work, scmi_protocols_late_init); INIT_WORK(&ni->init_work, scmi_protocols_late_init);
scmi_notification_instance_data_set(handle, ni);
handle->notify_ops = &notify_ops; handle->notify_ops = &notify_ops;
handle->notify_priv = ni;
/* Ensure handle is up to date */ /* Ensure handle is up to date */
smp_wmb(); smp_wmb();
...@@ -1694,7 +1684,7 @@ int scmi_notification_init(struct scmi_handle *handle) ...@@ -1694,7 +1684,7 @@ int scmi_notification_init(struct scmi_handle *handle)
err: err:
dev_warn(handle->dev, "Initialization Failed.\n"); dev_warn(handle->dev, "Initialization Failed.\n");
devres_release_group(handle->dev, NULL); devres_release_group(handle->dev, gid);
return -ENOMEM; return -ENOMEM;
} }
...@@ -1706,15 +1696,10 @@ void scmi_notification_exit(struct scmi_handle *handle) ...@@ -1706,15 +1696,10 @@ void scmi_notification_exit(struct scmi_handle *handle)
{ {
struct scmi_notify_instance *ni; struct scmi_notify_instance *ni;
/* Ensure notify_priv is updated */ ni = scmi_notification_instance_data_get(handle);
smp_rmb(); if (!ni)
if (!handle->notify_priv)
return; return;
ni = handle->notify_priv; scmi_notification_instance_data_set(handle, NULL);
handle->notify_priv = NULL;
/* Ensure handle is up to date */
smp_wmb();
/* Destroy while letting pending work complete */ /* Destroy while letting pending work complete */
destroy_workqueue(ni->notify_wq); destroy_workqueue(ni->notify_wq);
......
...@@ -609,8 +609,6 @@ struct scmi_notify_ops { ...@@ -609,8 +609,6 @@ struct scmi_notify_ops {
* operations and a dedicated protocol handler * operations and a dedicated protocol handler
* @devm_protocol_put: devres managed method to release a protocol * @devm_protocol_put: devres managed method to release a protocol
* @notify_ops: pointer to set of notifications related operations * @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 scmi_handle {
struct device *dev; struct device *dev;
...@@ -622,7 +620,6 @@ struct scmi_handle { ...@@ -622,7 +620,6 @@ struct scmi_handle {
void (*devm_protocol_put)(struct scmi_device *sdev, u8 proto); void (*devm_protocol_put)(struct scmi_device *sdev, u8 proto);
const struct scmi_notify_ops *notify_ops; const struct scmi_notify_ops *notify_ops;
void *notify_priv;
}; };
enum scmi_std_protocol { enum scmi_std_protocol {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment