.. | .. |
---|
1 | | -// SPDX-License-Identifier: GPL-2.0 |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ |
---|
2 | 2 | /* |
---|
3 | 3 | * System Control and Management Interface (SCMI) Message Protocol |
---|
4 | 4 | * driver common header file containing some definitions, structures |
---|
.. | .. |
---|
6 | 6 | * |
---|
7 | 7 | * Copyright (C) 2018 ARM Ltd. |
---|
8 | 8 | */ |
---|
| 9 | +#ifndef _SCMI_COMMON_H |
---|
| 10 | +#define _SCMI_COMMON_H |
---|
9 | 11 | |
---|
10 | 12 | #include <linux/bitfield.h> |
---|
11 | 13 | #include <linux/completion.h> |
---|
12 | 14 | #include <linux/device.h> |
---|
13 | 15 | #include <linux/errno.h> |
---|
14 | 16 | #include <linux/kernel.h> |
---|
| 17 | +#include <linux/module.h> |
---|
15 | 18 | #include <linux/scmi_protocol.h> |
---|
16 | 19 | #include <linux/types.h> |
---|
17 | 20 | |
---|
18 | 21 | #include <asm/unaligned.h> |
---|
| 22 | + |
---|
| 23 | +#include "notify.h" |
---|
19 | 24 | |
---|
20 | 25 | #define PROTOCOL_REV_MINOR_MASK GENMASK(15, 0) |
---|
21 | 26 | #define PROTOCOL_REV_MAJOR_MASK GENMASK(31, 16) |
---|
.. | .. |
---|
139 | 144 | struct completion *async_done; |
---|
140 | 145 | }; |
---|
141 | 146 | |
---|
142 | | -void scmi_xfer_put(const struct scmi_handle *h, struct scmi_xfer *xfer); |
---|
143 | | -int scmi_do_xfer(const struct scmi_handle *h, struct scmi_xfer *xfer); |
---|
144 | | -int scmi_do_xfer_with_response(const struct scmi_handle *h, |
---|
145 | | - struct scmi_xfer *xfer); |
---|
146 | | -int scmi_xfer_get_init(const struct scmi_handle *h, u8 msg_id, u8 prot_id, |
---|
147 | | - size_t tx_size, size_t rx_size, struct scmi_xfer **p); |
---|
| 147 | +struct scmi_xfer_ops; |
---|
| 148 | + |
---|
| 149 | +/** |
---|
| 150 | + * struct scmi_protocol_handle - Reference to an initialized protocol instance |
---|
| 151 | + * |
---|
| 152 | + * @dev: A reference to the associated SCMI instance device (handle->dev). |
---|
| 153 | + * @xops: A reference to a struct holding refs to the core xfer operations that |
---|
| 154 | + * can be used by the protocol implementation to generate SCMI messages. |
---|
| 155 | + * @set_priv: A method to set protocol private data for this instance. |
---|
| 156 | + * @get_priv: A method to get protocol private data previously set. |
---|
| 157 | + * |
---|
| 158 | + * This structure represents a protocol initialized against specific SCMI |
---|
| 159 | + * instance and it will be used as follows: |
---|
| 160 | + * - as a parameter fed from the core to the protocol initialization code so |
---|
| 161 | + * that it can access the core xfer operations to build and generate SCMI |
---|
| 162 | + * messages exclusively for the specific underlying protocol instance. |
---|
| 163 | + * - as an opaque handle fed by an SCMI driver user when it tries to access |
---|
| 164 | + * this protocol through its own protocol operations. |
---|
| 165 | + * In this case this handle will be returned as an opaque object together |
---|
| 166 | + * with the related protocol operations when the SCMI driver tries to access |
---|
| 167 | + * the protocol. |
---|
| 168 | + */ |
---|
| 169 | +struct scmi_protocol_handle { |
---|
| 170 | + struct device *dev; |
---|
| 171 | + const struct scmi_xfer_ops *xops; |
---|
| 172 | + int (*set_priv)(const struct scmi_protocol_handle *ph, void *priv); |
---|
| 173 | + void *(*get_priv)(const struct scmi_protocol_handle *ph); |
---|
| 174 | +}; |
---|
| 175 | + |
---|
| 176 | +/** |
---|
| 177 | + * struct scmi_xfer_ops - References to the core SCMI xfer operations. |
---|
| 178 | + * @version_get: Get this version protocol. |
---|
| 179 | + * @xfer_get_init: Initialize one struct xfer if any xfer slot is free. |
---|
| 180 | + * @reset_rx_to_maxsz: Reset rx size to max transport size. |
---|
| 181 | + * @do_xfer: Do the SCMI transfer. |
---|
| 182 | + * @do_xfer_with_response: Do the SCMI transfer waiting for a response. |
---|
| 183 | + * @xfer_put: Free the xfer slot. |
---|
| 184 | + * |
---|
| 185 | + * Note that all this operations expect a protocol handle as first parameter; |
---|
| 186 | + * they then internally use it to infer the underlying protocol number: this |
---|
| 187 | + * way is not possible for a protocol implementation to forge messages for |
---|
| 188 | + * another protocol. |
---|
| 189 | + */ |
---|
| 190 | +struct scmi_xfer_ops { |
---|
| 191 | + int (*version_get)(const struct scmi_protocol_handle *ph, u32 *version); |
---|
| 192 | + int (*xfer_get_init)(const struct scmi_protocol_handle *ph, u8 msg_id, |
---|
| 193 | + size_t tx_size, size_t rx_size, |
---|
| 194 | + struct scmi_xfer **p); |
---|
| 195 | + void (*reset_rx_to_maxsz)(const struct scmi_protocol_handle *ph, |
---|
| 196 | + struct scmi_xfer *xfer); |
---|
| 197 | + int (*do_xfer)(const struct scmi_protocol_handle *ph, |
---|
| 198 | + struct scmi_xfer *xfer); |
---|
| 199 | + int (*do_xfer_with_response)(const struct scmi_protocol_handle *ph, |
---|
| 200 | + struct scmi_xfer *xfer); |
---|
| 201 | + void (*xfer_put)(const struct scmi_protocol_handle *ph, |
---|
| 202 | + struct scmi_xfer *xfer); |
---|
| 203 | +}; |
---|
| 204 | + |
---|
| 205 | +struct scmi_revision_info * |
---|
| 206 | +scmi_get_revision_area(const struct scmi_protocol_handle *ph); |
---|
148 | 207 | int scmi_handle_put(const struct scmi_handle *handle); |
---|
149 | 208 | struct scmi_handle *scmi_handle_get(struct device *dev); |
---|
150 | 209 | void scmi_set_handle(struct scmi_device *scmi_dev); |
---|
151 | | -int scmi_version_get(const struct scmi_handle *h, u8 protocol, u32 *version); |
---|
152 | | -void scmi_setup_protocol_implemented(const struct scmi_handle *handle, |
---|
| 210 | +void scmi_setup_protocol_implemented(const struct scmi_protocol_handle *ph, |
---|
153 | 211 | u8 *prot_imp); |
---|
154 | 212 | |
---|
155 | | -int scmi_base_protocol_init(struct scmi_handle *h); |
---|
| 213 | +typedef int (*scmi_prot_init_ph_fn_t)(const struct scmi_protocol_handle *); |
---|
| 214 | + |
---|
| 215 | +/** |
---|
| 216 | + * struct scmi_protocol - Protocol descriptor |
---|
| 217 | + * @id: Protocol ID. |
---|
| 218 | + * @owner: Module reference if any. |
---|
| 219 | + * @init_instance: Mandatory protocol initialization function. |
---|
| 220 | + * @deinit_instance: Optional protocol de-initialization function. |
---|
| 221 | + * @ops: Optional reference to the operations provided by the protocol and |
---|
| 222 | + * exposed in scmi_protocol.h. |
---|
| 223 | + * @events: An optional reference to the events supported by this protocol. |
---|
| 224 | + */ |
---|
| 225 | +struct scmi_protocol { |
---|
| 226 | + const u8 id; |
---|
| 227 | + struct module *owner; |
---|
| 228 | + const scmi_prot_init_ph_fn_t init_instance; |
---|
| 229 | + const scmi_prot_init_ph_fn_t deinit_instance; |
---|
| 230 | + const void *ops; |
---|
| 231 | + const struct scmi_protocol_events *events; |
---|
| 232 | +}; |
---|
156 | 233 | |
---|
157 | 234 | int __init scmi_bus_init(void); |
---|
158 | 235 | void __exit scmi_bus_exit(void); |
---|
.. | .. |
---|
160 | 237 | #define DECLARE_SCMI_REGISTER_UNREGISTER(func) \ |
---|
161 | 238 | int __init scmi_##func##_register(void); \ |
---|
162 | 239 | void __exit scmi_##func##_unregister(void) |
---|
| 240 | +DECLARE_SCMI_REGISTER_UNREGISTER(base); |
---|
163 | 241 | DECLARE_SCMI_REGISTER_UNREGISTER(clock); |
---|
164 | 242 | DECLARE_SCMI_REGISTER_UNREGISTER(perf); |
---|
165 | 243 | DECLARE_SCMI_REGISTER_UNREGISTER(power); |
---|
166 | 244 | DECLARE_SCMI_REGISTER_UNREGISTER(reset); |
---|
167 | 245 | DECLARE_SCMI_REGISTER_UNREGISTER(sensors); |
---|
| 246 | +DECLARE_SCMI_REGISTER_UNREGISTER(voltage); |
---|
168 | 247 | DECLARE_SCMI_REGISTER_UNREGISTER(system); |
---|
169 | 248 | |
---|
170 | | -#define DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(id, name) \ |
---|
| 249 | +#define DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(name, proto) \ |
---|
171 | 250 | int __init scmi_##name##_register(void) \ |
---|
172 | 251 | { \ |
---|
173 | | - return scmi_protocol_register((id), &scmi_##name##_protocol_init); \ |
---|
| 252 | + return scmi_protocol_register(&(proto)); \ |
---|
174 | 253 | } \ |
---|
175 | 254 | \ |
---|
176 | 255 | void __exit scmi_##name##_unregister(void) \ |
---|
177 | 256 | { \ |
---|
178 | | - scmi_protocol_unregister((id)); \ |
---|
| 257 | + scmi_protocol_unregister(&(proto)); \ |
---|
179 | 258 | } |
---|
| 259 | + |
---|
| 260 | +const struct scmi_protocol *scmi_get_protocol(int protocol_id); |
---|
| 261 | +void scmi_put_protocol(int protocol_id); |
---|
| 262 | + |
---|
| 263 | +int scmi_acquire_protocol(const struct scmi_handle *handle, u8 protocol_id); |
---|
| 264 | +void scmi_release_protocol(const struct scmi_handle *handle, u8 protocol_id); |
---|
180 | 265 | |
---|
181 | 266 | /* SCMI Transport */ |
---|
182 | 267 | /** |
---|
.. | .. |
---|
202 | 287 | * @send_message: Callback to send a message |
---|
203 | 288 | * @mark_txdone: Callback to mark tx as done |
---|
204 | 289 | * @fetch_response: Callback to fetch response |
---|
| 290 | + * @fetch_notification: Callback to fetch notification |
---|
| 291 | + * @clear_channel: Callback to clear a channel |
---|
205 | 292 | * @poll_done: Callback to poll transfer status |
---|
206 | 293 | */ |
---|
207 | 294 | struct scmi_transport_ops { |
---|
.. | .. |
---|
214 | 301 | void (*mark_txdone)(struct scmi_chan_info *cinfo, int ret); |
---|
215 | 302 | void (*fetch_response)(struct scmi_chan_info *cinfo, |
---|
216 | 303 | struct scmi_xfer *xfer); |
---|
| 304 | + void (*fetch_notification)(struct scmi_chan_info *cinfo, |
---|
| 305 | + size_t max_len, struct scmi_xfer *xfer); |
---|
| 306 | + void (*clear_channel)(struct scmi_chan_info *cinfo); |
---|
217 | 307 | bool (*poll_done)(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer); |
---|
218 | 308 | }; |
---|
| 309 | + |
---|
| 310 | +int scmi_request_protocol_device(const struct scmi_device_id *id_table); |
---|
| 311 | +void scmi_unrequest_protocol_device(const struct scmi_device_id *id_table); |
---|
| 312 | +struct scmi_device *scmi_find_child_dev(struct device *parent, |
---|
| 313 | + int prot_id, const char *name); |
---|
219 | 314 | |
---|
220 | 315 | /** |
---|
221 | 316 | * struct scmi_desc - Description of SoC integration |
---|
.. | .. |
---|
227 | 322 | * @max_msg_size: Maximum size of data per message that can be handled. |
---|
228 | 323 | */ |
---|
229 | 324 | struct scmi_desc { |
---|
230 | | - struct scmi_transport_ops *ops; |
---|
| 325 | + const struct scmi_transport_ops *ops; |
---|
231 | 326 | int max_rx_timeout_ms; |
---|
232 | 327 | int max_msg; |
---|
233 | 328 | int max_msg_size; |
---|
234 | 329 | }; |
---|
235 | 330 | |
---|
236 | 331 | extern const struct scmi_desc scmi_mailbox_desc; |
---|
237 | | -#ifdef CONFIG_HAVE_ARM_SMCCC |
---|
| 332 | +#ifdef CONFIG_HAVE_ARM_SMCCC_DISCOVERY |
---|
238 | 333 | extern const struct scmi_desc scmi_smc_desc; |
---|
239 | 334 | #endif |
---|
240 | 335 | |
---|
.. | .. |
---|
249 | 344 | u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem); |
---|
250 | 345 | void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem, |
---|
251 | 346 | struct scmi_xfer *xfer); |
---|
| 347 | +void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem, |
---|
| 348 | + size_t max_len, struct scmi_xfer *xfer); |
---|
| 349 | +void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem); |
---|
252 | 350 | bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem, |
---|
253 | 351 | struct scmi_xfer *xfer); |
---|
| 352 | + |
---|
| 353 | +void scmi_set_notification_instance_data(const struct scmi_handle *handle, |
---|
| 354 | + void *priv); |
---|
| 355 | +void *scmi_get_notification_instance_data(const struct scmi_handle *handle); |
---|
| 356 | + |
---|
| 357 | +#endif /* _SCMI_COMMON_H */ |
---|