| @@ -19,12 +19,10 @@ · 18 unmodified lines |
| 19 | 19 | #include <linux/io.h> |
| 20 | 20 | #include <linux/kernel.h> |
| 21 | 21 | #include <linux/ktime.h> |
| 22 | | −#include <linux/mailbox_client.h> |
| 23 | 22 | #include <linux/module.h> |
| 24 | 23 | #include <linux/of_address.h> |
| 25 | 24 | #include <linux/of_device.h> |
| 26 | 25 | #include <linux/processor.h> |
| 27 | | −#include <linux/semaphore.h> |
| 28 | 26 | #include <linux/slab.h> |
| 29 | 27 | |
| 30 | 28 | #include "common.h" |
| @@ -32,19 +30,6 @@ · 1 unmodified line |
| 32 | 30 | #define CREATE_TRACE_POINTS |
| 33 | 31 | #include <trace/events/scmi.h> |
| 34 | 32 | |
| 35 | | −#define MSG_ID_MASK GENMASK(7, 0) |
| 36 | | −#define MSG_XTRACT_ID(hdr) FIELD_GET(MSG_ID_MASK, (hdr)) |
| 37 | | −#define MSG_TYPE_MASK GENMASK(9, 8) |
| 38 | | −#define MSG_XTRACT_TYPE(hdr) FIELD_GET(MSG_TYPE_MASK, (hdr)) |
| 39 | | −#define MSG_TYPE_COMMAND 0 |
| 40 | | −#define MSG_TYPE_DELAYED_RESP 2 |
| 41 | | −#define MSG_TYPE_NOTIFICATION 3 |
| 42 | | −#define MSG_PROTOCOL_ID_MASK GENMASK(17, 10) |
| 43 | | −#define MSG_XTRACT_PROT_ID(hdr) FIELD_GET(MSG_PROTOCOL_ID_MASK, (hdr)) |
| 44 | | −#define MSG_TOKEN_ID_MASK GENMASK(27, 18) |
| 45 | | −#define MSG_XTRACT_TOKEN(hdr) FIELD_GET(MSG_TOKEN_ID_MASK, (hdr)) |
| 46 | | −#define MSG_TOKEN_MAX (MSG_XTRACT_TOKEN(MSG_TOKEN_ID_MASK) + 1) |
| 47 | | − |
| 48 | 33 | enum scmi_error_codes { |
| 49 | 34 | SCMI_SUCCESS = 0, /* Success */ |
| 50 | 35 | SCMI_ERR_SUPPORT = -1, /* Not supported */ |
| @@ -82,46 +67,14 @@ struct scmi_xfers_info { · 31 unmodified lines |
| 82 | 67 | spinlock_t xfer_lock; |
| 83 | 68 | }; |
| 84 | 69 | |
| 85 | | −/** |
| 86 | | − * struct scmi_desc - Description of SoC integration |
| 87 | | − * |
| 88 | | − * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds) |
| 89 | | − * @max_msg: Maximum number of messages that can be pending |
| 90 | | − * simultaneously in the system |
| 91 | | − * @max_msg_size: Maximum size of data per message that can be handled. |
| 92 | | − */ |
| 93 | | −struct scmi_desc { |
| 94 | | − int max_rx_timeout_ms; |
| 95 | | − int max_msg; |
| 96 | | − int max_msg_size; |
| 97 | | −}; |
| 98 | | − |
| 99 | | −/** |
| 100 | | − * struct scmi_chan_info - Structure representing a SCMI channel information |
| 101 | | − * |
| 102 | | − * @cl: Mailbox Client |
| 103 | | − * @chan: Transmit/Receive mailbox channel |
| 104 | | − * @payload: Transmit/Receive mailbox channel payload area |
| 105 | | − * @dev: Reference to device in the SCMI hierarchy corresponding to this |
| 106 | | − * channel |
| 107 | | − * @handle: Pointer to SCMI entity handle |
| 108 | | − */ |
| 109 | | −struct scmi_chan_info { |
| 110 | | − struct mbox_client cl; |
| 111 | | − struct mbox_chan *chan; |
| 112 | | − void __iomem *payload; |
| 113 | | − struct device *dev; |
| 114 | | − struct scmi_handle *handle; |
| 115 | | −}; |
| 116 | | − |
| 117 | 70 | /** |
| 118 | 71 | * struct scmi_info - Structure representing a SCMI instance |
| 119 | 72 | * |
| 120 | 73 | * @dev: Device pointer |
| 121 | 74 | * @desc: SoC description for this instance |
| 122 | | − * @handle: Instance of SCMI handle to send to clients |
| 123 | 75 | * @version: SCMI revision information containing protocol version, |
| 124 | 76 | * implementation version and (sub-)vendor identification. |
| 77 | + * @handle: Instance of SCMI handle to send to clients |
| 125 | 78 | * @tx_minfo: Universal Transmit Message management info |
| 126 | 79 | * @tx_idr: IDR object to map protocol id to Tx channel info pointer |
| 127 | 80 | * @rx_idr: IDR object to map protocol id to Rx channel info pointer |
| @@ -143,27 +96,8 @@ struct scmi_info { · 15 unmodified lines |
| 143 | 96 | int users; |
| 144 | 97 | }; |
| 145 | 98 | |
| 146 | | −#define client_to_scmi_chan_info(c) container_of(c, struct scmi_chan_info, cl) |
| 147 | 99 | #define handle_to_scmi_info(h) container_of(h, struct scmi_info, handle) |
| 148 | 100 | |
| 149 | | −/* |
| 150 | | − * SCMI specification requires all parameters, message headers, return |
| 151 | | − * arguments or any protocol data to be expressed in little endian |
| 152 | | − * format only. |
| 153 | | − */ |
| 154 | | −struct scmi_shared_mem { |
| 155 | | − __le32 reserved; |
| 156 | | − __le32 channel_status; |
| 157 | | −#define SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR BIT(1) |
| 158 | | −#define SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE BIT(0) |
| 159 | | − __le32 reserved1[2]; |
| 160 | | − __le32 flags; |
| 161 | | −#define SCMI_SHMEM_FLAG_INTR_ENABLED BIT(0) |
| 162 | | − __le32 length; |
| 163 | | − __le32 msg_header; |
| 164 | | − u8 msg_payload[0]; |
| 165 | | −}; |
| 166 | | − |
| 167 | 101 | static const int scmi_linux_errmap[] = { |
| 168 | 102 | /* better than switch case as long as return value is continuous */ |
| 169 | 103 | 0, /* SCMI_SUCCESS */ |
| @@ -199,77 +133,6 @@ static inline void scmi_dump_header_dbg(struct device *dev, · 29 unmodified lines |
| 199 | 133 | hdr->id, hdr->seq, hdr->protocol_id); |
| 200 | 134 | } |
| 201 | 135 | |
| 202 | | −static void scmi_fetch_response(struct scmi_xfer *xfer, |
| 203 | | − struct scmi_shared_mem __iomem *mem) |
| 204 | | −{ |
| 205 | | − xfer->hdr.status = ioread32(mem->msg_payload); |
| 206 | | − /* Skip the length of header and status in payload area i.e 8 bytes */ |
| 207 | | − xfer->rx.len = min_t(size_t, xfer->rx.len, ioread32(&mem->length) - 8); |
| 208 | | − |
| 209 | | − /* Take a copy to the rx buffer.. */ |
| 210 | | − memcpy_fromio(xfer->rx.buf, mem->msg_payload + 4, xfer->rx.len); |
| 211 | | −} |
| 212 | | − |
| 213 | | −/** |
| 214 | | − * pack_scmi_header() - packs and returns 32-bit header |
| 215 | | − * |
| 216 | | − * @hdr: pointer to header containing all the information on message id, |
| 217 | | − * protocol id and sequence id. |
| 218 | | − * |
| 219 | | − * Return: 32-bit packed message header to be sent to the platform. |
| 220 | | − */ |
| 221 | | −static inline u32 pack_scmi_header(struct scmi_msg_hdr *hdr) |
| 222 | | −{ |
| 223 | | − return FIELD_PREP(MSG_ID_MASK, hdr->id) | |
| 224 | | − FIELD_PREP(MSG_TOKEN_ID_MASK, hdr->seq) | |
| 225 | | − FIELD_PREP(MSG_PROTOCOL_ID_MASK, hdr->protocol_id); |
| 226 | | −} |
| 227 | | − |
| 228 | | −/** |
| 229 | | − * unpack_scmi_header() - unpacks and records message and protocol id |
| 230 | | − * |
| 231 | | − * @msg_hdr: 32-bit packed message header sent from the platform |
| 232 | | − * @hdr: pointer to header to fetch message and protocol id. |
| 233 | | − */ |
| 234 | | −static inline void unpack_scmi_header(u32 msg_hdr, struct scmi_msg_hdr *hdr) |
| 235 | | −{ |
| 236 | | − hdr->id = MSG_XTRACT_ID(msg_hdr); |
| 237 | | − hdr->protocol_id = MSG_XTRACT_PROT_ID(msg_hdr); |
| 238 | | −} |
| 239 | | − |
| 240 | | −/** |
| 241 | | − * scmi_tx_prepare() - mailbox client callback to prepare for the transfer |
| 242 | | − * |
| 243 | | − * @cl: client pointer |
| 244 | | − * @m: mailbox message |
| 245 | | − * |
| 246 | | − * This function prepares the shared memory which contains the header and the |
| 247 | | − * payload. |
| 248 | | − */ |
| 249 | | −static void scmi_tx_prepare(struct mbox_client *cl, void *m) |
| 250 | | −{ |
| 251 | | − struct scmi_xfer *t = m; |
| 252 | | − struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl); |
| 253 | | − struct scmi_shared_mem __iomem *mem = cinfo->payload; |
| 254 | | − |
| 255 | | − /* |
| 256 | | − * Ideally channel must be free by now unless OS timeout last |
| 257 | | − * request and platform continued to process the same, wait |
| 258 | | − * until it releases the shared memory, otherwise we may endup |
| 259 | | − * overwriting its response with new message payload or vice-versa |
| 260 | | − */ |
| 261 | | − spin_until_cond(ioread32(&mem->channel_status) & |
| 262 | | − SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE); |
| 263 | | − /* Mark channel busy + clear error */ |
| 264 | | − iowrite32(0x0, &mem->channel_status); |
| 265 | | − iowrite32(t->hdr.poll_completion ? 0 : SCMI_SHMEM_FLAG_INTR_ENABLED, |
| 266 | | − &mem->flags); |
| 267 | | − iowrite32(sizeof(mem->msg_header) + t->tx.len, &mem->length); |
| 268 | | − iowrite32(pack_scmi_header(&t->hdr), &mem->msg_header); |
| 269 | | − if (t->tx.buf) |
| 270 | | − memcpy_toio(mem->msg_payload, t->tx.buf, t->tx.len); |
| 271 | | −} |
| 272 | | − |
| 273 | 136 | /** |
| 274 | 137 | * scmi_xfer_get() - Allocate one message |
| 275 | 138 | * |
| @@ -338,10 +201,10 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer) · 62 unmodified lines |
| 338 | 201 | } |
| 339 | 202 | |
| 340 | 203 | /** |
| 341 | | − * scmi_rx_callback() - mailbox client callback for receive messages |
| 204 | + * scmi_rx_callback() - callback for receiving messages |
| 342 | 205 | * |
| 343 | | − * @cl: client pointer |
| 344 | | − * @m: mailbox message |
| 206 | + * @cinfo: SCMI channel info |
| 207 | + * @msg_hdr: Message header |
| 345 | 208 | * |
| 346 | 209 | * Processes one received message to appropriate transfer information and |
| 347 | 210 | * signals completion of the transfer. |
| @@ -349,21 +212,14 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer) · 1 unmodified line |
| 349 | 212 | * NOTE: This function will be invoked in IRQ context, hence should be |
| 350 | 213 | * as optimal as possible. |
| 351 | 214 | */ |
| 352 | | −static void scmi_rx_callback(struct mbox_client *cl, void *m) |
| 215 | +void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr) |
| 353 | 216 | { |
| 354 | | − u8 msg_type; |
| 355 | | − u32 msg_hdr; |
| 356 | | − u16 xfer_id; |
| 357 | | − struct scmi_xfer *xfer; |
| 358 | | − struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl); |
| 359 | | − struct device *dev = cinfo->dev; |
| 360 | 217 | struct scmi_info *info = handle_to_scmi_info(cinfo->handle); |
| 361 | 218 | struct scmi_xfers_info *minfo = &info->tx_minfo; |
| 362 | | − struct scmi_shared_mem __iomem *mem = cinfo->payload; |
| 363 | | − |
| 364 | | − msg_hdr = ioread32(&mem->msg_header); |
| 365 | | − msg_type = MSG_XTRACT_TYPE(msg_hdr); |
| 366 | | − xfer_id = MSG_XTRACT_TOKEN(msg_hdr); |
| 219 | + u16 xfer_id = MSG_XTRACT_TOKEN(msg_hdr); |
| 220 | + u8 msg_type = MSG_XTRACT_TYPE(msg_hdr); |
| 221 | + struct device *dev = cinfo->dev; |
| 222 | + struct scmi_xfer *xfer; |
| 367 | 223 | |
| 368 | 224 | if (msg_type == MSG_TYPE_NOTIFICATION) |
| 369 | 225 | return; /* Notifications not yet supported */ |
| @@ -378,7 +234,7 @@ static void scmi_rx_callback(struct mbox_client *cl, void *m) · 8 unmodified lines |
| 378 | 234 | |
| 379 | 235 | scmi_dump_header_dbg(dev, &xfer->hdr); |
| 380 | 236 | |
| 381 | | − scmi_fetch_response(xfer, mem); |
| 237 | + info->desc->ops->fetch_response(cinfo, xfer); |
| 382 | 238 | |
| 383 | 239 | trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id, |
| 384 | 240 | xfer->hdr.protocol_id, xfer->hdr.seq, |
| @@ -403,28 +259,15 @@ void scmi_xfer_put(const struct scmi_handle *handle, struct scmi_xfer *xfer) · 18 unmodified lines |
| 403 | 259 | __scmi_xfer_put(&info->tx_minfo, xfer); |
| 404 | 260 | } |
| 405 | 261 | |
| 406 | | −static bool |
| 407 | | −scmi_xfer_poll_done(const struct scmi_chan_info *cinfo, struct scmi_xfer *xfer) |
| 408 | | −{ |
| 409 | | − struct scmi_shared_mem __iomem *mem = cinfo->payload; |
| 410 | | − u16 xfer_id = MSG_XTRACT_TOKEN(ioread32(&mem->msg_header)); |
| 411 | | − |
| 412 | | − if (xfer->hdr.seq != xfer_id) |
| 413 | | − return false; |
| 414 | | − |
| 415 | | − return ioread32(&mem->channel_status) & |
| 416 | | − (SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR | |
| 417 | | − SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE); |
| 418 | | −} |
| 419 | | − |
| 420 | 262 | #define SCMI_MAX_POLL_TO_NS (100 * NSEC_PER_USEC) |
| 421 | 263 | |
| 422 | | −static bool scmi_xfer_done_no_timeout(const struct scmi_chan_info *cinfo, |
| 264 | +static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo, |
| 423 | 265 | struct scmi_xfer *xfer, ktime_t stop) |
| 424 | 266 | { |
| 425 | | − ktime_t __cur = ktime_get(); |
| 267 | + struct scmi_info *info = handle_to_scmi_info(cinfo->handle); |
| 426 | 268 | |
| 427 | | − return scmi_xfer_poll_done(cinfo, xfer) || ktime_after(__cur, stop); |
| 269 | + return info->desc->ops->poll_done(cinfo, xfer) || |
| 270 | + ktime_after(ktime_get(), stop); |
| 428 | 271 | } |
| 429 | 272 | |
| 430 | 273 | /** |
| @@ -453,29 +296,26 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer) · 22 unmodified lines |
| 453 | 296 | xfer->hdr.protocol_id, xfer->hdr.seq, |
| 454 | 297 | xfer->hdr.poll_completion); |
| 455 | 298 | |
| 456 | | − ret = mbox_send_message(cinfo->chan, xfer); |
| 299 | + ret = info->desc->ops->send_message(cinfo, xfer); |
| 457 | 300 | if (ret < 0) { |
| 458 | | − dev_dbg(dev, "mbox send fail %d\n", ret); |
| 301 | + dev_dbg(dev, "Failed to send message %d\n", ret); |
| 459 | 302 | return ret; |
| 460 | 303 | } |
| 461 | 304 | |
| 462 | | − /* mbox_send_message returns non-negative value on success, so reset */ |
| 463 | | − ret = 0; |
| 464 | | − |
| 465 | 305 | if (xfer->hdr.poll_completion) { |
| 466 | 306 | ktime_t stop = ktime_add_ns(ktime_get(), SCMI_MAX_POLL_TO_NS); |
| 467 | 307 | |
| 468 | 308 | spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop)); |
| 469 | 309 | |
| 470 | 310 | if (ktime_before(ktime_get(), stop)) |
| 471 | | − scmi_fetch_response(xfer, cinfo->payload); |
| 311 | + info->desc->ops->fetch_response(cinfo, xfer); |
| 472 | 312 | else |
| 473 | 313 | ret = -ETIMEDOUT; |
| 474 | 314 | } else { |
| 475 | 315 | /* And we wait for the response. */ |
| 476 | 316 | timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms); |
| 477 | 317 | if (!wait_for_completion_timeout(&xfer->done, timeout)) { |
| 478 | | − dev_err(dev, "mbox timed out in resp(caller: %pS)\n", |
| 318 | + dev_err(dev, "timed out in resp(caller: %pS)\n", |
| 479 | 319 | (void *)_RET_IP_); |
| 480 | 320 | ret = -ETIMEDOUT; |
| 481 | 321 | } |
| @@ -484,13 +324,8 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer) · 2 unmodified lines |
| 484 | 324 | if (!ret && xfer->hdr.status) |
| 485 | 325 | ret = scmi_to_linux_errno(xfer->hdr.status); |
| 486 | 326 | |
| 487 | | − /* |
| 488 | | − * NOTE: we might prefer not to need the mailbox ticker to manage the |
| 489 | | − * transfer queueing since the protocol layer queues things by itself. |
| 490 | | − * Unfortunately, we have to kick the mailbox framework after we have |
| 491 | | − * received our message. |
| 492 | | − */ |
| 493 | | − mbox_client_txdone(cinfo->chan, ret); |
| 327 | + if (info->desc->ops->mark_txdone) |
| 328 | + info->desc->ops->mark_txdone(cinfo, ret); |
| 494 | 329 | |
| 495 | 330 | trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id, |
| 496 | 331 | xfer->hdr.protocol_id, xfer->hdr.seq, |
| @@ -731,23 +566,12 @@ static int scmi_xfer_info_init(struct scmi_info *sinfo) · 234 unmodified lines |
| 731 | 566 | return 0; |
| 732 | 567 | } |
| 733 | 568 | |
| 734 | | −static int scmi_mailbox_check(struct device_node *np, int idx) |
| 735 | | −{ |
| 736 | | − return of_parse_phandle_with_args(np, "mboxes", "#mbox-cells", |
| 737 | | − idx, NULL); |
| 738 | | −} |
| 739 | | − |
| 740 | | −static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev, |
| 741 | | − int prot_id, bool tx) |
| 569 | +static int scmi_chan_setup(struct scmi_info *info, struct device *dev, |
| 570 | + int prot_id, bool tx) |
| 742 | 571 | { |
| 743 | 572 | int ret, idx; |
| 744 | | − struct resource res; |
| 745 | | − resource_size_t size; |
| 746 | | − struct device_node *shmem, *np = dev->of_node; |
| 747 | 573 | struct scmi_chan_info *cinfo; |
| 748 | | − struct mbox_client *cl; |
| 749 | 574 | struct idr *idr; |
| 750 | | − const char *desc = tx ? "Tx" : "Rx"; |
| 751 | 575 | |
| 752 | 576 | /* Transmit channel is first entry i.e. index 0 */ |
| 753 | 577 | idx = tx ? 0 : 1; |
| @@ -758,7 +582,7 @@ static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev, · 4 unmodified lines |
| 758 | 582 | if (cinfo) |
| 759 | 583 | return 0; |
| 760 | 584 | |
| 761 | | − if (scmi_mailbox_check(np, idx)) { |
| 585 | + if (!info->desc->ops->chan_available(dev, idx)) { |
| 762 | 586 | cinfo = idr_find(idr, SCMI_PROTOCOL_BASE); |
| 763 | 587 | if (unlikely(!cinfo)) /* Possible only if platform has no Rx */ |
| 764 | 588 | return -EINVAL; |
| @@ -771,36 +595,9 @@ static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev, · 6 unmodified lines |
| 771 | 595 | |
| 772 | 596 | cinfo->dev = dev; |
| 773 | 597 | |
| 774 | | − cl = &cinfo->cl; |
| 775 | | − cl->dev = dev; |
| 776 | | − cl->rx_callback = scmi_rx_callback; |
| 777 | | − cl->tx_prepare = tx ? scmi_tx_prepare : NULL; |
| 778 | | − cl->tx_block = false; |
| 779 | | − cl->knows_txdone = tx; |
| 780 | | − |
| 781 | | − shmem = of_parse_phandle(np, "shmem", idx); |
| 782 | | − ret = of_address_to_resource(shmem, 0, &res); |
| 783 | | − of_node_put(shmem); |
| 784 | | − if (ret) { |
| 785 | | − dev_err(dev, "failed to get SCMI %s payload memory\n", desc); |
| 786 | | − return ret; |
| 787 | | − } |
| 788 | | − |
| 789 | | − size = resource_size(&res); |
| 790 | | − cinfo->payload = devm_ioremap(info->dev, res.start, size); |
| 791 | | − if (!cinfo->payload) { |
| 792 | | − dev_err(dev, "failed to ioremap SCMI %s payload\n", desc); |
| 793 | | − return -EADDRNOTAVAIL; |
| 794 | | − } |
| 795 | | − |
| 796 | | − cinfo->chan = mbox_request_channel(cl, idx); |
| 797 | | − if (IS_ERR(cinfo->chan)) { |
| 798 | | − ret = PTR_ERR(cinfo->chan); |
| 799 | | − if (ret != -EPROBE_DEFER) |
| 800 | | − dev_err(dev, "failed to request SCMI %s mailbox\n", |
| 801 | | − desc); |
| 598 | + ret = info->desc->ops->chan_setup(cinfo, info->dev, tx); |
| 599 | + if (ret) |
| 802 | 600 | return ret; |
| 803 | | − } |
| 804 | 601 | |
| 805 | 602 | idr_alloc: |
| 806 | 603 | ret = idr_alloc(idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL); |
| @@ -814,12 +611,12 @@ idr_alloc: · 7 unmodified lines |
| 814 | 611 | } |
| 815 | 612 | |
| 816 | 613 | static inline int |
| 817 | | −scmi_mbox_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id) |
| 614 | +scmi_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id) |
| 818 | 615 | { |
| 819 | | − int ret = scmi_mbox_chan_setup(info, dev, prot_id, true); |
| 616 | + int ret = scmi_chan_setup(info, dev, prot_id, true); |
| 820 | 617 | |
| 821 | 618 | if (!ret) /* Rx is optional, hence no error check */ |
| 822 | | − scmi_mbox_chan_setup(info, dev, prot_id, false); |
| 619 | + scmi_chan_setup(info, dev, prot_id, false); |
| 823 | 620 | |
| 824 | 621 | return ret; |
| 825 | 622 | } |
| @@ -837,7 +634,7 @@ scmi_create_protocol_device(struct device_node *np, struct scmi_info *info, · 11 unmodified lines |
| 837 | 634 | return; |
| 838 | 635 | } |
| 839 | 636 | |
| 840 | | − if (scmi_mbox_txrx_setup(info, &sdev->dev, prot_id)) { |
| 637 | + if (scmi_txrx_setup(info, &sdev->dev, prot_id)) { |
| 841 | 638 | dev_err(&sdev->dev, "failed to setup transport\n"); |
| 842 | 639 | scmi_device_destroy(sdev); |
| 843 | 640 | return; |
| @@ -890,12 +687,6 @@ static int scmi_probe(struct platform_device *pdev) · 46 unmodified lines |
| 890 | 687 | struct device *dev = &pdev->dev; |
| 891 | 688 | struct device_node *child, *np = dev->of_node; |
| 892 | 689 | |
| 893 | | − /* Only mailbox method supported, check for the presence of one */ |
| 894 | | − if (scmi_mailbox_check(np, 0)) { |
| 895 | | − dev_err(dev, "no mailbox found in %pOF\n", np); |
| 896 | | − return -EINVAL; |
| 897 | | − } |
| 898 | | − |
| 899 | 690 | desc = of_device_get_match_data(dev); |
| 900 | 691 | if (!desc) |
| 901 | 692 | return -EINVAL; |
| @@ -920,7 +711,7 @@ static int scmi_probe(struct platform_device *pdev) · 18 unmodified lines |
| 920 | 711 | handle->dev = info->dev; |
| 921 | 712 | handle->version = &info->version; |
| 922 | 713 | |
| 923 | | − ret = scmi_mbox_txrx_setup(info, dev, SCMI_PROTOCOL_BASE); |
| 714 | + ret = scmi_txrx_setup(info, dev, SCMI_PROTOCOL_BASE); |
| 924 | 715 | if (ret) |
| 925 | 716 | return ret; |
| 926 | 717 | |
| @@ -955,19 +746,9 @@ static int scmi_probe(struct platform_device *pdev) · 28 unmodified lines |
| 955 | 746 | return 0; |
| 956 | 747 | } |
| 957 | 748 | |
| 958 | | −static int scmi_mbox_free_channel(int id, void *p, void *data) |
| 749 | +void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id) |
| 959 | 750 | { |
| 960 | | − struct scmi_chan_info *cinfo = p; |
| 961 | | − struct idr *idr = data; |
| 962 | | − |
| 963 | | − if (!IS_ERR_OR_NULL(cinfo->chan)) { |
| 964 | | − mbox_free_channel(cinfo->chan); |
| 965 | | − cinfo->chan = NULL; |
| 966 | | − } |
| 967 | | − |
| 968 | 751 | idr_remove(idr, id); |
| 969 | | − |
| 970 | | − return 0; |
| 971 | 752 | } |
| 972 | 753 | |
| 973 | 754 | static int scmi_remove(struct platform_device *pdev) |
| @@ -987,11 +768,11 @@ static int scmi_remove(struct platform_device *pdev) · 13 unmodified lines |
| 987 | 768 | return ret; |
| 988 | 769 | |
| 989 | 770 | /* Safe to free channels since no more users */ |
| 990 | | − ret = idr_for_each(idr, scmi_mbox_free_channel, idr); |
| 771 | + ret = idr_for_each(idr, info->desc->ops->chan_free, idr); |
| 991 | 772 | idr_destroy(&info->tx_idr); |
| 992 | 773 | |
| 993 | 774 | idr = &info->rx_idr; |
| 994 | | − ret = idr_for_each(idr, scmi_mbox_free_channel, idr); |
| 775 | + ret = idr_for_each(idr, info->desc->ops->chan_free, idr); |
| 995 | 776 | idr_destroy(&info->rx_idr); |
| 996 | 777 | |
| 997 | 778 | return ret; |
| @@ -1043,15 +824,9 @@ static struct attribute *versions_attrs[] = { · 45 unmodified lines |
| 1043 | 824 | }; |
| 1044 | 825 | ATTRIBUTE_GROUPS(versions); |
| 1045 | 826 | |
| 1046 | | −static const struct scmi_desc scmi_generic_desc = { |
| 1047 | | − .max_rx_timeout_ms = 30, /* We may increase this if required */ |
| 1048 | | − .max_msg = 20, /* Limited by MBOX_TX_QUEUE_LEN */ |
| 1049 | | − .max_msg_size = 128, |
| 1050 | | −}; |
| 1051 | | − |
| 1052 | 827 | /* Each compatible listed below must have descriptor associated with it */ |
| 1053 | 828 | static const struct of_device_id scmi_of_match[] = { |
| 1054 | | − { .compatible = "arm,scmi", .data = &scmi_generic_desc }, |
| 829 | + { .compatible = "arm,scmi", .data = &scmi_mailbox_desc }, |
| 1055 | 830 | { /* Sentinel */ }, |
| 1056 | 831 | }; |
| 1057 | 832 | |