File Index
Files and directories
Sign in
FILE

ti_sci.c

File preview with syntax highlighting.

linux-6.19.14/drivers/firmware/ti_sci.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Texas Instruments System Control Interface Protocol Driver
   4 *
   5 * Copyright (C) 2015-2025 Texas Instruments Incorporated - https://www.ti.com/
   6 *	Nishanth Menon
   7 */
   8
   9#define pr_fmt(fmt) "%s: " fmt, __func__
  10
  11#include <linux/bitmap.h>
  12#include <linux/cpu.h>
  13#include <linux/debugfs.h>
  14#include <linux/export.h>
  15#include <linux/io.h>
  16#include <linux/iopoll.h>
  17#include <linux/kernel.h>
  18#include <linux/mailbox_client.h>
  19#include <linux/module.h>
  20#include <linux/of.h>
  21#include <linux/of_platform.h>
  22#include <linux/platform_device.h>
  23#include <linux/pm_qos.h>
  24#include <linux/property.h>
  25#include <linux/semaphore.h>
  26#include <linux/slab.h>
  27#include <linux/soc/ti/ti-msgmgr.h>
  28#include <linux/soc/ti/ti_sci_protocol.h>
  29#include <linux/suspend.h>
  30#include <linux/sys_soc.h>
  31#include <linux/reboot.h>
  32
  33#include "ti_sci.h"
  34
  35/* List of all TI SCI devices active in system */
  36static LIST_HEAD(ti_sci_list);
  37/* Protection for the entire list */
  38static DEFINE_MUTEX(ti_sci_list_mutex);
  39
  40/**
  41 * struct ti_sci_xfer - Structure representing a message flow
  42 * @tx_message:	Transmit message
  43 * @rx_len:	Receive message length
  44 * @xfer_buf:	Preallocated buffer to store receive message
  45 *		Since we work with request-ACK protocol, we can
  46 *		reuse the same buffer for the rx path as we
  47 *		use for the tx path.
  48 * @done:	completion event
  49 */
  50struct ti_sci_xfer {
  51	struct ti_msgmgr_message tx_message;
  52	u8 rx_len;
  53	u8 *xfer_buf;
  54	struct completion done;
  55};
  56
  57/**
  58 * struct ti_sci_xfers_info - Structure to manage transfer information
  59 * @sem_xfer_count:	Counting Semaphore for managing max simultaneous
  60 *			Messages.
  61 * @xfer_block:		Preallocated Message array
  62 * @xfer_alloc_table:	Bitmap table for allocated messages.
  63 *			Index of this bitmap table is also used for message
  64 *			sequence identifier.
  65 * @xfer_lock:		Protection for message allocation
  66 */
  67struct ti_sci_xfers_info {
  68	struct semaphore sem_xfer_count;
  69	struct ti_sci_xfer *xfer_block;
  70	unsigned long *xfer_alloc_table;
  71	/* protect transfer allocation */
  72	spinlock_t xfer_lock;
  73};
  74
  75/**
  76 * struct ti_sci_desc - Description of SoC integration
  77 * @default_host_id:	Host identifier representing the compute entity
  78 * @max_rx_timeout_ms:	Timeout for communication with SoC (in Milliseconds)
  79 * @max_msgs: Maximum number of messages that can be pending
  80 *		  simultaneously in the system
  81 * @max_msg_size: Maximum size of data per message that can be handled.
  82 */
  83struct ti_sci_desc {
  84	u8 default_host_id;
  85	int max_rx_timeout_ms;
  86	int max_msgs;
  87	int max_msg_size;
  88};
  89
  90/**
  91 * struct ti_sci_info - Structure representing a TI SCI instance
  92 * @dev:	Device pointer
  93 * @desc:	SoC description for this instance
  94 * @d:		Debugfs file entry
  95 * @debug_region: Memory region where the debug message are available
  96 * @debug_region_size: Debug region size
  97 * @debug_buffer: Buffer allocated to copy debug messages.
  98 * @handle:	Instance of TI SCI handle to send to clients.
  99 * @cl:		Mailbox Client
 100 * @chan_tx:	Transmit mailbox channel
 101 * @chan_rx:	Receive mailbox channel
 102 * @minfo:	Message info
 103 * @node:	list head
 104 * @host_id:	Host ID
 105 * @fw_caps:	FW/SoC low power capabilities
 106 * @users:	Number of users of this instance
 107 */
 108struct ti_sci_info {
 109	struct device *dev;
 110	const struct ti_sci_desc *desc;
 111	struct dentry *d;
 112	void __iomem *debug_region;
 113	char *debug_buffer;
 114	size_t debug_region_size;
 115	struct ti_sci_handle handle;
 116	struct mbox_client cl;
 117	struct mbox_chan *chan_tx;
 118	struct mbox_chan *chan_rx;
 119	struct ti_sci_xfers_info minfo;
 120	struct list_head node;
 121	u8 host_id;
 122	u64 fw_caps;
 123	/* protected by ti_sci_list_mutex */
 124	int users;
 125};
 126
 127#define cl_to_ti_sci_info(c)	container_of(c, struct ti_sci_info, cl)
 128#define handle_to_ti_sci_info(h) container_of(h, struct ti_sci_info, handle)
 129
 130#ifdef CONFIG_DEBUG_FS
 131
 132/**
 133 * ti_sci_debug_show() - Helper to dump the debug log
 134 * @s:	sequence file pointer
 135 * @unused:	unused.
 136 *
 137 * Return: 0
 138 */
 139static int ti_sci_debug_show(struct seq_file *s, void *unused)
 140{
 141	struct ti_sci_info *info = s->private;
 142
 143	memcpy_fromio(info->debug_buffer, info->debug_region,
 144		      info->debug_region_size);
 145	/*
 146	 * We don't trust firmware to leave NULL terminated last byte (hence
 147	 * we have allocated 1 extra 0 byte). Since we cannot guarantee any
 148	 * specific data format for debug messages, We just present the data
 149	 * in the buffer as is - we expect the messages to be self explanatory.
 150	 */
 151	seq_puts(s, info->debug_buffer);
 152	return 0;
 153}
 154
 155/* Provide the log file operations interface*/
 156DEFINE_SHOW_ATTRIBUTE(ti_sci_debug);
 157
 158/**
 159 * ti_sci_debugfs_create() - Create log debug file
 160 * @pdev:	platform device pointer
 161 * @info:	Pointer to SCI entity information
 162 *
 163 * Return: 0 if all went fine, else corresponding error.
 164 */
 165static int ti_sci_debugfs_create(struct platform_device *pdev,
 166				 struct ti_sci_info *info)
 167{
 168	struct device *dev = &pdev->dev;
 169	struct resource *res;
 170	char debug_name[50];
 171
 172	/* Debug region is optional */
 173	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 174					   "debug_messages");
 175	info->debug_region = devm_ioremap_resource(dev, res);
 176	if (IS_ERR(info->debug_region))
 177		return 0;
 178	info->debug_region_size = resource_size(res);
 179
 180	info->debug_buffer = devm_kcalloc(dev, info->debug_region_size + 1,
 181					  sizeof(char), GFP_KERNEL);
 182	if (!info->debug_buffer)
 183		return -ENOMEM;
 184	/* Setup NULL termination */
 185	info->debug_buffer[info->debug_region_size] = 0;
 186
 187	snprintf(debug_name, sizeof(debug_name), "ti_sci_debug@%s",
 188		 dev_name(dev));
 189	info->d = debugfs_create_file(debug_name, 0444, NULL, info,
 190				      &ti_sci_debug_fops);
 191	if (IS_ERR(info->d))
 192		return PTR_ERR(info->d);
 193
 194	dev_dbg(dev, "Debug region => %p, size = %zu bytes, resource: %pr\n",
 195		info->debug_region, info->debug_region_size, res);
 196	return 0;
 197}
 198
 199#else /* CONFIG_DEBUG_FS */
 200static inline int ti_sci_debugfs_create(struct platform_device *dev,
 201					struct ti_sci_info *info)
 202{
 203	return 0;
 204}
 205
 206static inline void ti_sci_debugfs_destroy(struct platform_device *dev,
 207					  struct ti_sci_info *info)
 208{
 209}
 210#endif /* CONFIG_DEBUG_FS */
 211
 212/**
 213 * ti_sci_dump_header_dbg() - Helper to dump a message header.
 214 * @dev:	Device pointer corresponding to the SCI entity
 215 * @hdr:	pointer to header.
 216 */
 217static inline void ti_sci_dump_header_dbg(struct device *dev,
 218					  struct ti_sci_msg_hdr *hdr)
 219{
 220	dev_dbg(dev, "MSGHDR:type=0x%04x host=0x%02x seq=0x%02x flags=0x%08x\n",
 221		hdr->type, hdr->host, hdr->seq, hdr->flags);
 222}
 223
 224/**
 225 * ti_sci_rx_callback() - mailbox client callback for receive messages
 226 * @cl:	client pointer
 227 * @m:	mailbox message
 228 *
 229 * Processes one received message to appropriate transfer information and
 230 * signals completion of the transfer.
 231 *
 232 * NOTE: This function will be invoked in IRQ context, hence should be
 233 * as optimal as possible.
 234 */
 235static void ti_sci_rx_callback(struct mbox_client *cl, void *m)
 236{
 237	struct ti_sci_info *info = cl_to_ti_sci_info(cl);
 238	struct device *dev = info->dev;
 239	struct ti_sci_xfers_info *minfo = &info->minfo;
 240	struct ti_msgmgr_message *mbox_msg = m;
 241	struct ti_sci_msg_hdr *hdr = (struct ti_sci_msg_hdr *)mbox_msg->buf;
 242	struct ti_sci_xfer *xfer;
 243	u8 xfer_id;
 244
 245	xfer_id = hdr->seq;
 246
 247	/*
 248	 * Are we even expecting this?
 249	 * NOTE: barriers were implicit in locks used for modifying the bitmap
 250	 */
 251	if (!test_bit(xfer_id, minfo->xfer_alloc_table)) {
 252		dev_err(dev, "Message for %d is not expected!\n", xfer_id);
 253		return;
 254	}
 255
 256	xfer = &minfo->xfer_block[xfer_id];
 257
 258	/* Is the message of valid length? */
 259	if (mbox_msg->len > info->desc->max_msg_size) {
 260		dev_err(dev, "Unable to handle %zu xfer(max %d)\n",
 261			mbox_msg->len, info->desc->max_msg_size);
 262		ti_sci_dump_header_dbg(dev, hdr);
 263		return;
 264	}
 265	if (mbox_msg->len < xfer->rx_len) {
 266		dev_err(dev, "Recv xfer %zu < expected %d length\n",
 267			mbox_msg->len, xfer->rx_len);
 268		ti_sci_dump_header_dbg(dev, hdr);
 269		return;
 270	}
 271
 272	ti_sci_dump_header_dbg(dev, hdr);
 273	/* Take a copy to the rx buffer.. */
 274	memcpy(xfer->xfer_buf, mbox_msg->buf, xfer->rx_len);
 275	complete(&xfer->done);
 276}
 277
 278/**
 279 * ti_sci_get_one_xfer() - Allocate one message
 280 * @info:	Pointer to SCI entity information
 281 * @msg_type:	Message type
 282 * @msg_flags:	Flag to set for the message
 283 * @tx_message_size: transmit message size
 284 * @rx_message_size: receive message size
 285 *
 286 * Helper function which is used by various command functions that are
 287 * exposed to clients of this driver for allocating a message traffic event.
 288 *
 289 * This function can sleep depending on pending requests already in the system
 290 * for the SCI entity. Further, this also holds a spinlock to maintain integrity
 291 * of internal data structures.
 292 *
 293 * Return: 0 if all went fine, else corresponding error.
 294 */
 295static struct ti_sci_xfer *ti_sci_get_one_xfer(struct ti_sci_info *info,
 296					       u16 msg_type, u32 msg_flags,
 297					       size_t tx_message_size,
 298					       size_t rx_message_size)
 299{
 300	struct ti_sci_xfers_info *minfo = &info->minfo;
 301	struct ti_sci_xfer *xfer;
 302	struct ti_sci_msg_hdr *hdr;
 303	unsigned long flags;
 304	unsigned long bit_pos;
 305	u8 xfer_id;
 306	int ret;
 307	int timeout;
 308
 309	/* Ensure we have sane transfer sizes */
 310	if (rx_message_size > info->desc->max_msg_size ||
 311	    tx_message_size > info->desc->max_msg_size ||
 312	    rx_message_size < sizeof(*hdr) || tx_message_size < sizeof(*hdr))
 313		return ERR_PTR(-ERANGE);
 314
 315	/*
 316	 * Ensure we have only controlled number of pending messages.
 317	 * Ideally, we might just have to wait a single message, be
 318	 * conservative and wait 5 times that..
 319	 */
 320	timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms) * 5;
 321	ret = down_timeout(&minfo->sem_xfer_count, timeout);
 322	if (ret < 0)
 323		return ERR_PTR(ret);
 324
 325	/* Keep the locked section as small as possible */
 326	spin_lock_irqsave(&minfo->xfer_lock, flags);
 327	bit_pos = find_first_zero_bit(minfo->xfer_alloc_table,
 328				      info->desc->max_msgs);
 329	set_bit(bit_pos, minfo->xfer_alloc_table);
 330	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
 331
 332	/*
 333	 * We already ensured in probe that we can have max messages that can
 334	 * fit in  hdr.seq - NOTE: this improves access latencies
 335	 * to predictable O(1) access, BUT, it opens us to risk if
 336	 * remote misbehaves with corrupted message sequence responses.
 337	 * If that happens, we are going to be messed up anyways..
 338	 */
 339	xfer_id = (u8)bit_pos;
 340
 341	xfer = &minfo->xfer_block[xfer_id];
 342
 343	hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
 344	xfer->tx_message.len = tx_message_size;
 345	xfer->tx_message.chan_rx = info->chan_rx;
 346	xfer->tx_message.timeout_rx_ms = info->desc->max_rx_timeout_ms;
 347	xfer->rx_len = (u8)rx_message_size;
 348
 349	reinit_completion(&xfer->done);
 350
 351	hdr->seq = xfer_id;
 352	hdr->type = msg_type;
 353	hdr->host = info->host_id;
 354	hdr->flags = msg_flags;
 355
 356	return xfer;
 357}
 358
 359/**
 360 * ti_sci_put_one_xfer() - Release a message
 361 * @minfo:	transfer info pointer
 362 * @xfer:	message that was reserved by ti_sci_get_one_xfer
 363 *
 364 * This holds a spinlock to maintain integrity of internal data structures.
 365 */
 366static void ti_sci_put_one_xfer(struct ti_sci_xfers_info *minfo,
 367				struct ti_sci_xfer *xfer)
 368{
 369	unsigned long flags;
 370	struct ti_sci_msg_hdr *hdr;
 371	u8 xfer_id;
 372
 373	hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
 374	xfer_id = hdr->seq;
 375
 376	/*
 377	 * Keep the locked section as small as possible
 378	 * NOTE: we might escape with smp_mb and no lock here..
 379	 * but just be conservative and symmetric.
 380	 */
 381	spin_lock_irqsave(&minfo->xfer_lock, flags);
 382	clear_bit(xfer_id, minfo->xfer_alloc_table);
 383	spin_unlock_irqrestore(&minfo->xfer_lock, flags);
 384
 385	/* Increment the count for the next user to get through */
 386	up(&minfo->sem_xfer_count);
 387}
 388
 389/**
 390 * ti_sci_do_xfer() - Do one transfer
 391 * @info:	Pointer to SCI entity information
 392 * @xfer:	Transfer to initiate and wait for response
 393 *
 394 * Return: -ETIMEDOUT in case of no response, if transmit error,
 395 *	   return corresponding error, else if all goes well,
 396 *	   return 0.
 397 */
 398static inline int ti_sci_do_xfer(struct ti_sci_info *info,
 399				 struct ti_sci_xfer *xfer)
 400{
 401	struct ti_sci_msg_hdr *hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
 402	bool response_expected = !!(hdr->flags & (TI_SCI_FLAG_REQ_ACK_ON_PROCESSED |
 403						  TI_SCI_FLAG_REQ_ACK_ON_RECEIVED));
 404	int ret;
 405	int timeout;
 406	struct device *dev = info->dev;
 407	bool done_state = true;
 408
 409	ret = mbox_send_message(info->chan_tx, &xfer->tx_message);
 410	if (ret < 0)
 411		return ret;
 412
 413	ret = 0;
 414
 415	if (response_expected && system_state <= SYSTEM_RUNNING) {
 416		/* And we wait for the response. */
 417		timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms);
 418		if (!wait_for_completion_timeout(&xfer->done, timeout))
 419			ret = -ETIMEDOUT;
 420	} else if (response_expected) {
 421		/*
 422		 * If we are !running, we cannot use wait_for_completion_timeout
 423		 * during noirq phase, so we must manually poll the completion.
 424		 */
 425		ret = read_poll_timeout_atomic(try_wait_for_completion, done_state,
 426					       done_state, 1,
 427					       info->desc->max_rx_timeout_ms * 1000,
 428					       false, &xfer->done);
 429	}
 430
 431	if (ret == -ETIMEDOUT)
 432		dev_err(dev, "Mbox timedout in resp(caller: %pS)\n",
 433			(void *)_RET_IP_);
 434
 435	/*
 436	 * NOTE: we might prefer not to need the mailbox ticker to manage the
 437	 * transfer queueing since the protocol layer queues things by itself.
 438	 * Unfortunately, we have to kick the mailbox framework after we have
 439	 * received our message.
 440	 */
 441	mbox_client_txdone(info->chan_tx, ret);
 442
 443	return ret;
 444}
 445
 446/**
 447 * ti_sci_cmd_get_revision() - command to get the revision of the SCI entity
 448 * @info:	Pointer to SCI entity information
 449 *
 450 * Updates the SCI information in the internal data structure.
 451 *
 452 * Return: 0 if all went fine, else return appropriate error.
 453 */
 454static int ti_sci_cmd_get_revision(struct ti_sci_info *info)
 455{
 456	struct device *dev = info->dev;
 457	struct ti_sci_handle *handle = &info->handle;
 458	struct ti_sci_version_info *ver = &handle->version;
 459	struct ti_sci_msg_resp_version *rev_info;
 460	struct ti_sci_xfer *xfer;
 461	int ret;
 462
 463	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_VERSION,
 464				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
 465				   sizeof(struct ti_sci_msg_hdr),
 466				   sizeof(*rev_info));
 467	if (IS_ERR(xfer)) {
 468		ret = PTR_ERR(xfer);
 469		dev_err(dev, "Message alloc failed(%d)\n", ret);
 470		return ret;
 471	}
 472
 473	rev_info = (struct ti_sci_msg_resp_version *)xfer->xfer_buf;
 474
 475	ret = ti_sci_do_xfer(info, xfer);
 476	if (ret) {
 477		dev_err(dev, "Mbox send fail %d\n", ret);
 478		goto fail;
 479	}
 480
 481	ver->abi_major = rev_info->abi_major;
 482	ver->abi_minor = rev_info->abi_minor;
 483	ver->firmware_revision = rev_info->firmware_revision;
 484	strscpy(ver->firmware_description, rev_info->firmware_description,
 485		sizeof(ver->firmware_description));
 486
 487fail:
 488	ti_sci_put_one_xfer(&info->minfo, xfer);
 489	return ret;
 490}
 491
 492/**
 493 * ti_sci_is_response_ack() - Generic ACK/NACK message checkup
 494 * @r:	pointer to response buffer
 495 *
 496 * Return: true if the response was an ACK, else returns false.
 497 */
 498static inline bool ti_sci_is_response_ack(void *r)
 499{
 500	struct ti_sci_msg_hdr *hdr = r;
 501
 502	return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false;
 503}
 504
 505/**
 506 * ti_sci_set_device_state() - Set device state helper
 507 * @handle:	pointer to TI SCI handle
 508 * @id:		Device identifier
 509 * @flags:	flags to setup for the device
 510 * @state:	State to move the device to
 511 *
 512 * Return: 0 if all went well, else returns appropriate error value.
 513 */
 514static int ti_sci_set_device_state(const struct ti_sci_handle *handle,
 515				   u32 id, u32 flags, u8 state)
 516{
 517	struct ti_sci_info *info;
 518	struct ti_sci_msg_req_set_device_state *req;
 519	struct ti_sci_msg_hdr *resp;
 520	struct ti_sci_xfer *xfer;
 521	struct device *dev;
 522	int ret = 0;
 523
 524	if (IS_ERR(handle))
 525		return PTR_ERR(handle);
 526	if (!handle)
 527		return -EINVAL;
 528
 529	info = handle_to_ti_sci_info(handle);
 530	dev = info->dev;
 531
 532	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE,
 533				   flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
 534				   sizeof(*req), sizeof(*resp));
 535	if (IS_ERR(xfer)) {
 536		ret = PTR_ERR(xfer);
 537		dev_err(dev, "Message alloc failed(%d)\n", ret);
 538		return ret;
 539	}
 540	req = (struct ti_sci_msg_req_set_device_state *)xfer->xfer_buf;
 541	req->id = id;
 542	req->state = state;
 543
 544	ret = ti_sci_do_xfer(info, xfer);
 545	if (ret) {
 546		dev_err(dev, "Mbox send fail %d\n", ret);
 547		goto fail;
 548	}
 549
 550	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
 551
 552	ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
 553
 554fail:
 555	ti_sci_put_one_xfer(&info->minfo, xfer);
 556
 557	return ret;
 558}
 559
 560/**
 561 * ti_sci_get_device_state() - Get device state helper
 562 * @handle:	Handle to the device
 563 * @id:		Device Identifier
 564 * @clcnt:	Pointer to Context Loss Count
 565 * @resets:	pointer to resets
 566 * @p_state:	pointer to p_state
 567 * @c_state:	pointer to c_state
 568 *
 569 * Return: 0 if all went fine, else return appropriate error.
 570 */
 571static int ti_sci_get_device_state(const struct ti_sci_handle *handle,
 572				   u32 id,  u32 *clcnt,  u32 *resets,
 573				    u8 *p_state,  u8 *c_state)
 574{
 575	struct ti_sci_info *info;
 576	struct ti_sci_msg_req_get_device_state *req;
 577	struct ti_sci_msg_resp_get_device_state *resp;
 578	struct ti_sci_xfer *xfer;
 579	struct device *dev;
 580	int ret = 0;
 581
 582	if (IS_ERR(handle))
 583		return PTR_ERR(handle);
 584	if (!handle)
 585		return -EINVAL;
 586
 587	if (!clcnt && !resets && !p_state && !c_state)
 588		return -EINVAL;
 589
 590	info = handle_to_ti_sci_info(handle);
 591	dev = info->dev;
 592
 593	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_DEVICE_STATE,
 594				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
 595				   sizeof(*req), sizeof(*resp));
 596	if (IS_ERR(xfer)) {
 597		ret = PTR_ERR(xfer);
 598		dev_err(dev, "Message alloc failed(%d)\n", ret);
 599		return ret;
 600	}
 601	req = (struct ti_sci_msg_req_get_device_state *)xfer->xfer_buf;
 602	req->id = id;
 603
 604	ret = ti_sci_do_xfer(info, xfer);
 605	if (ret) {
 606		dev_err(dev, "Mbox send fail %d\n", ret);
 607		goto fail;
 608	}
 609
 610	resp = (struct ti_sci_msg_resp_get_device_state *)xfer->xfer_buf;
 611	if (!ti_sci_is_response_ack(resp)) {
 612		ret = -ENODEV;
 613		goto fail;
 614	}
 615
 616	if (clcnt)
 617		*clcnt = resp->context_loss_count;
 618	if (resets)
 619		*resets = resp->resets;
 620	if (p_state)
 621		*p_state = resp->programmed_state;
 622	if (c_state)
 623		*c_state = resp->current_state;
 624fail:
 625	ti_sci_put_one_xfer(&info->minfo, xfer);
 626
 627	return ret;
 628}
 629
 630/**
 631 * ti_sci_cmd_get_device() - command to request for device managed by TISCI
 632 *			     that can be shared with other hosts.
 633 * @handle:	Pointer to TISCI handle as retrieved by *ti_sci_get_handle
 634 * @id:		Device Identifier
 635 *
 636 * Request for the device - NOTE: the client MUST maintain integrity of
 637 * usage count by balancing get_device with put_device. No refcounting is
 638 * managed by driver for that purpose.
 639 *
 640 * Return: 0 if all went fine, else return appropriate error.
 641 */
 642static int ti_sci_cmd_get_device(const struct ti_sci_handle *handle, u32 id)
 643{
 644	return ti_sci_set_device_state(handle, id, 0,
 645				       MSG_DEVICE_SW_STATE_ON);
 646}
 647
 648/**
 649 * ti_sci_cmd_get_device_exclusive() - command to request for device managed by
 650 *				       TISCI that is exclusively owned by the
 651 *				       requesting host.
 652 * @handle:	Pointer to TISCI handle as retrieved by *ti_sci_get_handle
 653 * @id:		Device Identifier
 654 *
 655 * Request for the device - NOTE: the client MUST maintain integrity of
 656 * usage count by balancing get_device with put_device. No refcounting is
 657 * managed by driver for that purpose.
 658 *
 659 * Return: 0 if all went fine, else return appropriate error.
 660 */
 661static int ti_sci_cmd_get_device_exclusive(const struct ti_sci_handle *handle,
 662					   u32 id)
 663{
 664	return ti_sci_set_device_state(handle, id,
 665				       MSG_FLAG_DEVICE_EXCLUSIVE,
 666				       MSG_DEVICE_SW_STATE_ON);
 667}
 668
 669/**
 670 * ti_sci_cmd_idle_device() - Command to idle a device managed by TISCI
 671 * @handle:	Pointer to TISCI handle as retrieved by *ti_sci_get_handle
 672 * @id:		Device Identifier
 673 *
 674 * Request for the device - NOTE: the client MUST maintain integrity of
 675 * usage count by balancing get_device with put_device. No refcounting is
 676 * managed by driver for that purpose.
 677 *
 678 * Return: 0 if all went fine, else return appropriate error.
 679 */
 680static int ti_sci_cmd_idle_device(const struct ti_sci_handle *handle, u32 id)
 681{
 682	return ti_sci_set_device_state(handle, id, 0,
 683				       MSG_DEVICE_SW_STATE_RETENTION);
 684}
 685
 686/**
 687 * ti_sci_cmd_idle_device_exclusive() - Command to idle a device managed by
 688 *					TISCI that is exclusively owned by
 689 *					requesting host.
 690 * @handle:	Pointer to TISCI handle as retrieved by *ti_sci_get_handle
 691 * @id:		Device Identifier
 692 *
 693 * Request for the device - NOTE: the client MUST maintain integrity of
 694 * usage count by balancing get_device with put_device. No refcounting is
 695 * managed by driver for that purpose.
 696 *
 697 * Return: 0 if all went fine, else return appropriate error.
 698 */
 699static int ti_sci_cmd_idle_device_exclusive(const struct ti_sci_handle *handle,
 700					    u32 id)
 701{
 702	return ti_sci_set_device_state(handle, id,
 703				       MSG_FLAG_DEVICE_EXCLUSIVE,
 704				       MSG_DEVICE_SW_STATE_RETENTION);
 705}
 706
 707/**
 708 * ti_sci_cmd_put_device() - command to release a device managed by TISCI
 709 * @handle:	Pointer to TISCI handle as retrieved by *ti_sci_get_handle
 710 * @id:		Device Identifier
 711 *
 712 * Request for the device - NOTE: the client MUST maintain integrity of
 713 * usage count by balancing get_device with put_device. No refcounting is
 714 * managed by driver for that purpose.
 715 *
 716 * Return: 0 if all went fine, else return appropriate error.
 717 */
 718static int ti_sci_cmd_put_device(const struct ti_sci_handle *handle, u32 id)
 719{
 720	return ti_sci_set_device_state(handle, id,
 721				       0, MSG_DEVICE_SW_STATE_AUTO_OFF);
 722}
 723
 724/**
 725 * ti_sci_cmd_dev_is_valid() - Is the device valid
 726 * @handle:	Pointer to TISCI handle as retrieved by *ti_sci_get_handle
 727 * @id:		Device Identifier
 728 *
 729 * Return: 0 if all went fine and the device ID is valid, else return
 730 * appropriate error.
 731 */
 732static int ti_sci_cmd_dev_is_valid(const struct ti_sci_handle *handle, u32 id)
 733{
 734	u8 unused;
 735
 736	/* check the device state which will also tell us if the ID is valid */
 737	return ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &unused);
 738}
 739
 740/**
 741 * ti_sci_cmd_dev_get_clcnt() - Get context loss counter
 742 * @handle:	Pointer to TISCI handle
 743 * @id:		Device Identifier
 744 * @count:	Pointer to Context Loss counter to populate
 745 *
 746 * Return: 0 if all went fine, else return appropriate error.
 747 */
 748static int ti_sci_cmd_dev_get_clcnt(const struct ti_sci_handle *handle, u32 id,
 749				    u32 *count)
 750{
 751	return ti_sci_get_device_state(handle, id, count, NULL, NULL, NULL);
 752}
 753
 754/**
 755 * ti_sci_cmd_dev_is_idle() - Check if the device is requested to be idle
 756 * @handle:	Pointer to TISCI handle
 757 * @id:		Device Identifier
 758 * @r_state:	true if requested to be idle
 759 *
 760 * Return: 0 if all went fine, else return appropriate error.
 761 */
 762static int ti_sci_cmd_dev_is_idle(const struct ti_sci_handle *handle, u32 id,
 763				  bool *r_state)
 764{
 765	int ret;
 766	u8 state;
 767
 768	if (!r_state)
 769		return -EINVAL;
 770
 771	ret = ti_sci_get_device_state(handle, id, NULL, NULL, &state, NULL);
 772	if (ret)
 773		return ret;
 774
 775	*r_state = (state == MSG_DEVICE_SW_STATE_RETENTION);
 776
 777	return 0;
 778}
 779
 780/**
 781 * ti_sci_cmd_dev_is_stop() - Check if the device is requested to be stopped
 782 * @handle:	Pointer to TISCI handle
 783 * @id:		Device Identifier
 784 * @r_state:	true if requested to be stopped
 785 * @curr_state:	true if currently stopped.
 786 *
 787 * Return: 0 if all went fine, else return appropriate error.
 788 */
 789static int ti_sci_cmd_dev_is_stop(const struct ti_sci_handle *handle, u32 id,
 790				  bool *r_state,  bool *curr_state)
 791{
 792	int ret;
 793	u8 p_state, c_state;
 794
 795	if (!r_state && !curr_state)
 796		return -EINVAL;
 797
 798	ret =
 799	    ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state);
 800	if (ret)
 801		return ret;
 802
 803	if (r_state)
 804		*r_state = (p_state == MSG_DEVICE_SW_STATE_AUTO_OFF);
 805	if (curr_state)
 806		*curr_state = (c_state == MSG_DEVICE_HW_STATE_OFF);
 807
 808	return 0;
 809}
 810
 811/**
 812 * ti_sci_cmd_dev_is_on() - Check if the device is requested to be ON
 813 * @handle:	Pointer to TISCI handle
 814 * @id:		Device Identifier
 815 * @r_state:	true if requested to be ON
 816 * @curr_state:	true if currently ON and active
 817 *
 818 * Return: 0 if all went fine, else return appropriate error.
 819 */
 820static int ti_sci_cmd_dev_is_on(const struct ti_sci_handle *handle, u32 id,
 821				bool *r_state,  bool *curr_state)
 822{
 823	int ret;
 824	u8 p_state, c_state;
 825
 826	if (!r_state && !curr_state)
 827		return -EINVAL;
 828
 829	ret =
 830	    ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state);
 831	if (ret)
 832		return ret;
 833
 834	if (r_state)
 835		*r_state = (p_state == MSG_DEVICE_SW_STATE_ON);
 836	if (curr_state)
 837		*curr_state = (c_state == MSG_DEVICE_HW_STATE_ON);
 838
 839	return 0;
 840}
 841
 842/**
 843 * ti_sci_cmd_dev_is_trans() - Check if the device is currently transitioning
 844 * @handle:	Pointer to TISCI handle
 845 * @id:		Device Identifier
 846 * @curr_state:	true if currently transitioning.
 847 *
 848 * Return: 0 if all went fine, else return appropriate error.
 849 */
 850static int ti_sci_cmd_dev_is_trans(const struct ti_sci_handle *handle, u32 id,
 851				   bool *curr_state)
 852{
 853	int ret;
 854	u8 state;
 855
 856	if (!curr_state)
 857		return -EINVAL;
 858
 859	ret = ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &state);
 860	if (ret)
 861		return ret;
 862
 863	*curr_state = (state == MSG_DEVICE_HW_STATE_TRANS);
 864
 865	return 0;
 866}
 867
 868/**
 869 * ti_sci_cmd_set_device_resets() - command to set resets for device managed
 870 *				    by TISCI
 871 * @handle:	Pointer to TISCI handle as retrieved by *ti_sci_get_handle
 872 * @id:		Device Identifier
 873 * @reset_state: Device specific reset bit field
 874 *
 875 * Return: 0 if all went fine, else return appropriate error.
 876 */
 877static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle,
 878					u32 id, u32 reset_state)
 879{
 880	struct ti_sci_info *info;
 881	struct ti_sci_msg_req_set_device_resets *req;
 882	struct ti_sci_msg_hdr *resp;
 883	struct ti_sci_xfer *xfer;
 884	struct device *dev;
 885	int ret = 0;
 886
 887	if (IS_ERR(handle))
 888		return PTR_ERR(handle);
 889	if (!handle)
 890		return -EINVAL;
 891
 892	info = handle_to_ti_sci_info(handle);
 893	dev = info->dev;
 894
 895	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_DEVICE_RESETS,
 896				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
 897				   sizeof(*req), sizeof(*resp));
 898	if (IS_ERR(xfer)) {
 899		ret = PTR_ERR(xfer);
 900		dev_err(dev, "Message alloc failed(%d)\n", ret);
 901		return ret;
 902	}
 903	req = (struct ti_sci_msg_req_set_device_resets *)xfer->xfer_buf;
 904	req->id = id;
 905	req->resets = reset_state;
 906
 907	ret = ti_sci_do_xfer(info, xfer);
 908	if (ret) {
 909		dev_err(dev, "Mbox send fail %d\n", ret);
 910		goto fail;
 911	}
 912
 913	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
 914
 915	ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
 916
 917fail:
 918	ti_sci_put_one_xfer(&info->minfo, xfer);
 919
 920	return ret;
 921}
 922
 923/**
 924 * ti_sci_cmd_get_device_resets() - Get reset state for device managed
 925 *				    by TISCI
 926 * @handle:		Pointer to TISCI handle
 927 * @id:			Device Identifier
 928 * @reset_state:	Pointer to reset state to populate
 929 *
 930 * Return: 0 if all went fine, else return appropriate error.
 931 */
 932static int ti_sci_cmd_get_device_resets(const struct ti_sci_handle *handle,
 933					u32 id, u32 *reset_state)
 934{
 935	return ti_sci_get_device_state(handle, id, NULL, reset_state, NULL,
 936				       NULL);
 937}
 938
 939/**
 940 * ti_sci_set_clock_state() - Set clock state helper
 941 * @handle:	pointer to TI SCI handle
 942 * @dev_id:	Device identifier this request is for
 943 * @clk_id:	Clock identifier for the device for this request.
 944 *		Each device has it's own set of clock inputs. This indexes
 945 *		which clock input to modify.
 946 * @flags:	Header flags as needed
 947 * @state:	State to request for the clock.
 948 *
 949 * Return: 0 if all went well, else returns appropriate error value.
 950 */
 951static int ti_sci_set_clock_state(const struct ti_sci_handle *handle,
 952				  u32 dev_id, u32 clk_id,
 953				  u32 flags, u8 state)
 954{
 955	struct ti_sci_info *info;
 956	struct ti_sci_msg_req_set_clock_state *req;
 957	struct ti_sci_msg_hdr *resp;
 958	struct ti_sci_xfer *xfer;
 959	struct device *dev;
 960	int ret = 0;
 961
 962	if (IS_ERR(handle))
 963		return PTR_ERR(handle);
 964	if (!handle)
 965		return -EINVAL;
 966
 967	info = handle_to_ti_sci_info(handle);
 968	dev = info->dev;
 969
 970	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CLOCK_STATE,
 971				   flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
 972				   sizeof(*req), sizeof(*resp));
 973	if (IS_ERR(xfer)) {
 974		ret = PTR_ERR(xfer);
 975		dev_err(dev, "Message alloc failed(%d)\n", ret);
 976		return ret;
 977	}
 978	req = (struct ti_sci_msg_req_set_clock_state *)xfer->xfer_buf;
 979	req->dev_id = dev_id;
 980	if (clk_id < 255) {
 981		req->clk_id = clk_id;
 982	} else {
 983		req->clk_id = 255;
 984		req->clk_id_32 = clk_id;
 985	}
 986	req->request_state = state;
 987
 988	ret = ti_sci_do_xfer(info, xfer);
 989	if (ret) {
 990		dev_err(dev, "Mbox send fail %d\n", ret);
 991		goto fail;
 992	}
 993
 994	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
 995
 996	ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
 997
 998fail:
 999	ti_sci_put_one_xfer(&info->minfo, xfer);
1000
1001	return ret;
1002}
1003
1004/**
1005 * ti_sci_cmd_get_clock_state() - Get clock state helper
1006 * @handle:	pointer to TI SCI handle
1007 * @dev_id:	Device identifier this request is for
1008 * @clk_id:	Clock identifier for the device for this request.
1009 *		Each device has it's own set of clock inputs. This indexes
1010 *		which clock input to modify.
1011 * @programmed_state:	State requested for clock to move to
1012 * @current_state:	State that the clock is currently in
1013 *
1014 * Return: 0 if all went well, else returns appropriate error value.
1015 */
1016static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle,
1017				      u32 dev_id, u32 clk_id,
1018				      u8 *programmed_state, u8 *current_state)
1019{
1020	struct ti_sci_info *info;
1021	struct ti_sci_msg_req_get_clock_state *req;
1022	struct ti_sci_msg_resp_get_clock_state *resp;
1023	struct ti_sci_xfer *xfer;
1024	struct device *dev;
1025	int ret = 0;
1026
1027	if (IS_ERR(handle))
1028		return PTR_ERR(handle);
1029	if (!handle)
1030		return -EINVAL;
1031
1032	if (!programmed_state && !current_state)
1033		return -EINVAL;
1034
1035	info = handle_to_ti_sci_info(handle);
1036	dev = info->dev;
1037
1038	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_CLOCK_STATE,
1039				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1040				   sizeof(*req), sizeof(*resp));
1041	if (IS_ERR(xfer)) {
1042		ret = PTR_ERR(xfer);
1043		dev_err(dev, "Message alloc failed(%d)\n", ret);
1044		return ret;
1045	}
1046	req = (struct ti_sci_msg_req_get_clock_state *)xfer->xfer_buf;
1047	req->dev_id = dev_id;
1048	if (clk_id < 255) {
1049		req->clk_id = clk_id;
1050	} else {
1051		req->clk_id = 255;
1052		req->clk_id_32 = clk_id;
1053	}
1054
1055	ret = ti_sci_do_xfer(info, xfer);
1056	if (ret) {
1057		dev_err(dev, "Mbox send fail %d\n", ret);
1058		goto fail;
1059	}
1060
1061	resp = (struct ti_sci_msg_resp_get_clock_state *)xfer->xfer_buf;
1062
1063	if (!ti_sci_is_response_ack(resp)) {
1064		ret = -ENODEV;
1065		goto fail;
1066	}
1067
1068	if (programmed_state)
1069		*programmed_state = resp->programmed_state;
1070	if (current_state)
1071		*current_state = resp->current_state;
1072
1073fail:
1074	ti_sci_put_one_xfer(&info->minfo, xfer);
1075
1076	return ret;
1077}
1078
1079/**
1080 * ti_sci_cmd_get_clock() - Get control of a clock from TI SCI
1081 * @handle:	pointer to TI SCI handle
1082 * @dev_id:	Device identifier this request is for
1083 * @clk_id:	Clock identifier for the device for this request.
1084 *		Each device has it's own set of clock inputs. This indexes
1085 *		which clock input to modify.
1086 * @needs_ssc: 'true' if Spread Spectrum clock is desired, else 'false'
1087 * @can_change_freq: 'true' if frequency change is desired, else 'false'
1088 * @enable_input_term: 'true' if input termination is desired, else 'false'
1089 *
1090 * Return: 0 if all went well, else returns appropriate error value.
1091 */
1092static int ti_sci_cmd_get_clock(const struct ti_sci_handle *handle, u32 dev_id,
1093				u32 clk_id, bool needs_ssc,
1094				bool can_change_freq, bool enable_input_term)
1095{
1096	u32 flags = 0;
1097
1098	flags |= needs_ssc ? MSG_FLAG_CLOCK_ALLOW_SSC : 0;
1099	flags |= can_change_freq ? MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE : 0;
1100	flags |= enable_input_term ? MSG_FLAG_CLOCK_INPUT_TERM : 0;
1101
1102	return ti_sci_set_clock_state(handle, dev_id, clk_id, flags,
1103				      MSG_CLOCK_SW_STATE_REQ);
1104}
1105
1106/**
1107 * ti_sci_cmd_idle_clock() - Idle a clock which is in our control
1108 * @handle:	pointer to TI SCI handle
1109 * @dev_id:	Device identifier this request is for
1110 * @clk_id:	Clock identifier for the device for this request.
1111 *		Each device has it's own set of clock inputs. This indexes
1112 *		which clock input to modify.
1113 *
1114 * NOTE: This clock must have been requested by get_clock previously.
1115 *
1116 * Return: 0 if all went well, else returns appropriate error value.
1117 */
1118static int ti_sci_cmd_idle_clock(const struct ti_sci_handle *handle,
1119				 u32 dev_id, u32 clk_id)
1120{
1121	return ti_sci_set_clock_state(handle, dev_id, clk_id,
1122				      MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE,
1123				      MSG_CLOCK_SW_STATE_UNREQ);
1124}
1125
1126/**
1127 * ti_sci_cmd_put_clock() - Release a clock from our control back to TISCI
1128 * @handle:	pointer to TI SCI handle
1129 * @dev_id:	Device identifier this request is for
1130 * @clk_id:	Clock identifier for the device for this request.
1131 *		Each device has it's own set of clock inputs. This indexes
1132 *		which clock input to modify.
1133 *
1134 * NOTE: This clock must have been requested by get_clock previously.
1135 *
1136 * Return: 0 if all went well, else returns appropriate error value.
1137 */
1138static int ti_sci_cmd_put_clock(const struct ti_sci_handle *handle,
1139				u32 dev_id, u32 clk_id)
1140{
1141	return ti_sci_set_clock_state(handle, dev_id, clk_id,
1142				      MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE,
1143				      MSG_CLOCK_SW_STATE_AUTO);
1144}
1145
1146/**
1147 * ti_sci_cmd_clk_is_auto() - Is the clock being auto managed
1148 * @handle:	pointer to TI SCI handle
1149 * @dev_id:	Device identifier this request is for
1150 * @clk_id:	Clock identifier for the device for this request.
1151 *		Each device has it's own set of clock inputs. This indexes
1152 *		which clock input to modify.
1153 * @req_state: state indicating if the clock is auto managed
1154 *
1155 * Return: 0 if all went well, else returns appropriate error value.
1156 */
1157static int ti_sci_cmd_clk_is_auto(const struct ti_sci_handle *handle,
1158				  u32 dev_id, u32 clk_id, bool *req_state)
1159{
1160	u8 state = 0;
1161	int ret;
1162
1163	if (!req_state)
1164		return -EINVAL;
1165
1166	ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, &state, NULL);
1167	if (ret)
1168		return ret;
1169
1170	*req_state = (state == MSG_CLOCK_SW_STATE_AUTO);
1171	return 0;
1172}
1173
1174/**
1175 * ti_sci_cmd_clk_is_on() - Is the clock ON
1176 * @handle:	pointer to TI SCI handle
1177 * @dev_id:	Device identifier this request is for
1178 * @clk_id:	Clock identifier for the device for this request.
1179 *		Each device has it's own set of clock inputs. This indexes
1180 *		which clock input to modify.
1181 * @req_state: state indicating if the clock is managed by us and enabled
1182 * @curr_state: state indicating if the clock is ready for operation
1183 *
1184 * Return: 0 if all went well, else returns appropriate error value.
1185 */
1186static int ti_sci_cmd_clk_is_on(const struct ti_sci_handle *handle, u32 dev_id,
1187				u32 clk_id, bool *req_state, bool *curr_state)
1188{
1189	u8 c_state = 0, r_state = 0;
1190	int ret;
1191
1192	if (!req_state && !curr_state)
1193		return -EINVAL;
1194
1195	ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
1196					 &r_state, &c_state);
1197	if (ret)
1198		return ret;
1199
1200	if (req_state)
1201		*req_state = (r_state == MSG_CLOCK_SW_STATE_REQ);
1202	if (curr_state)
1203		*curr_state = (c_state == MSG_CLOCK_HW_STATE_READY);
1204	return 0;
1205}
1206
1207/**
1208 * ti_sci_cmd_clk_is_off() - Is the clock OFF
1209 * @handle:	pointer to TI SCI handle
1210 * @dev_id:	Device identifier this request is for
1211 * @clk_id:	Clock identifier for the device for this request.
1212 *		Each device has it's own set of clock inputs. This indexes
1213 *		which clock input to modify.
1214 * @req_state: state indicating if the clock is managed by us and disabled
1215 * @curr_state: state indicating if the clock is NOT ready for operation
1216 *
1217 * Return: 0 if all went well, else returns appropriate error value.
1218 */
1219static int ti_sci_cmd_clk_is_off(const struct ti_sci_handle *handle, u32 dev_id,
1220				 u32 clk_id, bool *req_state, bool *curr_state)
1221{
1222	u8 c_state = 0, r_state = 0;
1223	int ret;
1224
1225	if (!req_state && !curr_state)
1226		return -EINVAL;
1227
1228	ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
1229					 &r_state, &c_state);
1230	if (ret)
1231		return ret;
1232
1233	if (req_state)
1234		*req_state = (r_state == MSG_CLOCK_SW_STATE_UNREQ);
1235	if (curr_state)
1236		*curr_state = (c_state == MSG_CLOCK_HW_STATE_NOT_READY);
1237	return 0;
1238}
1239
1240/**
1241 * ti_sci_cmd_clk_set_parent() - Set the clock source of a specific device clock
1242 * @handle:	pointer to TI SCI handle
1243 * @dev_id:	Device identifier this request is for
1244 * @clk_id:	Clock identifier for the device for this request.
1245 *		Each device has it's own set of clock inputs. This indexes
1246 *		which clock input to modify.
1247 * @parent_id:	Parent clock identifier to set
1248 *
1249 * Return: 0 if all went well, else returns appropriate error value.
1250 */
1251static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle,
1252				     u32 dev_id, u32 clk_id, u32 parent_id)
1253{
1254	struct ti_sci_info *info;
1255	struct ti_sci_msg_req_set_clock_parent *req;
1256	struct ti_sci_msg_hdr *resp;
1257	struct ti_sci_xfer *xfer;
1258	struct device *dev;
1259	int ret = 0;
1260
1261	if (IS_ERR(handle))
1262		return PTR_ERR(handle);
1263	if (!handle)
1264		return -EINVAL;
1265
1266	info = handle_to_ti_sci_info(handle);
1267	dev = info->dev;
1268
1269	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CLOCK_PARENT,
1270				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1271				   sizeof(*req), sizeof(*resp));
1272	if (IS_ERR(xfer)) {
1273		ret = PTR_ERR(xfer);
1274		dev_err(dev, "Message alloc failed(%d)\n", ret);
1275		return ret;
1276	}
1277	req = (struct ti_sci_msg_req_set_clock_parent *)xfer->xfer_buf;
1278	req->dev_id = dev_id;
1279	if (clk_id < 255) {
1280		req->clk_id = clk_id;
1281	} else {
1282		req->clk_id = 255;
1283		req->clk_id_32 = clk_id;
1284	}
1285	if (parent_id < 255) {
1286		req->parent_id = parent_id;
1287	} else {
1288		req->parent_id = 255;
1289		req->parent_id_32 = parent_id;
1290	}
1291
1292	ret = ti_sci_do_xfer(info, xfer);
1293	if (ret) {
1294		dev_err(dev, "Mbox send fail %d\n", ret);
1295		goto fail;
1296	}
1297
1298	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
1299
1300	ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
1301
1302fail:
1303	ti_sci_put_one_xfer(&info->minfo, xfer);
1304
1305	return ret;
1306}
1307
1308/**
1309 * ti_sci_cmd_clk_get_parent() - Get current parent clock source
1310 * @handle:	pointer to TI SCI handle
1311 * @dev_id:	Device identifier this request is for
1312 * @clk_id:	Clock identifier for the device for this request.
1313 *		Each device has it's own set of clock inputs. This indexes
1314 *		which clock input to modify.
1315 * @parent_id:	Current clock parent
1316 *
1317 * Return: 0 if all went well, else returns appropriate error value.
1318 */
1319static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle,
1320				     u32 dev_id, u32 clk_id, u32 *parent_id)
1321{
1322	struct ti_sci_info *info;
1323	struct ti_sci_msg_req_get_clock_parent *req;
1324	struct ti_sci_msg_resp_get_clock_parent *resp;
1325	struct ti_sci_xfer *xfer;
1326	struct device *dev;
1327	int ret = 0;
1328
1329	if (IS_ERR(handle))
1330		return PTR_ERR(handle);
1331	if (!handle || !parent_id)
1332		return -EINVAL;
1333
1334	info = handle_to_ti_sci_info(handle);
1335	dev = info->dev;
1336
1337	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_CLOCK_PARENT,
1338				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1339				   sizeof(*req), sizeof(*resp));
1340	if (IS_ERR(xfer)) {
1341		ret = PTR_ERR(xfer);
1342		dev_err(dev, "Message alloc failed(%d)\n", ret);
1343		return ret;
1344	}
1345	req = (struct ti_sci_msg_req_get_clock_parent *)xfer->xfer_buf;
1346	req->dev_id = dev_id;
1347	if (clk_id < 255) {
1348		req->clk_id = clk_id;
1349	} else {
1350		req->clk_id = 255;
1351		req->clk_id_32 = clk_id;
1352	}
1353
1354	ret = ti_sci_do_xfer(info, xfer);
1355	if (ret) {
1356		dev_err(dev, "Mbox send fail %d\n", ret);
1357		goto fail;
1358	}
1359
1360	resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->xfer_buf;
1361
1362	if (!ti_sci_is_response_ack(resp)) {
1363		ret = -ENODEV;
1364	} else {
1365		if (resp->parent_id < 255)
1366			*parent_id = resp->parent_id;
1367		else
1368			*parent_id = resp->parent_id_32;
1369	}
1370
1371fail:
1372	ti_sci_put_one_xfer(&info->minfo, xfer);
1373
1374	return ret;
1375}
1376
1377/**
1378 * ti_sci_cmd_clk_get_num_parents() - Get num parents of the current clk source
1379 * @handle:	pointer to TI SCI handle
1380 * @dev_id:	Device identifier this request is for
1381 * @clk_id:	Clock identifier for the device for this request.
1382 *		Each device has it's own set of clock inputs. This indexes
1383 *		which clock input to modify.
1384 * @num_parents: Returns he number of parents to the current clock.
1385 *
1386 * Return: 0 if all went well, else returns appropriate error value.
1387 */
1388static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle,
1389					  u32 dev_id, u32 clk_id,
1390					  u32 *num_parents)
1391{
1392	struct ti_sci_info *info;
1393	struct ti_sci_msg_req_get_clock_num_parents *req;
1394	struct ti_sci_msg_resp_get_clock_num_parents *resp;
1395	struct ti_sci_xfer *xfer;
1396	struct device *dev;
1397	int ret = 0;
1398
1399	if (IS_ERR(handle))
1400		return PTR_ERR(handle);
1401	if (!handle || !num_parents)
1402		return -EINVAL;
1403
1404	info = handle_to_ti_sci_info(handle);
1405	dev = info->dev;
1406
1407	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_NUM_CLOCK_PARENTS,
1408				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1409				   sizeof(*req), sizeof(*resp));
1410	if (IS_ERR(xfer)) {
1411		ret = PTR_ERR(xfer);
1412		dev_err(dev, "Message alloc failed(%d)\n", ret);
1413		return ret;
1414	}
1415	req = (struct ti_sci_msg_req_get_clock_num_parents *)xfer->xfer_buf;
1416	req->dev_id = dev_id;
1417	if (clk_id < 255) {
1418		req->clk_id = clk_id;
1419	} else {
1420		req->clk_id = 255;
1421		req->clk_id_32 = clk_id;
1422	}
1423
1424	ret = ti_sci_do_xfer(info, xfer);
1425	if (ret) {
1426		dev_err(dev, "Mbox send fail %d\n", ret);
1427		goto fail;
1428	}
1429
1430	resp = (struct ti_sci_msg_resp_get_clock_num_parents *)xfer->xfer_buf;
1431
1432	if (!ti_sci_is_response_ack(resp)) {
1433		ret = -ENODEV;
1434	} else {
1435		if (resp->num_parents < 255)
1436			*num_parents = resp->num_parents;
1437		else
1438			*num_parents = resp->num_parents_32;
1439	}
1440
1441fail:
1442	ti_sci_put_one_xfer(&info->minfo, xfer);
1443
1444	return ret;
1445}
1446
1447/**
1448 * ti_sci_cmd_clk_get_match_freq() - Find a good match for frequency
1449 * @handle:	pointer to TI SCI handle
1450 * @dev_id:	Device identifier this request is for
1451 * @clk_id:	Clock identifier for the device for this request.
1452 *		Each device has it's own set of clock inputs. This indexes
1453 *		which clock input to modify.
1454 * @min_freq:	The minimum allowable frequency in Hz. This is the minimum
1455 *		allowable programmed frequency and does not account for clock
1456 *		tolerances and jitter.
1457 * @target_freq: The target clock frequency in Hz. A frequency will be
1458 *		processed as close to this target frequency as possible.
1459 * @max_freq:	The maximum allowable frequency in Hz. This is the maximum
1460 *		allowable programmed frequency and does not account for clock
1461 *		tolerances and jitter.
1462 * @match_freq:	Frequency match in Hz response.
1463 *
1464 * Return: 0 if all went well, else returns appropriate error value.
1465 */
1466static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle,
1467					 u32 dev_id, u32 clk_id, u64 min_freq,
1468					 u64 target_freq, u64 max_freq,
1469					 u64 *match_freq)
1470{
1471	struct ti_sci_info *info;
1472	struct ti_sci_msg_req_query_clock_freq *req;
1473	struct ti_sci_msg_resp_query_clock_freq *resp;
1474	struct ti_sci_xfer *xfer;
1475	struct device *dev;
1476	int ret = 0;
1477
1478	if (IS_ERR(handle))
1479		return PTR_ERR(handle);
1480	if (!handle || !match_freq)
1481		return -EINVAL;
1482
1483	info = handle_to_ti_sci_info(handle);
1484	dev = info->dev;
1485
1486	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_QUERY_CLOCK_FREQ,
1487				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1488				   sizeof(*req), sizeof(*resp));
1489	if (IS_ERR(xfer)) {
1490		ret = PTR_ERR(xfer);
1491		dev_err(dev, "Message alloc failed(%d)\n", ret);
1492		return ret;
1493	}
1494	req = (struct ti_sci_msg_req_query_clock_freq *)xfer->xfer_buf;
1495	req->dev_id = dev_id;
1496	if (clk_id < 255) {
1497		req->clk_id = clk_id;
1498	} else {
1499		req->clk_id = 255;
1500		req->clk_id_32 = clk_id;
1501	}
1502	req->min_freq_hz = min_freq;
1503	req->target_freq_hz = target_freq;
1504	req->max_freq_hz = max_freq;
1505
1506	ret = ti_sci_do_xfer(info, xfer);
1507	if (ret) {
1508		dev_err(dev, "Mbox send fail %d\n", ret);
1509		goto fail;
1510	}
1511
1512	resp = (struct ti_sci_msg_resp_query_clock_freq *)xfer->xfer_buf;
1513
1514	if (!ti_sci_is_response_ack(resp))
1515		ret = -ENODEV;
1516	else
1517		*match_freq = resp->freq_hz;
1518
1519fail:
1520	ti_sci_put_one_xfer(&info->minfo, xfer);
1521
1522	return ret;
1523}
1524
1525/**
1526 * ti_sci_cmd_clk_set_freq() - Set a frequency for clock
1527 * @handle:	pointer to TI SCI handle
1528 * @dev_id:	Device identifier this request is for
1529 * @clk_id:	Clock identifier for the device for this request.
1530 *		Each device has it's own set of clock inputs. This indexes
1531 *		which clock input to modify.
1532 * @min_freq:	The minimum allowable frequency in Hz. This is the minimum
1533 *		allowable programmed frequency and does not account for clock
1534 *		tolerances and jitter.
1535 * @target_freq: The target clock frequency in Hz. A frequency will be
1536 *		processed as close to this target frequency as possible.
1537 * @max_freq:	The maximum allowable frequency in Hz. This is the maximum
1538 *		allowable programmed frequency and does not account for clock
1539 *		tolerances and jitter.
1540 *
1541 * Return: 0 if all went well, else returns appropriate error value.
1542 */
1543static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle,
1544				   u32 dev_id, u32 clk_id, u64 min_freq,
1545				   u64 target_freq, u64 max_freq)
1546{
1547	struct ti_sci_info *info;
1548	struct ti_sci_msg_req_set_clock_freq *req;
1549	struct ti_sci_msg_hdr *resp;
1550	struct ti_sci_xfer *xfer;
1551	struct device *dev;
1552	int ret = 0;
1553
1554	if (IS_ERR(handle))
1555		return PTR_ERR(handle);
1556	if (!handle)
1557		return -EINVAL;
1558
1559	info = handle_to_ti_sci_info(handle);
1560	dev = info->dev;
1561
1562	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CLOCK_FREQ,
1563				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1564				   sizeof(*req), sizeof(*resp));
1565	if (IS_ERR(xfer)) {
1566		ret = PTR_ERR(xfer);
1567		dev_err(dev, "Message alloc failed(%d)\n", ret);
1568		return ret;
1569	}
1570	req = (struct ti_sci_msg_req_set_clock_freq *)xfer->xfer_buf;
1571	req->dev_id = dev_id;
1572	if (clk_id < 255) {
1573		req->clk_id = clk_id;
1574	} else {
1575		req->clk_id = 255;
1576		req->clk_id_32 = clk_id;
1577	}
1578	req->min_freq_hz = min_freq;
1579	req->target_freq_hz = target_freq;
1580	req->max_freq_hz = max_freq;
1581
1582	ret = ti_sci_do_xfer(info, xfer);
1583	if (ret) {
1584		dev_err(dev, "Mbox send fail %d\n", ret);
1585		goto fail;
1586	}
1587
1588	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
1589
1590	ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
1591
1592fail:
1593	ti_sci_put_one_xfer(&info->minfo, xfer);
1594
1595	return ret;
1596}
1597
1598/**
1599 * ti_sci_cmd_clk_get_freq() - Get current frequency
1600 * @handle:	pointer to TI SCI handle
1601 * @dev_id:	Device identifier this request is for
1602 * @clk_id:	Clock identifier for the device for this request.
1603 *		Each device has it's own set of clock inputs. This indexes
1604 *		which clock input to modify.
1605 * @freq:	Currently frequency in Hz
1606 *
1607 * Return: 0 if all went well, else returns appropriate error value.
1608 */
1609static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle,
1610				   u32 dev_id, u32 clk_id, u64 *freq)
1611{
1612	struct ti_sci_info *info;
1613	struct ti_sci_msg_req_get_clock_freq *req;
1614	struct ti_sci_msg_resp_get_clock_freq *resp;
1615	struct ti_sci_xfer *xfer;
1616	struct device *dev;
1617	int ret = 0;
1618
1619	if (IS_ERR(handle))
1620		return PTR_ERR(handle);
1621	if (!handle || !freq)
1622		return -EINVAL;
1623
1624	info = handle_to_ti_sci_info(handle);
1625	dev = info->dev;
1626
1627	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_CLOCK_FREQ,
1628				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1629				   sizeof(*req), sizeof(*resp));
1630	if (IS_ERR(xfer)) {
1631		ret = PTR_ERR(xfer);
1632		dev_err(dev, "Message alloc failed(%d)\n", ret);
1633		return ret;
1634	}
1635	req = (struct ti_sci_msg_req_get_clock_freq *)xfer->xfer_buf;
1636	req->dev_id = dev_id;
1637	if (clk_id < 255) {
1638		req->clk_id = clk_id;
1639	} else {
1640		req->clk_id = 255;
1641		req->clk_id_32 = clk_id;
1642	}
1643
1644	ret = ti_sci_do_xfer(info, xfer);
1645	if (ret) {
1646		dev_err(dev, "Mbox send fail %d\n", ret);
1647		goto fail;
1648	}
1649
1650	resp = (struct ti_sci_msg_resp_get_clock_freq *)xfer->xfer_buf;
1651
1652	if (!ti_sci_is_response_ack(resp))
1653		ret = -ENODEV;
1654	else
1655		*freq = resp->freq_hz;
1656
1657fail:
1658	ti_sci_put_one_xfer(&info->minfo, xfer);
1659
1660	return ret;
1661}
1662
1663/**
1664 * ti_sci_cmd_prepare_sleep() - Prepare system for system suspend
1665 * @handle:		pointer to TI SCI handle
1666 * @mode:		Device identifier
1667 * @ctx_lo:		Low part of address for context save
1668 * @ctx_hi:		High part of address for context save
1669 * @debug_flags:	Debug flags to pass to firmware
1670 *
1671 * Return: 0 if all went well, else returns appropriate error value.
1672 */
1673static int ti_sci_cmd_prepare_sleep(const struct ti_sci_handle *handle, u8 mode,
1674				    u32 ctx_lo, u32 ctx_hi, u32 debug_flags)
1675{
1676	u32 msg_flags = mode == TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO ?
1677			TI_SCI_FLAG_REQ_GENERIC_NORESPONSE :
1678			TI_SCI_FLAG_REQ_ACK_ON_PROCESSED;
1679	struct ti_sci_info *info;
1680	struct ti_sci_msg_req_prepare_sleep *req;
1681	struct ti_sci_msg_hdr *resp;
1682	struct ti_sci_xfer *xfer;
1683	struct device *dev;
1684	int ret = 0;
1685
1686	if (IS_ERR(handle))
1687		return PTR_ERR(handle);
1688	if (!handle)
1689		return -EINVAL;
1690
1691	info = handle_to_ti_sci_info(handle);
1692	dev = info->dev;
1693
1694	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PREPARE_SLEEP,
1695				   msg_flags,
1696				   sizeof(*req), sizeof(*resp));
1697	if (IS_ERR(xfer)) {
1698		ret = PTR_ERR(xfer);
1699		dev_err(dev, "Message alloc failed(%d)\n", ret);
1700		return ret;
1701	}
1702
1703	req = (struct ti_sci_msg_req_prepare_sleep *)xfer->xfer_buf;
1704	req->mode = mode;
1705	req->ctx_lo = ctx_lo;
1706	req->ctx_hi = ctx_hi;
1707	req->debug_flags = debug_flags;
1708
1709	ret = ti_sci_do_xfer(info, xfer);
1710	if (ret) {
1711		dev_err(dev, "Mbox send fail %d\n", ret);
1712		goto fail;
1713	}
1714
1715	if (msg_flags == TI_SCI_FLAG_REQ_ACK_ON_PROCESSED) {
1716		resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
1717		if (!ti_sci_is_response_ack(resp)) {
1718			dev_err(dev, "Failed to prepare sleep\n");
1719			ret = -ENODEV;
1720		}
1721	}
1722
1723fail:
1724	ti_sci_put_one_xfer(&info->minfo, xfer);
1725
1726	return ret;
1727}
1728
1729/**
1730 * ti_sci_msg_cmd_query_fw_caps() - Get the FW/SoC capabilities
1731 * @handle:		Pointer to TI SCI handle
1732 * @fw_caps:		Each bit in fw_caps indicating one FW/SOC capability
1733 *
1734 * Check if the firmware supports any optional low power modes.
1735 * Old revisions of TIFS (< 08.04) will NACK the request which results in
1736 * -ENODEV being returned.
1737 *
1738 * Return: 0 if all went well, else returns appropriate error value.
1739 */
1740static int ti_sci_msg_cmd_query_fw_caps(const struct ti_sci_handle *handle,
1741					u64 *fw_caps)
1742{
1743	struct ti_sci_info *info;
1744	struct ti_sci_xfer *xfer;
1745	struct ti_sci_msg_resp_query_fw_caps *resp;
1746	struct device *dev;
1747	int ret = 0;
1748
1749	if (IS_ERR(handle))
1750		return PTR_ERR(handle);
1751	if (!handle)
1752		return -EINVAL;
1753
1754	info = handle_to_ti_sci_info(handle);
1755	dev = info->dev;
1756
1757	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_QUERY_FW_CAPS,
1758				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1759				   sizeof(struct ti_sci_msg_hdr),
1760				   sizeof(*resp));
1761	if (IS_ERR(xfer)) {
1762		ret = PTR_ERR(xfer);
1763		dev_err(dev, "Message alloc failed(%d)\n", ret);
1764		return ret;
1765	}
1766
1767	ret = ti_sci_do_xfer(info, xfer);
1768	if (ret) {
1769		dev_err(dev, "Mbox send fail %d\n", ret);
1770		goto fail;
1771	}
1772
1773	resp = (struct ti_sci_msg_resp_query_fw_caps *)xfer->xfer_buf;
1774
1775	if (!ti_sci_is_response_ack(resp)) {
1776		dev_err(dev, "Failed to get capabilities\n");
1777		ret = -ENODEV;
1778		goto fail;
1779	}
1780
1781	if (fw_caps)
1782		*fw_caps = resp->fw_caps;
1783
1784fail:
1785	ti_sci_put_one_xfer(&info->minfo, xfer);
1786
1787	return ret;
1788}
1789
1790/**
1791 * ti_sci_cmd_set_io_isolation() - Enable IO isolation in LPM
1792 * @handle:		Pointer to TI SCI handle
1793 * @state:		The desired state of the IO isolation
1794 *
1795 * Return: 0 if all went well, else returns appropriate error value.
1796 */
1797static int ti_sci_cmd_set_io_isolation(const struct ti_sci_handle *handle,
1798				       u8 state)
1799{
1800	struct ti_sci_info *info;
1801	struct ti_sci_msg_req_set_io_isolation *req;
1802	struct ti_sci_msg_hdr *resp;
1803	struct ti_sci_xfer *xfer;
1804	struct device *dev;
1805	int ret = 0;
1806
1807	if (IS_ERR(handle))
1808		return PTR_ERR(handle);
1809	if (!handle)
1810		return -EINVAL;
1811
1812	info = handle_to_ti_sci_info(handle);
1813	dev = info->dev;
1814
1815	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_IO_ISOLATION,
1816				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1817				   sizeof(*req), sizeof(*resp));
1818	if (IS_ERR(xfer)) {
1819		ret = PTR_ERR(xfer);
1820		dev_err(dev, "Message alloc failed(%d)\n", ret);
1821		return ret;
1822	}
1823	req = (struct ti_sci_msg_req_set_io_isolation *)xfer->xfer_buf;
1824	req->state = state;
1825
1826	ret = ti_sci_do_xfer(info, xfer);
1827	if (ret) {
1828		dev_err(dev, "Mbox send fail %d\n", ret);
1829		goto fail;
1830	}
1831
1832	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
1833
1834	if (!ti_sci_is_response_ack(resp)) {
1835		dev_err(dev, "Failed to set IO isolation\n");
1836		ret = -ENODEV;
1837	}
1838
1839fail:
1840	ti_sci_put_one_xfer(&info->minfo, xfer);
1841
1842	return ret;
1843}
1844
1845/**
1846 * ti_sci_msg_cmd_lpm_wake_reason() - Get the wakeup source from LPM
1847 * @handle:		Pointer to TI SCI handle
1848 * @source:		The wakeup source that woke the SoC from LPM
1849 * @timestamp:		Timestamp of the wakeup event
1850 * @pin:		The pin that has triggered wake up
1851 * @mode:		The last entered low power mode
1852 *
1853 * Return: 0 if all went well, else returns appropriate error value.
1854 */
1855static int ti_sci_msg_cmd_lpm_wake_reason(const struct ti_sci_handle *handle,
1856					  u32 *source, u64 *timestamp, u8 *pin, u8 *mode)
1857{
1858	struct ti_sci_info *info;
1859	struct ti_sci_xfer *xfer;
1860	struct ti_sci_msg_resp_lpm_wake_reason *resp;
1861	struct device *dev;
1862	int ret = 0;
1863
1864	if (IS_ERR(handle))
1865		return PTR_ERR(handle);
1866	if (!handle)
1867		return -EINVAL;
1868
1869	info = handle_to_ti_sci_info(handle);
1870	dev = info->dev;
1871
1872	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_WAKE_REASON,
1873				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1874				   sizeof(struct ti_sci_msg_hdr),
1875				   sizeof(*resp));
1876	if (IS_ERR(xfer)) {
1877		ret = PTR_ERR(xfer);
1878		dev_err(dev, "Message alloc failed(%d)\n", ret);
1879		return ret;
1880	}
1881
1882	ret = ti_sci_do_xfer(info, xfer);
1883	if (ret) {
1884		dev_err(dev, "Mbox send fail %d\n", ret);
1885		goto fail;
1886	}
1887
1888	resp = (struct ti_sci_msg_resp_lpm_wake_reason *)xfer->xfer_buf;
1889
1890	if (!ti_sci_is_response_ack(resp)) {
1891		dev_err(dev, "Failed to get wake reason\n");
1892		ret = -ENODEV;
1893		goto fail;
1894	}
1895
1896	if (source)
1897		*source = resp->wake_source;
1898	if (timestamp)
1899		*timestamp = resp->wake_timestamp;
1900	if (pin)
1901		*pin = resp->wake_pin;
1902	if (mode)
1903		*mode = resp->mode;
1904
1905fail:
1906	ti_sci_put_one_xfer(&info->minfo, xfer);
1907
1908	return ret;
1909}
1910
1911/**
1912 * ti_sci_cmd_set_device_constraint() - Set LPM constraint on behalf of a device
1913 * @handle:	pointer to TI SCI handle
1914 * @id:	Device identifier
1915 * @state:	The desired state of device constraint: set or clear
1916 *
1917 * Return: 0 if all went well, else returns appropriate error value.
1918 */
1919static int ti_sci_cmd_set_device_constraint(const struct ti_sci_handle *handle,
1920					    u32 id, u8 state)
1921{
1922	struct ti_sci_info *info;
1923	struct ti_sci_msg_req_lpm_set_device_constraint *req;
1924	struct ti_sci_msg_hdr *resp;
1925	struct ti_sci_xfer *xfer;
1926	struct device *dev;
1927	int ret = 0;
1928
1929	if (IS_ERR(handle))
1930		return PTR_ERR(handle);
1931	if (!handle)
1932		return -EINVAL;
1933
1934	info = handle_to_ti_sci_info(handle);
1935	dev = info->dev;
1936
1937	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_SET_DEVICE_CONSTRAINT,
1938				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1939				   sizeof(*req), sizeof(*resp));
1940	if (IS_ERR(xfer)) {
1941		ret = PTR_ERR(xfer);
1942		dev_err(dev, "Message alloc failed(%d)\n", ret);
1943		return ret;
1944	}
1945	req = (struct ti_sci_msg_req_lpm_set_device_constraint *)xfer->xfer_buf;
1946	req->id = id;
1947	req->state = state;
1948
1949	ret = ti_sci_do_xfer(info, xfer);
1950	if (ret) {
1951		dev_err(dev, "Mbox send fail %d\n", ret);
1952		goto fail;
1953	}
1954
1955	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
1956
1957	if (!ti_sci_is_response_ack(resp)) {
1958		dev_err(dev, "Failed to set device constraint\n");
1959		ret = -ENODEV;
1960	}
1961
1962fail:
1963	ti_sci_put_one_xfer(&info->minfo, xfer);
1964
1965	return ret;
1966}
1967
1968/**
1969 * ti_sci_cmd_set_latency_constraint() - Set LPM resume latency constraint
1970 * @handle:	pointer to TI SCI handle
1971 * @latency:	maximum acceptable latency (in ms) to wake up from LPM
1972 * @state:	The desired state of latency constraint: set or clear
1973 *
1974 * Return: 0 if all went well, else returns appropriate error value.
1975 */
1976static int ti_sci_cmd_set_latency_constraint(const struct ti_sci_handle *handle,
1977					     u16 latency, u8 state)
1978{
1979	struct ti_sci_info *info;
1980	struct ti_sci_msg_req_lpm_set_latency_constraint *req;
1981	struct ti_sci_msg_hdr *resp;
1982	struct ti_sci_xfer *xfer;
1983	struct device *dev;
1984	int ret = 0;
1985
1986	if (IS_ERR(handle))
1987		return PTR_ERR(handle);
1988	if (!handle)
1989		return -EINVAL;
1990
1991	info = handle_to_ti_sci_info(handle);
1992	dev = info->dev;
1993
1994	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_SET_LATENCY_CONSTRAINT,
1995				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
1996				   sizeof(*req), sizeof(*resp));
1997	if (IS_ERR(xfer)) {
1998		ret = PTR_ERR(xfer);
1999		dev_err(dev, "Message alloc failed(%d)\n", ret);
2000		return ret;
2001	}
2002	req = (struct ti_sci_msg_req_lpm_set_latency_constraint *)xfer->xfer_buf;
2003	req->latency = latency;
2004	req->state = state;
2005
2006	ret = ti_sci_do_xfer(info, xfer);
2007	if (ret) {
2008		dev_err(dev, "Mbox send fail %d\n", ret);
2009		goto fail;
2010	}
2011
2012	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2013
2014	if (!ti_sci_is_response_ack(resp)) {
2015		dev_err(dev, "Failed to set device constraint\n");
2016		ret = -ENODEV;
2017	}
2018
2019fail:
2020	ti_sci_put_one_xfer(&info->minfo, xfer);
2021
2022	return ret;
2023}
2024
2025/**
2026 * ti_sci_cmd_lpm_abort() - Abort entry to LPM by clearing selection of LPM to enter
2027 * @dev:	Device pointer corresponding to the SCI entity
2028 *
2029 * Return: 0 if all went well, else returns appropriate error value.
2030 */
2031static int ti_sci_cmd_lpm_abort(struct device *dev)
2032{
2033	struct ti_sci_info *info = dev_get_drvdata(dev);
2034	struct ti_sci_msg_hdr *req;
2035	struct ti_sci_msg_hdr *resp;
2036	struct ti_sci_xfer *xfer;
2037	int ret = 0;
2038
2039	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_LPM_ABORT,
2040				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2041				   sizeof(*req), sizeof(*resp));
2042	if (IS_ERR(xfer)) {
2043		ret = PTR_ERR(xfer);
2044		dev_err(dev, "Message alloc failed(%d)\n", ret);
2045		return ret;
2046	}
2047	req = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2048
2049	ret = ti_sci_do_xfer(info, xfer);
2050	if (ret) {
2051		dev_err(dev, "Mbox send fail %d\n", ret);
2052		goto fail;
2053	}
2054
2055	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2056
2057	if (!ti_sci_is_response_ack(resp))
2058		ret = -ENODEV;
2059
2060fail:
2061	ti_sci_put_one_xfer(&info->minfo, xfer);
2062
2063	return ret;
2064}
2065
2066static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle)
2067{
2068	struct ti_sci_info *info;
2069	struct ti_sci_msg_req_reboot *req;
2070	struct ti_sci_msg_hdr *resp;
2071	struct ti_sci_xfer *xfer;
2072	struct device *dev;
2073	int ret = 0;
2074
2075	if (IS_ERR(handle))
2076		return PTR_ERR(handle);
2077	if (!handle)
2078		return -EINVAL;
2079
2080	info = handle_to_ti_sci_info(handle);
2081	dev = info->dev;
2082
2083	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SYS_RESET,
2084				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2085				   sizeof(*req), sizeof(*resp));
2086	if (IS_ERR(xfer)) {
2087		ret = PTR_ERR(xfer);
2088		dev_err(dev, "Message alloc failed(%d)\n", ret);
2089		return ret;
2090	}
2091	req = (struct ti_sci_msg_req_reboot *)xfer->xfer_buf;
2092
2093	ret = ti_sci_do_xfer(info, xfer);
2094	if (ret) {
2095		dev_err(dev, "Mbox send fail %d\n", ret);
2096		goto fail;
2097	}
2098
2099	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2100
2101	if (!ti_sci_is_response_ack(resp))
2102		ret = -ENODEV;
2103	else
2104		ret = 0;
2105
2106fail:
2107	ti_sci_put_one_xfer(&info->minfo, xfer);
2108
2109	return ret;
2110}
2111
2112/**
2113 * ti_sci_get_resource_range - Helper to get a range of resources assigned
2114 *			       to a host. Resource is uniquely identified by
2115 *			       type and subtype.
2116 * @handle:		Pointer to TISCI handle.
2117 * @dev_id:		TISCI device ID.
2118 * @subtype:		Resource assignment subtype that is being requested
2119 *			from the given device.
2120 * @s_host:		Host processor ID to which the resources are allocated
2121 * @desc:		Pointer to ti_sci_resource_desc to be updated with the
2122 *			resource range start index and number of resources
2123 *
2124 * Return: 0 if all went fine, else return appropriate error.
2125 */
2126static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
2127				     u32 dev_id, u8 subtype, u8 s_host,
2128				     struct ti_sci_resource_desc *desc)
2129{
2130	struct ti_sci_msg_resp_get_resource_range *resp;
2131	struct ti_sci_msg_req_get_resource_range *req;
2132	struct ti_sci_xfer *xfer;
2133	struct ti_sci_info *info;
2134	struct device *dev;
2135	int ret = 0;
2136
2137	if (IS_ERR(handle))
2138		return PTR_ERR(handle);
2139	if (!handle || !desc)
2140		return -EINVAL;
2141
2142	info = handle_to_ti_sci_info(handle);
2143	dev = info->dev;
2144
2145	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_RESOURCE_RANGE,
2146				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2147				   sizeof(*req), sizeof(*resp));
2148	if (IS_ERR(xfer)) {
2149		ret = PTR_ERR(xfer);
2150		dev_err(dev, "Message alloc failed(%d)\n", ret);
2151		return ret;
2152	}
2153
2154	req = (struct ti_sci_msg_req_get_resource_range *)xfer->xfer_buf;
2155	req->secondary_host = s_host;
2156	req->type = dev_id & MSG_RM_RESOURCE_TYPE_MASK;
2157	req->subtype = subtype & MSG_RM_RESOURCE_SUBTYPE_MASK;
2158
2159	ret = ti_sci_do_xfer(info, xfer);
2160	if (ret) {
2161		dev_err(dev, "Mbox send fail %d\n", ret);
2162		goto fail;
2163	}
2164
2165	resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->xfer_buf;
2166
2167	if (!ti_sci_is_response_ack(resp)) {
2168		ret = -ENODEV;
2169	} else if (!resp->range_num && !resp->range_num_sec) {
2170		/* Neither of the two resource range is valid */
2171		ret = -ENODEV;
2172	} else {
2173		desc->start = resp->range_start;
2174		desc->num = resp->range_num;
2175		desc->start_sec = resp->range_start_sec;
2176		desc->num_sec = resp->range_num_sec;
2177	}
2178
2179fail:
2180	ti_sci_put_one_xfer(&info->minfo, xfer);
2181
2182	return ret;
2183}
2184
2185/**
2186 * ti_sci_cmd_get_resource_range - Get a range of resources assigned to host
2187 *				   that is same as ti sci interface host.
2188 * @handle:		Pointer to TISCI handle.
2189 * @dev_id:		TISCI device ID.
2190 * @subtype:		Resource assignment subtype that is being requested
2191 *			from the given device.
2192 * @desc:		Pointer to ti_sci_resource_desc to be updated with the
2193 *			resource range start index and number of resources
2194 *
2195 * Return: 0 if all went fine, else return appropriate error.
2196 */
2197static int ti_sci_cmd_get_resource_range(const struct ti_sci_handle *handle,
2198					 u32 dev_id, u8 subtype,
2199					 struct ti_sci_resource_desc *desc)
2200{
2201	return ti_sci_get_resource_range(handle, dev_id, subtype,
2202					 TI_SCI_IRQ_SECONDARY_HOST_INVALID,
2203					 desc);
2204}
2205
2206/**
2207 * ti_sci_cmd_get_resource_range_from_shost - Get a range of resources
2208 *					      assigned to a specified host.
2209 * @handle:		Pointer to TISCI handle.
2210 * @dev_id:		TISCI device ID.
2211 * @subtype:		Resource assignment subtype that is being requested
2212 *			from the given device.
2213 * @s_host:		Host processor ID to which the resources are allocated
2214 * @desc:		Pointer to ti_sci_resource_desc to be updated with the
2215 *			resource range start index and number of resources
2216 *
2217 * Return: 0 if all went fine, else return appropriate error.
2218 */
2219static
2220int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle,
2221					     u32 dev_id, u8 subtype, u8 s_host,
2222					     struct ti_sci_resource_desc *desc)
2223{
2224	return ti_sci_get_resource_range(handle, dev_id, subtype, s_host, desc);
2225}
2226
2227/**
2228 * ti_sci_manage_irq() - Helper api to configure/release the irq route between
2229 *			 the requested source and destination
2230 * @handle:		Pointer to TISCI handle.
2231 * @valid_params:	Bit fields defining the validity of certain params
2232 * @src_id:		Device ID of the IRQ source
2233 * @src_index:		IRQ source index within the source device
2234 * @dst_id:		Device ID of the IRQ destination
2235 * @dst_host_irq:	IRQ number of the destination device
2236 * @ia_id:		Device ID of the IA, if the IRQ flows through this IA
2237 * @vint:		Virtual interrupt to be used within the IA
2238 * @global_event:	Global event number to be used for the requesting event
2239 * @vint_status_bit:	Virtual interrupt status bit to be used for the event
2240 * @s_host:		Secondary host ID to which the irq/event is being
2241 *			requested for.
2242 * @type:		Request type irq set or release.
2243 *
2244 * Return: 0 if all went fine, else return appropriate error.
2245 */
2246static int ti_sci_manage_irq(const struct ti_sci_handle *handle,
2247			     u32 valid_params, u16 src_id, u16 src_index,
2248			     u16 dst_id, u16 dst_host_irq, u16 ia_id, u16 vint,
2249			     u16 global_event, u8 vint_status_bit, u8 s_host,
2250			     u16 type)
2251{
2252	struct ti_sci_msg_req_manage_irq *req;
2253	struct ti_sci_msg_hdr *resp;
2254	struct ti_sci_xfer *xfer;
2255	struct ti_sci_info *info;
2256	struct device *dev;
2257	int ret = 0;
2258
2259	if (IS_ERR(handle))
2260		return PTR_ERR(handle);
2261	if (!handle)
2262		return -EINVAL;
2263
2264	info = handle_to_ti_sci_info(handle);
2265	dev = info->dev;
2266
2267	xfer = ti_sci_get_one_xfer(info, type, TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2268				   sizeof(*req), sizeof(*resp));
2269	if (IS_ERR(xfer)) {
2270		ret = PTR_ERR(xfer);
2271		dev_err(dev, "Message alloc failed(%d)\n", ret);
2272		return ret;
2273	}
2274	req = (struct ti_sci_msg_req_manage_irq *)xfer->xfer_buf;
2275	req->valid_params = valid_params;
2276	req->src_id = src_id;
2277	req->src_index = src_index;
2278	req->dst_id = dst_id;
2279	req->dst_host_irq = dst_host_irq;
2280	req->ia_id = ia_id;
2281	req->vint = vint;
2282	req->global_event = global_event;
2283	req->vint_status_bit = vint_status_bit;
2284	req->secondary_host = s_host;
2285
2286	ret = ti_sci_do_xfer(info, xfer);
2287	if (ret) {
2288		dev_err(dev, "Mbox send fail %d\n", ret);
2289		goto fail;
2290	}
2291
2292	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2293
2294	ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
2295
2296fail:
2297	ti_sci_put_one_xfer(&info->minfo, xfer);
2298
2299	return ret;
2300}
2301
2302/**
2303 * ti_sci_set_irq() - Helper api to configure the irq route between the
2304 *		      requested source and destination
2305 * @handle:		Pointer to TISCI handle.
2306 * @valid_params:	Bit fields defining the validity of certain params
2307 * @src_id:		Device ID of the IRQ source
2308 * @src_index:		IRQ source index within the source device
2309 * @dst_id:		Device ID of the IRQ destination
2310 * @dst_host_irq:	IRQ number of the destination device
2311 * @ia_id:		Device ID of the IA, if the IRQ flows through this IA
2312 * @vint:		Virtual interrupt to be used within the IA
2313 * @global_event:	Global event number to be used for the requesting event
2314 * @vint_status_bit:	Virtual interrupt status bit to be used for the event
2315 * @s_host:		Secondary host ID to which the irq/event is being
2316 *			requested for.
2317 *
2318 * Return: 0 if all went fine, else return appropriate error.
2319 */
2320static int ti_sci_set_irq(const struct ti_sci_handle *handle, u32 valid_params,
2321			  u16 src_id, u16 src_index, u16 dst_id,
2322			  u16 dst_host_irq, u16 ia_id, u16 vint,
2323			  u16 global_event, u8 vint_status_bit, u8 s_host)
2324{
2325	pr_debug("%s: IRQ set with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
2326		 __func__, valid_params, src_id, src_index,
2327		 dst_id, dst_host_irq, ia_id, vint, global_event,
2328		 vint_status_bit);
2329
2330	return ti_sci_manage_irq(handle, valid_params, src_id, src_index,
2331				 dst_id, dst_host_irq, ia_id, vint,
2332				 global_event, vint_status_bit, s_host,
2333				 TI_SCI_MSG_SET_IRQ);
2334}
2335
2336/**
2337 * ti_sci_free_irq() - Helper api to free the irq route between the
2338 *			   requested source and destination
2339 * @handle:		Pointer to TISCI handle.
2340 * @valid_params:	Bit fields defining the validity of certain params
2341 * @src_id:		Device ID of the IRQ source
2342 * @src_index:		IRQ source index within the source device
2343 * @dst_id:		Device ID of the IRQ destination
2344 * @dst_host_irq:	IRQ number of the destination device
2345 * @ia_id:		Device ID of the IA, if the IRQ flows through this IA
2346 * @vint:		Virtual interrupt to be used within the IA
2347 * @global_event:	Global event number to be used for the requesting event
2348 * @vint_status_bit:	Virtual interrupt status bit to be used for the event
2349 * @s_host:		Secondary host ID to which the irq/event is being
2350 *			requested for.
2351 *
2352 * Return: 0 if all went fine, else return appropriate error.
2353 */
2354static int ti_sci_free_irq(const struct ti_sci_handle *handle, u32 valid_params,
2355			   u16 src_id, u16 src_index, u16 dst_id,
2356			   u16 dst_host_irq, u16 ia_id, u16 vint,
2357			   u16 global_event, u8 vint_status_bit, u8 s_host)
2358{
2359	pr_debug("%s: IRQ release with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
2360		 __func__, valid_params, src_id, src_index,
2361		 dst_id, dst_host_irq, ia_id, vint, global_event,
2362		 vint_status_bit);
2363
2364	return ti_sci_manage_irq(handle, valid_params, src_id, src_index,
2365				 dst_id, dst_host_irq, ia_id, vint,
2366				 global_event, vint_status_bit, s_host,
2367				 TI_SCI_MSG_FREE_IRQ);
2368}
2369
2370/**
2371 * ti_sci_cmd_set_irq() - Configure a host irq route between the requested
2372 *			  source and destination.
2373 * @handle:		Pointer to TISCI handle.
2374 * @src_id:		Device ID of the IRQ source
2375 * @src_index:		IRQ source index within the source device
2376 * @dst_id:		Device ID of the IRQ destination
2377 * @dst_host_irq:	IRQ number of the destination device
2378 *
2379 * Return: 0 if all went fine, else return appropriate error.
2380 */
2381static int ti_sci_cmd_set_irq(const struct ti_sci_handle *handle, u16 src_id,
2382			      u16 src_index, u16 dst_id, u16 dst_host_irq)
2383{
2384	u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID;
2385
2386	return ti_sci_set_irq(handle, valid_params, src_id, src_index, dst_id,
2387			      dst_host_irq, 0, 0, 0, 0, 0);
2388}
2389
2390/**
2391 * ti_sci_cmd_set_event_map() - Configure an event based irq route between the
2392 *				requested source and Interrupt Aggregator.
2393 * @handle:		Pointer to TISCI handle.
2394 * @src_id:		Device ID of the IRQ source
2395 * @src_index:		IRQ source index within the source device
2396 * @ia_id:		Device ID of the IA, if the IRQ flows through this IA
2397 * @vint:		Virtual interrupt to be used within the IA
2398 * @global_event:	Global event number to be used for the requesting event
2399 * @vint_status_bit:	Virtual interrupt status bit to be used for the event
2400 *
2401 * Return: 0 if all went fine, else return appropriate error.
2402 */
2403static int ti_sci_cmd_set_event_map(const struct ti_sci_handle *handle,
2404				    u16 src_id, u16 src_index, u16 ia_id,
2405				    u16 vint, u16 global_event,
2406				    u8 vint_status_bit)
2407{
2408	u32 valid_params = MSG_FLAG_IA_ID_VALID | MSG_FLAG_VINT_VALID |
2409			   MSG_FLAG_GLB_EVNT_VALID |
2410			   MSG_FLAG_VINT_STS_BIT_VALID;
2411
2412	return ti_sci_set_irq(handle, valid_params, src_id, src_index, 0, 0,
2413			      ia_id, vint, global_event, vint_status_bit, 0);
2414}
2415
2416/**
2417 * ti_sci_cmd_free_irq() - Free a host irq route between the between the
2418 *			   requested source and destination.
2419 * @handle:		Pointer to TISCI handle.
2420 * @src_id:		Device ID of the IRQ source
2421 * @src_index:		IRQ source index within the source device
2422 * @dst_id:		Device ID of the IRQ destination
2423 * @dst_host_irq:	IRQ number of the destination device
2424 *
2425 * Return: 0 if all went fine, else return appropriate error.
2426 */
2427static int ti_sci_cmd_free_irq(const struct ti_sci_handle *handle, u16 src_id,
2428			       u16 src_index, u16 dst_id, u16 dst_host_irq)
2429{
2430	u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID;
2431
2432	return ti_sci_free_irq(handle, valid_params, src_id, src_index, dst_id,
2433			       dst_host_irq, 0, 0, 0, 0, 0);
2434}
2435
2436/**
2437 * ti_sci_cmd_free_event_map() - Free an event map between the requested source
2438 *				 and Interrupt Aggregator.
2439 * @handle:		Pointer to TISCI handle.
2440 * @src_id:		Device ID of the IRQ source
2441 * @src_index:		IRQ source index within the source device
2442 * @ia_id:		Device ID of the IA, if the IRQ flows through this IA
2443 * @vint:		Virtual interrupt to be used within the IA
2444 * @global_event:	Global event number to be used for the requesting event
2445 * @vint_status_bit:	Virtual interrupt status bit to be used for the event
2446 *
2447 * Return: 0 if all went fine, else return appropriate error.
2448 */
2449static int ti_sci_cmd_free_event_map(const struct ti_sci_handle *handle,
2450				     u16 src_id, u16 src_index, u16 ia_id,
2451				     u16 vint, u16 global_event,
2452				     u8 vint_status_bit)
2453{
2454	u32 valid_params = MSG_FLAG_IA_ID_VALID |
2455			   MSG_FLAG_VINT_VALID | MSG_FLAG_GLB_EVNT_VALID |
2456			   MSG_FLAG_VINT_STS_BIT_VALID;
2457
2458	return ti_sci_free_irq(handle, valid_params, src_id, src_index, 0, 0,
2459			       ia_id, vint, global_event, vint_status_bit, 0);
2460}
2461
2462/**
2463 * ti_sci_cmd_rm_ring_cfg() - Configure a NAVSS ring
2464 * @handle:	Pointer to TI SCI handle.
2465 * @params:	Pointer to ti_sci_msg_rm_ring_cfg ring config structure
2466 *
2467 * Return: 0 if all went well, else returns appropriate error value.
2468 *
2469 * See @ti_sci_msg_rm_ring_cfg and @ti_sci_msg_rm_ring_cfg_req for
2470 * more info.
2471 */
2472static int ti_sci_cmd_rm_ring_cfg(const struct ti_sci_handle *handle,
2473				  const struct ti_sci_msg_rm_ring_cfg *params)
2474{
2475	struct ti_sci_msg_rm_ring_cfg_req *req;
2476	struct ti_sci_msg_hdr *resp;
2477	struct ti_sci_xfer *xfer;
2478	struct ti_sci_info *info;
2479	struct device *dev;
2480	int ret = 0;
2481
2482	if (IS_ERR_OR_NULL(handle))
2483		return -EINVAL;
2484
2485	info = handle_to_ti_sci_info(handle);
2486	dev = info->dev;
2487
2488	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_RM_RING_CFG,
2489				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2490				   sizeof(*req), sizeof(*resp));
2491	if (IS_ERR(xfer)) {
2492		ret = PTR_ERR(xfer);
2493		dev_err(dev, "RM_RA:Message config failed(%d)\n", ret);
2494		return ret;
2495	}
2496	req = (struct ti_sci_msg_rm_ring_cfg_req *)xfer->xfer_buf;
2497	req->valid_params = params->valid_params;
2498	req->nav_id = params->nav_id;
2499	req->index = params->index;
2500	req->addr_lo = params->addr_lo;
2501	req->addr_hi = params->addr_hi;
2502	req->count = params->count;
2503	req->mode = params->mode;
2504	req->size = params->size;
2505	req->order_id = params->order_id;
2506	req->virtid = params->virtid;
2507	req->asel = params->asel;
2508
2509	ret = ti_sci_do_xfer(info, xfer);
2510	if (ret) {
2511		dev_err(dev, "RM_RA:Mbox config send fail %d\n", ret);
2512		goto fail;
2513	}
2514
2515	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2516	ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
2517
2518fail:
2519	ti_sci_put_one_xfer(&info->minfo, xfer);
2520	dev_dbg(dev, "RM_RA:config ring %u ret:%d\n", params->index, ret);
2521	return ret;
2522}
2523
2524/**
2525 * ti_sci_cmd_rm_psil_pair() - Pair PSI-L source to destination thread
2526 * @handle:	Pointer to TI SCI handle.
2527 * @nav_id:	Device ID of Navigator Subsystem which should be used for
2528 *		pairing
2529 * @src_thread:	Source PSI-L thread ID
2530 * @dst_thread: Destination PSI-L thread ID
2531 *
2532 * Return: 0 if all went well, else returns appropriate error value.
2533 */
2534static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle,
2535				   u32 nav_id, u32 src_thread, u32 dst_thread)
2536{
2537	struct ti_sci_msg_psil_pair *req;
2538	struct ti_sci_msg_hdr *resp;
2539	struct ti_sci_xfer *xfer;
2540	struct ti_sci_info *info;
2541	struct device *dev;
2542	int ret = 0;
2543
2544	if (IS_ERR(handle))
2545		return PTR_ERR(handle);
2546	if (!handle)
2547		return -EINVAL;
2548
2549	info = handle_to_ti_sci_info(handle);
2550	dev = info->dev;
2551
2552	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_RM_PSIL_PAIR,
2553				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2554				   sizeof(*req), sizeof(*resp));
2555	if (IS_ERR(xfer)) {
2556		ret = PTR_ERR(xfer);
2557		dev_err(dev, "RM_PSIL:Message reconfig failed(%d)\n", ret);
2558		return ret;
2559	}
2560	req = (struct ti_sci_msg_psil_pair *)xfer->xfer_buf;
2561	req->nav_id = nav_id;
2562	req->src_thread = src_thread;
2563	req->dst_thread = dst_thread;
2564
2565	ret = ti_sci_do_xfer(info, xfer);
2566	if (ret) {
2567		dev_err(dev, "RM_PSIL:Mbox send fail %d\n", ret);
2568		goto fail;
2569	}
2570
2571	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2572	ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
2573
2574fail:
2575	ti_sci_put_one_xfer(&info->minfo, xfer);
2576
2577	return ret;
2578}
2579
2580/**
2581 * ti_sci_cmd_rm_psil_unpair() - Unpair PSI-L source from destination thread
2582 * @handle:	Pointer to TI SCI handle.
2583 * @nav_id:	Device ID of Navigator Subsystem which should be used for
2584 *		unpairing
2585 * @src_thread:	Source PSI-L thread ID
2586 * @dst_thread:	Destination PSI-L thread ID
2587 *
2588 * Return: 0 if all went well, else returns appropriate error value.
2589 */
2590static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle,
2591				     u32 nav_id, u32 src_thread, u32 dst_thread)
2592{
2593	struct ti_sci_msg_psil_unpair *req;
2594	struct ti_sci_msg_hdr *resp;
2595	struct ti_sci_xfer *xfer;
2596	struct ti_sci_info *info;
2597	struct device *dev;
2598	int ret = 0;
2599
2600	if (IS_ERR(handle))
2601		return PTR_ERR(handle);
2602	if (!handle)
2603		return -EINVAL;
2604
2605	info = handle_to_ti_sci_info(handle);
2606	dev = info->dev;
2607
2608	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_RM_PSIL_UNPAIR,
2609				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2610				   sizeof(*req), sizeof(*resp));
2611	if (IS_ERR(xfer)) {
2612		ret = PTR_ERR(xfer);
2613		dev_err(dev, "RM_PSIL:Message reconfig failed(%d)\n", ret);
2614		return ret;
2615	}
2616	req = (struct ti_sci_msg_psil_unpair *)xfer->xfer_buf;
2617	req->nav_id = nav_id;
2618	req->src_thread = src_thread;
2619	req->dst_thread = dst_thread;
2620
2621	ret = ti_sci_do_xfer(info, xfer);
2622	if (ret) {
2623		dev_err(dev, "RM_PSIL:Mbox send fail %d\n", ret);
2624		goto fail;
2625	}
2626
2627	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2628	ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
2629
2630fail:
2631	ti_sci_put_one_xfer(&info->minfo, xfer);
2632
2633	return ret;
2634}
2635
2636/**
2637 * ti_sci_cmd_rm_udmap_tx_ch_cfg() - Configure a UDMAP TX channel
2638 * @handle:	Pointer to TI SCI handle.
2639 * @params:	Pointer to ti_sci_msg_rm_udmap_tx_ch_cfg TX channel config
2640 *		structure
2641 *
2642 * Return: 0 if all went well, else returns appropriate error value.
2643 *
2644 * See @ti_sci_msg_rm_udmap_tx_ch_cfg and @ti_sci_msg_rm_udmap_tx_ch_cfg_req for
2645 * more info.
2646 */
2647static int ti_sci_cmd_rm_udmap_tx_ch_cfg(const struct ti_sci_handle *handle,
2648			const struct ti_sci_msg_rm_udmap_tx_ch_cfg *params)
2649{
2650	struct ti_sci_msg_rm_udmap_tx_ch_cfg_req *req;
2651	struct ti_sci_msg_hdr *resp;
2652	struct ti_sci_xfer *xfer;
2653	struct ti_sci_info *info;
2654	struct device *dev;
2655	int ret = 0;
2656
2657	if (IS_ERR_OR_NULL(handle))
2658		return -EINVAL;
2659
2660	info = handle_to_ti_sci_info(handle);
2661	dev = info->dev;
2662
2663	xfer = ti_sci_get_one_xfer(info, TISCI_MSG_RM_UDMAP_TX_CH_CFG,
2664				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2665				   sizeof(*req), sizeof(*resp));
2666	if (IS_ERR(xfer)) {
2667		ret = PTR_ERR(xfer);
2668		dev_err(dev, "Message TX_CH_CFG alloc failed(%d)\n", ret);
2669		return ret;
2670	}
2671	req = (struct ti_sci_msg_rm_udmap_tx_ch_cfg_req *)xfer->xfer_buf;
2672	req->valid_params = params->valid_params;
2673	req->nav_id = params->nav_id;
2674	req->index = params->index;
2675	req->tx_pause_on_err = params->tx_pause_on_err;
2676	req->tx_filt_einfo = params->tx_filt_einfo;
2677	req->tx_filt_pswords = params->tx_filt_pswords;
2678	req->tx_atype = params->tx_atype;
2679	req->tx_chan_type = params->tx_chan_type;
2680	req->tx_supr_tdpkt = params->tx_supr_tdpkt;
2681	req->tx_fetch_size = params->tx_fetch_size;
2682	req->tx_credit_count = params->tx_credit_count;
2683	req->txcq_qnum = params->txcq_qnum;
2684	req->tx_priority = params->tx_priority;
2685	req->tx_qos = params->tx_qos;
2686	req->tx_orderid = params->tx_orderid;
2687	req->fdepth = params->fdepth;
2688	req->tx_sched_priority = params->tx_sched_priority;
2689	req->tx_burst_size = params->tx_burst_size;
2690	req->tx_tdtype = params->tx_tdtype;
2691	req->extended_ch_type = params->extended_ch_type;
2692
2693	ret = ti_sci_do_xfer(info, xfer);
2694	if (ret) {
2695		dev_err(dev, "Mbox send TX_CH_CFG fail %d\n", ret);
2696		goto fail;
2697	}
2698
2699	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2700	ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
2701
2702fail:
2703	ti_sci_put_one_xfer(&info->minfo, xfer);
2704	dev_dbg(dev, "TX_CH_CFG: chn %u ret:%u\n", params->index, ret);
2705	return ret;
2706}
2707
2708/**
2709 * ti_sci_cmd_rm_udmap_rx_ch_cfg() - Configure a UDMAP RX channel
2710 * @handle:	Pointer to TI SCI handle.
2711 * @params:	Pointer to ti_sci_msg_rm_udmap_rx_ch_cfg RX channel config
2712 *		structure
2713 *
2714 * Return: 0 if all went well, else returns appropriate error value.
2715 *
2716 * See @ti_sci_msg_rm_udmap_rx_ch_cfg and @ti_sci_msg_rm_udmap_rx_ch_cfg_req for
2717 * more info.
2718 */
2719static int ti_sci_cmd_rm_udmap_rx_ch_cfg(const struct ti_sci_handle *handle,
2720			const struct ti_sci_msg_rm_udmap_rx_ch_cfg *params)
2721{
2722	struct ti_sci_msg_rm_udmap_rx_ch_cfg_req *req;
2723	struct ti_sci_msg_hdr *resp;
2724	struct ti_sci_xfer *xfer;
2725	struct ti_sci_info *info;
2726	struct device *dev;
2727	int ret = 0;
2728
2729	if (IS_ERR_OR_NULL(handle))
2730		return -EINVAL;
2731
2732	info = handle_to_ti_sci_info(handle);
2733	dev = info->dev;
2734
2735	xfer = ti_sci_get_one_xfer(info, TISCI_MSG_RM_UDMAP_RX_CH_CFG,
2736				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2737				   sizeof(*req), sizeof(*resp));
2738	if (IS_ERR(xfer)) {
2739		ret = PTR_ERR(xfer);
2740		dev_err(dev, "Message RX_CH_CFG alloc failed(%d)\n", ret);
2741		return ret;
2742	}
2743	req = (struct ti_sci_msg_rm_udmap_rx_ch_cfg_req *)xfer->xfer_buf;
2744	req->valid_params = params->valid_params;
2745	req->nav_id = params->nav_id;
2746	req->index = params->index;
2747	req->rx_fetch_size = params->rx_fetch_size;
2748	req->rxcq_qnum = params->rxcq_qnum;
2749	req->rx_priority = params->rx_priority;
2750	req->rx_qos = params->rx_qos;
2751	req->rx_orderid = params->rx_orderid;
2752	req->rx_sched_priority = params->rx_sched_priority;
2753	req->flowid_start = params->flowid_start;
2754	req->flowid_cnt = params->flowid_cnt;
2755	req->rx_pause_on_err = params->rx_pause_on_err;
2756	req->rx_atype = params->rx_atype;
2757	req->rx_chan_type = params->rx_chan_type;
2758	req->rx_ignore_short = params->rx_ignore_short;
2759	req->rx_ignore_long = params->rx_ignore_long;
2760	req->rx_burst_size = params->rx_burst_size;
2761
2762	ret = ti_sci_do_xfer(info, xfer);
2763	if (ret) {
2764		dev_err(dev, "Mbox send RX_CH_CFG fail %d\n", ret);
2765		goto fail;
2766	}
2767
2768	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2769	ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
2770
2771fail:
2772	ti_sci_put_one_xfer(&info->minfo, xfer);
2773	dev_dbg(dev, "RX_CH_CFG: chn %u ret:%d\n", params->index, ret);
2774	return ret;
2775}
2776
2777/**
2778 * ti_sci_cmd_rm_udmap_rx_flow_cfg() - Configure UDMAP RX FLOW
2779 * @handle:	Pointer to TI SCI handle.
2780 * @params:	Pointer to ti_sci_msg_rm_udmap_flow_cfg RX FLOW config
2781 *		structure
2782 *
2783 * Return: 0 if all went well, else returns appropriate error value.
2784 *
2785 * See @ti_sci_msg_rm_udmap_flow_cfg and @ti_sci_msg_rm_udmap_flow_cfg_req for
2786 * more info.
2787 */
2788static int ti_sci_cmd_rm_udmap_rx_flow_cfg(const struct ti_sci_handle *handle,
2789			const struct ti_sci_msg_rm_udmap_flow_cfg *params)
2790{
2791	struct ti_sci_msg_rm_udmap_flow_cfg_req *req;
2792	struct ti_sci_msg_hdr *resp;
2793	struct ti_sci_xfer *xfer;
2794	struct ti_sci_info *info;
2795	struct device *dev;
2796	int ret = 0;
2797
2798	if (IS_ERR_OR_NULL(handle))
2799		return -EINVAL;
2800
2801	info = handle_to_ti_sci_info(handle);
2802	dev = info->dev;
2803
2804	xfer = ti_sci_get_one_xfer(info, TISCI_MSG_RM_UDMAP_FLOW_CFG,
2805				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2806				   sizeof(*req), sizeof(*resp));
2807	if (IS_ERR(xfer)) {
2808		ret = PTR_ERR(xfer);
2809		dev_err(dev, "RX_FL_CFG: Message alloc failed(%d)\n", ret);
2810		return ret;
2811	}
2812	req = (struct ti_sci_msg_rm_udmap_flow_cfg_req *)xfer->xfer_buf;
2813	req->valid_params = params->valid_params;
2814	req->nav_id = params->nav_id;
2815	req->flow_index = params->flow_index;
2816	req->rx_einfo_present = params->rx_einfo_present;
2817	req->rx_psinfo_present = params->rx_psinfo_present;
2818	req->rx_error_handling = params->rx_error_handling;
2819	req->rx_desc_type = params->rx_desc_type;
2820	req->rx_sop_offset = params->rx_sop_offset;
2821	req->rx_dest_qnum = params->rx_dest_qnum;
2822	req->rx_src_tag_hi = params->rx_src_tag_hi;
2823	req->rx_src_tag_lo = params->rx_src_tag_lo;
2824	req->rx_dest_tag_hi = params->rx_dest_tag_hi;
2825	req->rx_dest_tag_lo = params->rx_dest_tag_lo;
2826	req->rx_src_tag_hi_sel = params->rx_src_tag_hi_sel;
2827	req->rx_src_tag_lo_sel = params->rx_src_tag_lo_sel;
2828	req->rx_dest_tag_hi_sel = params->rx_dest_tag_hi_sel;
2829	req->rx_dest_tag_lo_sel = params->rx_dest_tag_lo_sel;
2830	req->rx_fdq0_sz0_qnum = params->rx_fdq0_sz0_qnum;
2831	req->rx_fdq1_qnum = params->rx_fdq1_qnum;
2832	req->rx_fdq2_qnum = params->rx_fdq2_qnum;
2833	req->rx_fdq3_qnum = params->rx_fdq3_qnum;
2834	req->rx_ps_location = params->rx_ps_location;
2835
2836	ret = ti_sci_do_xfer(info, xfer);
2837	if (ret) {
2838		dev_err(dev, "RX_FL_CFG: Mbox send fail %d\n", ret);
2839		goto fail;
2840	}
2841
2842	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
2843	ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL;
2844
2845fail:
2846	ti_sci_put_one_xfer(&info->minfo, xfer);
2847	dev_dbg(info->dev, "RX_FL_CFG: %u ret:%d\n", params->flow_index, ret);
2848	return ret;
2849}
2850
2851/**
2852 * ti_sci_cmd_proc_request() - Command to request a physical processor control
2853 * @handle:	Pointer to TI SCI handle
2854 * @proc_id:	Processor ID this request is for
2855 *
2856 * Return: 0 if all went well, else returns appropriate error value.
2857 */
2858static int ti_sci_cmd_proc_request(const struct ti_sci_handle *handle,
2859				   u8 proc_id)
2860{
2861	struct ti_sci_msg_req_proc_request *req;
2862	struct ti_sci_msg_hdr *resp;
2863	struct ti_sci_info *info;
2864	struct ti_sci_xfer *xfer;
2865	struct device *dev;
2866	int ret = 0;
2867
2868	if (!handle)
2869		return -EINVAL;
2870	if (IS_ERR(handle))
2871		return PTR_ERR(handle);
2872
2873	info = handle_to_ti_sci_info(handle);
2874	dev = info->dev;
2875
2876	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PROC_REQUEST,
2877				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2878				   sizeof(*req), sizeof(*resp));
2879	if (IS_ERR(xfer)) {
2880		ret = PTR_ERR(xfer);
2881		dev_err(dev, "Message alloc failed(%d)\n", ret);
2882		return ret;
2883	}
2884	req = (struct ti_sci_msg_req_proc_request *)xfer->xfer_buf;
2885	req->processor_id = proc_id;
2886
2887	ret = ti_sci_do_xfer(info, xfer);
2888	if (ret) {
2889		dev_err(dev, "Mbox send fail %d\n", ret);
2890		goto fail;
2891	}
2892
2893	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
2894
2895	ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
2896
2897fail:
2898	ti_sci_put_one_xfer(&info->minfo, xfer);
2899
2900	return ret;
2901}
2902
2903/**
2904 * ti_sci_cmd_proc_release() - Command to release a physical processor control
2905 * @handle:	Pointer to TI SCI handle
2906 * @proc_id:	Processor ID this request is for
2907 *
2908 * Return: 0 if all went well, else returns appropriate error value.
2909 */
2910static int ti_sci_cmd_proc_release(const struct ti_sci_handle *handle,
2911				   u8 proc_id)
2912{
2913	struct ti_sci_msg_req_proc_release *req;
2914	struct ti_sci_msg_hdr *resp;
2915	struct ti_sci_info *info;
2916	struct ti_sci_xfer *xfer;
2917	struct device *dev;
2918	int ret = 0;
2919
2920	if (!handle)
2921		return -EINVAL;
2922	if (IS_ERR(handle))
2923		return PTR_ERR(handle);
2924
2925	info = handle_to_ti_sci_info(handle);
2926	dev = info->dev;
2927
2928	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PROC_RELEASE,
2929				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2930				   sizeof(*req), sizeof(*resp));
2931	if (IS_ERR(xfer)) {
2932		ret = PTR_ERR(xfer);
2933		dev_err(dev, "Message alloc failed(%d)\n", ret);
2934		return ret;
2935	}
2936	req = (struct ti_sci_msg_req_proc_release *)xfer->xfer_buf;
2937	req->processor_id = proc_id;
2938
2939	ret = ti_sci_do_xfer(info, xfer);
2940	if (ret) {
2941		dev_err(dev, "Mbox send fail %d\n", ret);
2942		goto fail;
2943	}
2944
2945	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
2946
2947	ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
2948
2949fail:
2950	ti_sci_put_one_xfer(&info->minfo, xfer);
2951
2952	return ret;
2953}
2954
2955/**
2956 * ti_sci_cmd_proc_handover() - Command to handover a physical processor
2957 *				control to a host in the processor's access
2958 *				control list.
2959 * @handle:	Pointer to TI SCI handle
2960 * @proc_id:	Processor ID this request is for
2961 * @host_id:	Host ID to get the control of the processor
2962 *
2963 * Return: 0 if all went well, else returns appropriate error value.
2964 */
2965static int ti_sci_cmd_proc_handover(const struct ti_sci_handle *handle,
2966				    u8 proc_id, u8 host_id)
2967{
2968	struct ti_sci_msg_req_proc_handover *req;
2969	struct ti_sci_msg_hdr *resp;
2970	struct ti_sci_info *info;
2971	struct ti_sci_xfer *xfer;
2972	struct device *dev;
2973	int ret = 0;
2974
2975	if (!handle)
2976		return -EINVAL;
2977	if (IS_ERR(handle))
2978		return PTR_ERR(handle);
2979
2980	info = handle_to_ti_sci_info(handle);
2981	dev = info->dev;
2982
2983	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PROC_HANDOVER,
2984				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
2985				   sizeof(*req), sizeof(*resp));
2986	if (IS_ERR(xfer)) {
2987		ret = PTR_ERR(xfer);
2988		dev_err(dev, "Message alloc failed(%d)\n", ret);
2989		return ret;
2990	}
2991	req = (struct ti_sci_msg_req_proc_handover *)xfer->xfer_buf;
2992	req->processor_id = proc_id;
2993	req->host_id = host_id;
2994
2995	ret = ti_sci_do_xfer(info, xfer);
2996	if (ret) {
2997		dev_err(dev, "Mbox send fail %d\n", ret);
2998		goto fail;
2999	}
3000
3001	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
3002
3003	ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
3004
3005fail:
3006	ti_sci_put_one_xfer(&info->minfo, xfer);
3007
3008	return ret;
3009}
3010
3011/**
3012 * ti_sci_cmd_proc_set_config() - Command to set the processor boot
3013 *				    configuration flags
3014 * @handle:		Pointer to TI SCI handle
3015 * @proc_id:		Processor ID this request is for
3016 * @bootvector:		Processor Boot vector (start address)
3017 * @config_flags_set:	Configuration flags to be set
3018 * @config_flags_clear:	Configuration flags to be cleared.
3019 *
3020 * Return: 0 if all went well, else returns appropriate error value.
3021 */
3022static int ti_sci_cmd_proc_set_config(const struct ti_sci_handle *handle,
3023				      u8 proc_id, u64 bootvector,
3024				      u32 config_flags_set,
3025				      u32 config_flags_clear)
3026{
3027	struct ti_sci_msg_req_set_config *req;
3028	struct ti_sci_msg_hdr *resp;
3029	struct ti_sci_info *info;
3030	struct ti_sci_xfer *xfer;
3031	struct device *dev;
3032	int ret = 0;
3033
3034	if (!handle)
3035		return -EINVAL;
3036	if (IS_ERR(handle))
3037		return PTR_ERR(handle);
3038
3039	info = handle_to_ti_sci_info(handle);
3040	dev = info->dev;
3041
3042	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CONFIG,
3043				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
3044				   sizeof(*req), sizeof(*resp));
3045	if (IS_ERR(xfer)) {
3046		ret = PTR_ERR(xfer);
3047		dev_err(dev, "Message alloc failed(%d)\n", ret);
3048		return ret;
3049	}
3050	req = (struct ti_sci_msg_req_set_config *)xfer->xfer_buf;
3051	req->processor_id = proc_id;
3052	req->bootvector_low = bootvector & TI_SCI_ADDR_LOW_MASK;
3053	req->bootvector_high = (bootvector & TI_SCI_ADDR_HIGH_MASK) >>
3054				TI_SCI_ADDR_HIGH_SHIFT;
3055	req->config_flags_set = config_flags_set;
3056	req->config_flags_clear = config_flags_clear;
3057
3058	ret = ti_sci_do_xfer(info, xfer);
3059	if (ret) {
3060		dev_err(dev, "Mbox send fail %d\n", ret);
3061		goto fail;
3062	}
3063
3064	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
3065
3066	ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
3067
3068fail:
3069	ti_sci_put_one_xfer(&info->minfo, xfer);
3070
3071	return ret;
3072}
3073
3074/**
3075 * ti_sci_cmd_proc_set_control() - Command to set the processor boot
3076 *				     control flags
3077 * @handle:			Pointer to TI SCI handle
3078 * @proc_id:			Processor ID this request is for
3079 * @control_flags_set:		Control flags to be set
3080 * @control_flags_clear:	Control flags to be cleared
3081 *
3082 * Return: 0 if all went well, else returns appropriate error value.
3083 */
3084static int ti_sci_cmd_proc_set_control(const struct ti_sci_handle *handle,
3085				       u8 proc_id, u32 control_flags_set,
3086				       u32 control_flags_clear)
3087{
3088	struct ti_sci_msg_req_set_ctrl *req;
3089	struct ti_sci_msg_hdr *resp;
3090	struct ti_sci_info *info;
3091	struct ti_sci_xfer *xfer;
3092	struct device *dev;
3093	int ret = 0;
3094
3095	if (!handle)
3096		return -EINVAL;
3097	if (IS_ERR(handle))
3098		return PTR_ERR(handle);
3099
3100	info = handle_to_ti_sci_info(handle);
3101	dev = info->dev;
3102
3103	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CTRL,
3104				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
3105				   sizeof(*req), sizeof(*resp));
3106	if (IS_ERR(xfer)) {
3107		ret = PTR_ERR(xfer);
3108		dev_err(dev, "Message alloc failed(%d)\n", ret);
3109		return ret;
3110	}
3111	req = (struct ti_sci_msg_req_set_ctrl *)xfer->xfer_buf;
3112	req->processor_id = proc_id;
3113	req->control_flags_set = control_flags_set;
3114	req->control_flags_clear = control_flags_clear;
3115
3116	ret = ti_sci_do_xfer(info, xfer);
3117	if (ret) {
3118		dev_err(dev, "Mbox send fail %d\n", ret);
3119		goto fail;
3120	}
3121
3122	resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf;
3123
3124	ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
3125
3126fail:
3127	ti_sci_put_one_xfer(&info->minfo, xfer);
3128
3129	return ret;
3130}
3131
3132/**
3133 * ti_sci_cmd_proc_get_status() - Command to get the processor boot status
3134 * @handle:	Pointer to TI SCI handle
3135 * @proc_id:	Processor ID this request is for
3136 * @bv:		Processor Boot vector (start address)
3137 * @cfg_flags:	Processor specific configuration flags
3138 * @ctrl_flags:	Processor specific control flags
3139 * @sts_flags:	Processor specific status flags
3140 *
3141 * Return: 0 if all went well, else returns appropriate error value.
3142 */
3143static int ti_sci_cmd_proc_get_status(const struct ti_sci_handle *handle,
3144				      u8 proc_id, u64 *bv, u32 *cfg_flags,
3145				      u32 *ctrl_flags, u32 *sts_flags)
3146{
3147	struct ti_sci_msg_resp_get_status *resp;
3148	struct ti_sci_msg_req_get_status *req;
3149	struct ti_sci_info *info;
3150	struct ti_sci_xfer *xfer;
3151	struct device *dev;
3152	int ret = 0;
3153
3154	if (!handle)
3155		return -EINVAL;
3156	if (IS_ERR(handle))
3157		return PTR_ERR(handle);
3158
3159	info = handle_to_ti_sci_info(handle);
3160	dev = info->dev;
3161
3162	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_STATUS,
3163				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
3164				   sizeof(*req), sizeof(*resp));
3165	if (IS_ERR(xfer)) {
3166		ret = PTR_ERR(xfer);
3167		dev_err(dev, "Message alloc failed(%d)\n", ret);
3168		return ret;
3169	}
3170	req = (struct ti_sci_msg_req_get_status *)xfer->xfer_buf;
3171	req->processor_id = proc_id;
3172
3173	ret = ti_sci_do_xfer(info, xfer);
3174	if (ret) {
3175		dev_err(dev, "Mbox send fail %d\n", ret);
3176		goto fail;
3177	}
3178
3179	resp = (struct ti_sci_msg_resp_get_status *)xfer->tx_message.buf;
3180
3181	if (!ti_sci_is_response_ack(resp)) {
3182		ret = -ENODEV;
3183	} else {
3184		*bv = (resp->bootvector_low & TI_SCI_ADDR_LOW_MASK) |
3185		      (((u64)resp->bootvector_high << TI_SCI_ADDR_HIGH_SHIFT) &
3186		       TI_SCI_ADDR_HIGH_MASK);
3187		*cfg_flags = resp->config_flags;
3188		*ctrl_flags = resp->control_flags;
3189		*sts_flags = resp->status_flags;
3190	}
3191
3192fail:
3193	ti_sci_put_one_xfer(&info->minfo, xfer);
3194
3195	return ret;
3196}
3197
3198/*
3199 * ti_sci_setup_ops() - Setup the operations structures
3200 * @info:	pointer to TISCI pointer
3201 */
3202static void ti_sci_setup_ops(struct ti_sci_info *info)
3203{
3204	struct ti_sci_ops *ops = &info->handle.ops;
3205	struct ti_sci_core_ops *core_ops = &ops->core_ops;
3206	struct ti_sci_dev_ops *dops = &ops->dev_ops;
3207	struct ti_sci_clk_ops *cops = &ops->clk_ops;
3208	struct ti_sci_pm_ops *pmops = &ops->pm_ops;
3209	struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops;
3210	struct ti_sci_rm_irq_ops *iops = &ops->rm_irq_ops;
3211	struct ti_sci_rm_ringacc_ops *rops = &ops->rm_ring_ops;
3212	struct ti_sci_rm_psil_ops *psilops = &ops->rm_psil_ops;
3213	struct ti_sci_rm_udmap_ops *udmap_ops = &ops->rm_udmap_ops;
3214	struct ti_sci_proc_ops *pops = &ops->proc_ops;
3215
3216	core_ops->reboot_device = ti_sci_cmd_core_reboot;
3217
3218	dops->get_device = ti_sci_cmd_get_device;
3219	dops->get_device_exclusive = ti_sci_cmd_get_device_exclusive;
3220	dops->idle_device = ti_sci_cmd_idle_device;
3221	dops->idle_device_exclusive = ti_sci_cmd_idle_device_exclusive;
3222	dops->put_device = ti_sci_cmd_put_device;
3223
3224	dops->is_valid = ti_sci_cmd_dev_is_valid;
3225	dops->get_context_loss_count = ti_sci_cmd_dev_get_clcnt;
3226	dops->is_idle = ti_sci_cmd_dev_is_idle;
3227	dops->is_stop = ti_sci_cmd_dev_is_stop;
3228	dops->is_on = ti_sci_cmd_dev_is_on;
3229	dops->is_transitioning = ti_sci_cmd_dev_is_trans;
3230	dops->set_device_resets = ti_sci_cmd_set_device_resets;
3231	dops->get_device_resets = ti_sci_cmd_get_device_resets;
3232
3233	cops->get_clock = ti_sci_cmd_get_clock;
3234	cops->idle_clock = ti_sci_cmd_idle_clock;
3235	cops->put_clock = ti_sci_cmd_put_clock;
3236	cops->is_auto = ti_sci_cmd_clk_is_auto;
3237	cops->is_on = ti_sci_cmd_clk_is_on;
3238	cops->is_off = ti_sci_cmd_clk_is_off;
3239
3240	cops->set_parent = ti_sci_cmd_clk_set_parent;
3241	cops->get_parent = ti_sci_cmd_clk_get_parent;
3242	cops->get_num_parents = ti_sci_cmd_clk_get_num_parents;
3243
3244	cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq;
3245	cops->set_freq = ti_sci_cmd_clk_set_freq;
3246	cops->get_freq = ti_sci_cmd_clk_get_freq;
3247
3248	if (info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
3249		pr_debug("detected DM managed LPM in fw_caps\n");
3250		pmops->lpm_wake_reason = ti_sci_msg_cmd_lpm_wake_reason;
3251		pmops->set_device_constraint = ti_sci_cmd_set_device_constraint;
3252		pmops->set_latency_constraint = ti_sci_cmd_set_latency_constraint;
3253	}
3254
3255	rm_core_ops->get_range = ti_sci_cmd_get_resource_range;
3256	rm_core_ops->get_range_from_shost =
3257				ti_sci_cmd_get_resource_range_from_shost;
3258
3259	iops->set_irq = ti_sci_cmd_set_irq;
3260	iops->set_event_map = ti_sci_cmd_set_event_map;
3261	iops->free_irq = ti_sci_cmd_free_irq;
3262	iops->free_event_map = ti_sci_cmd_free_event_map;
3263
3264	rops->set_cfg = ti_sci_cmd_rm_ring_cfg;
3265
3266	psilops->pair = ti_sci_cmd_rm_psil_pair;
3267	psilops->unpair = ti_sci_cmd_rm_psil_unpair;
3268
3269	udmap_ops->tx_ch_cfg = ti_sci_cmd_rm_udmap_tx_ch_cfg;
3270	udmap_ops->rx_ch_cfg = ti_sci_cmd_rm_udmap_rx_ch_cfg;
3271	udmap_ops->rx_flow_cfg = ti_sci_cmd_rm_udmap_rx_flow_cfg;
3272
3273	pops->request = ti_sci_cmd_proc_request;
3274	pops->release = ti_sci_cmd_proc_release;
3275	pops->handover = ti_sci_cmd_proc_handover;
3276	pops->set_config = ti_sci_cmd_proc_set_config;
3277	pops->set_control = ti_sci_cmd_proc_set_control;
3278	pops->get_status = ti_sci_cmd_proc_get_status;
3279}
3280
3281/**
3282 * ti_sci_get_handle() - Get the TI SCI handle for a device
3283 * @dev:	Pointer to device for which we want SCI handle
3284 *
3285 * NOTE: The function does not track individual clients of the framework
3286 * and is expected to be maintained by caller of TI SCI protocol library.
3287 * ti_sci_put_handle must be balanced with successful ti_sci_get_handle
3288 * Return: pointer to handle if successful, else:
3289 * -EPROBE_DEFER if the instance is not ready
3290 * -ENODEV if the required node handler is missing
3291 * -EINVAL if invalid conditions are encountered.
3292 */
3293const struct ti_sci_handle *ti_sci_get_handle(struct device *dev)
3294{
3295	struct device_node *ti_sci_np;
3296	struct ti_sci_handle *handle = NULL;
3297	struct ti_sci_info *info;
3298
3299	if (!dev) {
3300		pr_err("I need a device pointer\n");
3301		return ERR_PTR(-EINVAL);
3302	}
3303	ti_sci_np = of_get_parent(dev->of_node);
3304	if (!ti_sci_np) {
3305		dev_err(dev, "No OF information\n");
3306		return ERR_PTR(-EINVAL);
3307	}
3308
3309	mutex_lock(&ti_sci_list_mutex);
3310	list_for_each_entry(info, &ti_sci_list, node) {
3311		if (ti_sci_np == info->dev->of_node) {
3312			handle = &info->handle;
3313			info->users++;
3314			break;
3315		}
3316	}
3317	mutex_unlock(&ti_sci_list_mutex);
3318	of_node_put(ti_sci_np);
3319
3320	if (!handle)
3321		return ERR_PTR(-EPROBE_DEFER);
3322
3323	return handle;
3324}
3325EXPORT_SYMBOL_GPL(ti_sci_get_handle);
3326
3327/**
3328 * ti_sci_put_handle() - Release the handle acquired by ti_sci_get_handle
3329 * @handle:	Handle acquired by ti_sci_get_handle
3330 *
3331 * NOTE: The function does not track individual clients of the framework
3332 * and is expected to be maintained by caller of TI SCI protocol library.
3333 * ti_sci_put_handle must be balanced with successful ti_sci_get_handle
3334 *
3335 * Return: 0 is successfully released
3336 * if an error pointer was passed, it returns the error value back,
3337 * if null was passed, it returns -EINVAL;
3338 */
3339int ti_sci_put_handle(const struct ti_sci_handle *handle)
3340{
3341	struct ti_sci_info *info;
3342
3343	if (IS_ERR(handle))
3344		return PTR_ERR(handle);
3345	if (!handle)
3346		return -EINVAL;
3347
3348	info = handle_to_ti_sci_info(handle);
3349	mutex_lock(&ti_sci_list_mutex);
3350	if (!WARN_ON(!info->users))
3351		info->users--;
3352	mutex_unlock(&ti_sci_list_mutex);
3353
3354	return 0;
3355}
3356EXPORT_SYMBOL_GPL(ti_sci_put_handle);
3357
3358static void devm_ti_sci_release(struct device *dev, void *res)
3359{
3360	const struct ti_sci_handle **ptr = res;
3361	const struct ti_sci_handle *handle = *ptr;
3362	int ret;
3363
3364	ret = ti_sci_put_handle(handle);
3365	if (ret)
3366		dev_err(dev, "failed to put handle %d\n", ret);
3367}
3368
3369/**
3370 * devm_ti_sci_get_handle() - Managed get handle
3371 * @dev:	device for which we want SCI handle for.
3372 *
3373 * NOTE: This releases the handle once the device resources are
3374 * no longer needed. MUST NOT BE released with ti_sci_put_handle.
3375 * The function does not track individual clients of the framework
3376 * and is expected to be maintained by caller of TI SCI protocol library.
3377 *
3378 * Return: 0 if all went fine, else corresponding error.
3379 */
3380const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev)
3381{
3382	const struct ti_sci_handle **ptr;
3383	const struct ti_sci_handle *handle;
3384
3385	ptr = devres_alloc(devm_ti_sci_release, sizeof(*ptr), GFP_KERNEL);
3386	if (!ptr)
3387		return ERR_PTR(-ENOMEM);
3388	handle = ti_sci_get_handle(dev);
3389
3390	if (!IS_ERR(handle)) {
3391		*ptr = handle;
3392		devres_add(dev, ptr);
3393	} else {
3394		devres_free(ptr);
3395	}
3396
3397	return handle;
3398}
3399EXPORT_SYMBOL_GPL(devm_ti_sci_get_handle);
3400
3401/**
3402 * ti_sci_get_by_phandle() - Get the TI SCI handle using DT phandle
3403 * @np:		device node
3404 * @property:	property name containing phandle on TISCI node
3405 *
3406 * NOTE: The function does not track individual clients of the framework
3407 * and is expected to be maintained by caller of TI SCI protocol library.
3408 * ti_sci_put_handle must be balanced with successful ti_sci_get_by_phandle
3409 * Return: pointer to handle if successful, else:
3410 * -EPROBE_DEFER if the instance is not ready
3411 * -ENODEV if the required node handler is missing
3412 * -EINVAL if invalid conditions are encountered.
3413 */
3414const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np,
3415						  const char *property)
3416{
3417	struct ti_sci_handle *handle = NULL;
3418	struct device_node *ti_sci_np;
3419	struct ti_sci_info *info;
3420
3421	if (!np) {
3422		pr_err("I need a device pointer\n");
3423		return ERR_PTR(-EINVAL);
3424	}
3425
3426	ti_sci_np = of_parse_phandle(np, property, 0);
3427	if (!ti_sci_np)
3428		return ERR_PTR(-ENODEV);
3429
3430	mutex_lock(&ti_sci_list_mutex);
3431	list_for_each_entry(info, &ti_sci_list, node) {
3432		if (ti_sci_np == info->dev->of_node) {
3433			handle = &info->handle;
3434			info->users++;
3435			break;
3436		}
3437	}
3438	mutex_unlock(&ti_sci_list_mutex);
3439	of_node_put(ti_sci_np);
3440
3441	if (!handle)
3442		return ERR_PTR(-EPROBE_DEFER);
3443
3444	return handle;
3445}
3446EXPORT_SYMBOL_GPL(ti_sci_get_by_phandle);
3447
3448/**
3449 * devm_ti_sci_get_by_phandle() - Managed get handle using phandle
3450 * @dev:	Device pointer requesting TISCI handle
3451 * @property:	property name containing phandle on TISCI node
3452 *
3453 * NOTE: This releases the handle once the device resources are
3454 * no longer needed. MUST NOT BE released with ti_sci_put_handle.
3455 * The function does not track individual clients of the framework
3456 * and is expected to be maintained by caller of TI SCI protocol library.
3457 *
3458 * Return: 0 if all went fine, else corresponding error.
3459 */
3460const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev,
3461						       const char *property)
3462{
3463	const struct ti_sci_handle *handle;
3464	const struct ti_sci_handle **ptr;
3465
3466	ptr = devres_alloc(devm_ti_sci_release, sizeof(*ptr), GFP_KERNEL);
3467	if (!ptr)
3468		return ERR_PTR(-ENOMEM);
3469	handle = ti_sci_get_by_phandle(dev_of_node(dev), property);
3470
3471	if (!IS_ERR(handle)) {
3472		*ptr = handle;
3473		devres_add(dev, ptr);
3474	} else {
3475		devres_free(ptr);
3476	}
3477
3478	return handle;
3479}
3480EXPORT_SYMBOL_GPL(devm_ti_sci_get_by_phandle);
3481
3482/**
3483 * ti_sci_get_free_resource() - Get a free resource from TISCI resource.
3484 * @res:	Pointer to the TISCI resource
3485 *
3486 * Return: resource num if all went ok else TI_SCI_RESOURCE_NULL.
3487 */
3488u16 ti_sci_get_free_resource(struct ti_sci_resource *res)
3489{
3490	unsigned long flags;
3491	u16 set, free_bit;
3492
3493	raw_spin_lock_irqsave(&res->lock, flags);
3494	for (set = 0; set < res->sets; set++) {
3495		struct ti_sci_resource_desc *desc = &res->desc[set];
3496		int res_count = desc->num + desc->num_sec;
3497
3498		free_bit = find_first_zero_bit(desc->res_map, res_count);
3499		if (free_bit != res_count) {
3500			__set_bit(free_bit, desc->res_map);
3501			raw_spin_unlock_irqrestore(&res->lock, flags);
3502
3503			if (desc->num && free_bit < desc->num)
3504				return desc->start + free_bit;
3505			else
3506				return desc->start_sec + free_bit;
3507		}
3508	}
3509	raw_spin_unlock_irqrestore(&res->lock, flags);
3510
3511	return TI_SCI_RESOURCE_NULL;
3512}
3513EXPORT_SYMBOL_GPL(ti_sci_get_free_resource);
3514
3515/**
3516 * ti_sci_release_resource() - Release a resource from TISCI resource.
3517 * @res:	Pointer to the TISCI resource
3518 * @id:		Resource id to be released.
3519 */
3520void ti_sci_release_resource(struct ti_sci_resource *res, u16 id)
3521{
3522	unsigned long flags;
3523	u16 set;
3524
3525	raw_spin_lock_irqsave(&res->lock, flags);
3526	for (set = 0; set < res->sets; set++) {
3527		struct ti_sci_resource_desc *desc = &res->desc[set];
3528
3529		if (desc->num && desc->start <= id &&
3530		    (desc->start + desc->num) > id)
3531			__clear_bit(id - desc->start, desc->res_map);
3532		else if (desc->num_sec && desc->start_sec <= id &&
3533			 (desc->start_sec + desc->num_sec) > id)
3534			__clear_bit(id - desc->start_sec, desc->res_map);
3535	}
3536	raw_spin_unlock_irqrestore(&res->lock, flags);
3537}
3538EXPORT_SYMBOL_GPL(ti_sci_release_resource);
3539
3540/**
3541 * ti_sci_get_num_resources() - Get the number of resources in TISCI resource
3542 * @res:	Pointer to the TISCI resource
3543 *
3544 * Return: Total number of available resources.
3545 */
3546u32 ti_sci_get_num_resources(struct ti_sci_resource *res)
3547{
3548	u32 set, count = 0;
3549
3550	for (set = 0; set < res->sets; set++)
3551		count += res->desc[set].num + res->desc[set].num_sec;
3552
3553	return count;
3554}
3555EXPORT_SYMBOL_GPL(ti_sci_get_num_resources);
3556
3557/**
3558 * devm_ti_sci_get_resource_sets() - Get a TISCI resources assigned to a device
3559 * @handle:	TISCI handle
3560 * @dev:	Device pointer to which the resource is assigned
3561 * @dev_id:	TISCI device id to which the resource is assigned
3562 * @sub_types:	Array of sub_types assigned corresponding to device
3563 * @sets:	Number of sub_types
3564 *
3565 * Return: Pointer to ti_sci_resource if all went well else appropriate
3566 *	   error pointer.
3567 */
3568static struct ti_sci_resource *
3569devm_ti_sci_get_resource_sets(const struct ti_sci_handle *handle,
3570			      struct device *dev, u32 dev_id, u32 *sub_types,
3571			      u32 sets)
3572{
3573	struct ti_sci_resource *res;
3574	bool valid_set = false;
3575	int i, ret, res_count;
3576
3577	res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
3578	if (!res)
3579		return ERR_PTR(-ENOMEM);
3580
3581	res->sets = sets;
3582	res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc),
3583				 GFP_KERNEL);
3584	if (!res->desc)
3585		return ERR_PTR(-ENOMEM);
3586
3587	for (i = 0; i < res->sets; i++) {
3588		ret = handle->ops.rm_core_ops.get_range(handle, dev_id,
3589							sub_types[i],
3590							&res->desc[i]);
3591		if (ret) {
3592			dev_dbg(dev, "dev = %d subtype %d not allocated for this host\n",
3593				dev_id, sub_types[i]);
3594			memset(&res->desc[i], 0, sizeof(res->desc[i]));
3595			continue;
3596		}
3597
3598		dev_dbg(dev, "dev/sub_type: %d/%d, start/num: %d/%d | %d/%d\n",
3599			dev_id, sub_types[i], res->desc[i].start,
3600			res->desc[i].num, res->desc[i].start_sec,
3601			res->desc[i].num_sec);
3602
3603		valid_set = true;
3604		res_count = res->desc[i].num + res->desc[i].num_sec;
3605		res->desc[i].res_map = devm_bitmap_zalloc(dev, res_count,
3606							  GFP_KERNEL);
3607		if (!res->desc[i].res_map)
3608			return ERR_PTR(-ENOMEM);
3609	}
3610	raw_spin_lock_init(&res->lock);
3611
3612	if (valid_set)
3613		return res;
3614
3615	return ERR_PTR(-EINVAL);
3616}
3617
3618/**
3619 * devm_ti_sci_get_of_resource() - Get a TISCI resource assigned to a device
3620 * @handle:	TISCI handle
3621 * @dev:	Device pointer to which the resource is assigned
3622 * @dev_id:	TISCI device id to which the resource is assigned
3623 * @of_prop:	property name by which the resource are represented
3624 *
3625 * Return: Pointer to ti_sci_resource if all went well else appropriate
3626 *	   error pointer.
3627 */
3628struct ti_sci_resource *
3629devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
3630			    struct device *dev, u32 dev_id, char *of_prop)
3631{
3632	struct ti_sci_resource *res;
3633	u32 *sub_types;
3634	int sets;
3635
3636	sets = of_property_count_elems_of_size(dev_of_node(dev), of_prop,
3637					       sizeof(u32));
3638	if (sets < 0) {
3639		dev_err(dev, "%s resource type ids not available\n", of_prop);
3640		return ERR_PTR(sets);
3641	}
3642
3643	sub_types = kcalloc(sets, sizeof(*sub_types), GFP_KERNEL);
3644	if (!sub_types)
3645		return ERR_PTR(-ENOMEM);
3646
3647	of_property_read_u32_array(dev_of_node(dev), of_prop, sub_types, sets);
3648	res = devm_ti_sci_get_resource_sets(handle, dev, dev_id, sub_types,
3649					    sets);
3650
3651	kfree(sub_types);
3652	return res;
3653}
3654EXPORT_SYMBOL_GPL(devm_ti_sci_get_of_resource);
3655
3656/**
3657 * devm_ti_sci_get_resource() - Get a resource range assigned to the device
3658 * @handle:	TISCI handle
3659 * @dev:	Device pointer to which the resource is assigned
3660 * @dev_id:	TISCI device id to which the resource is assigned
3661 * @sub_type:	TISCI resource subytpe representing the resource.
3662 *
3663 * Return: Pointer to ti_sci_resource if all went well else appropriate
3664 *	   error pointer.
3665 */
3666struct ti_sci_resource *
3667devm_ti_sci_get_resource(const struct ti_sci_handle *handle, struct device *dev,
3668			 u32 dev_id, u32 sub_type)
3669{
3670	return devm_ti_sci_get_resource_sets(handle, dev, dev_id, &sub_type, 1);
3671}
3672EXPORT_SYMBOL_GPL(devm_ti_sci_get_resource);
3673
3674/*
3675 * Iterate all device nodes that have a wakeup-source property and check if one
3676 * of the possible phandles points to a Partial-IO system state. If it
3677 * does resolve the device node to an actual device and check if wakeup is
3678 * enabled.
3679 */
3680static bool ti_sci_partial_io_wakeup_enabled(struct ti_sci_info *info)
3681{
3682	struct device_node *wakeup_node = NULL;
3683
3684	for_each_node_with_property(wakeup_node, "wakeup-source") {
3685		struct of_phandle_iterator it;
3686		int err;
3687
3688		of_for_each_phandle(&it, err, wakeup_node, "wakeup-source", NULL, 0) {
3689			struct platform_device *pdev;
3690			bool may_wakeup;
3691
3692			/*
3693			 * Continue if idle-state-name is not off-wake. Return
3694			 * value is the index of the string which should be 0 if
3695			 * off-wake is present.
3696			 */
3697			if (of_property_match_string(it.node, "idle-state-name", "off-wake"))
3698				continue;
3699
3700			pdev = of_find_device_by_node(wakeup_node);
3701			if (!pdev)
3702				continue;
3703
3704			may_wakeup = device_may_wakeup(&pdev->dev);
3705			put_device(&pdev->dev);
3706
3707			if (may_wakeup) {
3708				dev_dbg(info->dev, "%pOF identified as wakeup source for Partial-IO\n",
3709					wakeup_node);
3710				of_node_put(it.node);
3711				of_node_put(wakeup_node);
3712				return true;
3713			}
3714		}
3715	}
3716
3717	return false;
3718}
3719
3720static int ti_sci_sys_off_handler(struct sys_off_data *data)
3721{
3722	struct ti_sci_info *info = data->cb_data;
3723	const struct ti_sci_handle *handle = &info->handle;
3724	bool enter_partial_io = ti_sci_partial_io_wakeup_enabled(info);
3725	int ret;
3726
3727	if (!enter_partial_io)
3728		return NOTIFY_DONE;
3729
3730	dev_info(info->dev, "Entering Partial-IO because a powered wakeup-enabled device was found.\n");
3731
3732	ret = ti_sci_cmd_prepare_sleep(handle, TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO, 0, 0, 0);
3733	if (ret) {
3734		dev_err(info->dev,
3735			"Failed to enter Partial-IO %pe, trying to do an emergency restart\n",
3736			ERR_PTR(ret));
3737		emergency_restart();
3738	}
3739
3740	mdelay(5000);
3741	emergency_restart();
3742
3743	return NOTIFY_DONE;
3744}
3745
3746static int tisci_reboot_handler(struct sys_off_data *data)
3747{
3748	struct ti_sci_info *info = data->cb_data;
3749	const struct ti_sci_handle *handle = &info->handle;
3750
3751	ti_sci_cmd_core_reboot(handle);
3752
3753	/* call fail OR pass, we should not be here in the first place */
3754	return NOTIFY_BAD;
3755}
3756
3757static int ti_sci_prepare_system_suspend(struct ti_sci_info *info)
3758{
3759	/*
3760	 * Map and validate the target Linux suspend state to TISCI LPM.
3761	 * Default is to let Device Manager select the low power mode.
3762	 */
3763	switch (pm_suspend_target_state) {
3764	case PM_SUSPEND_MEM:
3765		if (info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
3766			/*
3767			 * For the DM_MANAGED mode the context is reserved for
3768			 * internal use and can be 0
3769			 */
3770			return ti_sci_cmd_prepare_sleep(&info->handle,
3771							TISCI_MSG_VALUE_SLEEP_MODE_DM_MANAGED,
3772							0, 0, 0);
3773		} else {
3774			/* DM Managed is not supported by the firmware. */
3775			dev_err(info->dev, "Suspend to memory is not supported by the firmware\n");
3776			return -EOPNOTSUPP;
3777		}
3778		break;
3779	default:
3780		/*
3781		 * Do not fail if we don't have action to take for a
3782		 * specific suspend mode.
3783		 */
3784		return 0;
3785	}
3786}
3787
3788static int ti_sci_suspend(struct device *dev)
3789{
3790	struct ti_sci_info *info = dev_get_drvdata(dev);
3791	struct device *cpu_dev, *cpu_dev_max = NULL;
3792	s32 val, cpu_lat = 0;
3793	u16 cpu_lat_ms;
3794	int i, ret;
3795
3796	if (info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
3797		for_each_possible_cpu(i) {
3798			cpu_dev = get_cpu_device(i);
3799			val = dev_pm_qos_read_value(cpu_dev, DEV_PM_QOS_RESUME_LATENCY);
3800			if (val != PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) {
3801				cpu_lat = max(cpu_lat, val);
3802				cpu_dev_max = cpu_dev;
3803			}
3804		}
3805		if (cpu_dev_max) {
3806			/*
3807			 * PM QoS latency unit is usecs, device manager uses msecs.
3808			 * Convert to msecs and round down for device manager.
3809			 */
3810			cpu_lat_ms = cpu_lat / USEC_PER_MSEC;
3811			dev_dbg(cpu_dev_max, "%s: sending max CPU latency=%u ms\n", __func__,
3812				cpu_lat_ms);
3813			ret = ti_sci_cmd_set_latency_constraint(&info->handle,
3814								cpu_lat_ms,
3815								TISCI_MSG_CONSTRAINT_SET);
3816			if (ret)
3817				return ret;
3818		}
3819	}
3820
3821	ret = ti_sci_prepare_system_suspend(info);
3822	if (ret)
3823		return ret;
3824
3825	return 0;
3826}
3827
3828static int ti_sci_suspend_noirq(struct device *dev)
3829{
3830	struct ti_sci_info *info = dev_get_drvdata(dev);
3831	int ret = 0;
3832
3833	if (info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION) {
3834		ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_ENABLE);
3835		if (ret)
3836			return ret;
3837	}
3838
3839	return 0;
3840}
3841
3842static int ti_sci_resume_noirq(struct device *dev)
3843{
3844	struct ti_sci_info *info = dev_get_drvdata(dev);
3845	int ret = 0;
3846	u32 source;
3847	u64 time;
3848	u8 pin;
3849	u8 mode;
3850
3851	if (info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION) {
3852		ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_DISABLE);
3853		if (ret)
3854			return ret;
3855	}
3856
3857	ret = ti_sci_msg_cmd_lpm_wake_reason(&info->handle, &source, &time, &pin, &mode);
3858	/* Do not fail to resume on error as the wake reason is not critical */
3859	if (!ret)
3860		dev_info(dev, "ti_sci: wakeup source:0x%x, pin:0x%x, mode:0x%x\n",
3861			 source, pin, mode);
3862
3863	return 0;
3864}
3865
3866static void ti_sci_pm_complete(struct device *dev)
3867{
3868	struct ti_sci_info *info = dev_get_drvdata(dev);
3869
3870	if (info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT) {
3871		if (ti_sci_cmd_lpm_abort(dev))
3872			dev_err(dev, "LPM clear selection failed.\n");
3873	}
3874}
3875
3876static const struct dev_pm_ops ti_sci_pm_ops = {
3877	.suspend = pm_sleep_ptr(ti_sci_suspend),
3878	.suspend_noirq = pm_sleep_ptr(ti_sci_suspend_noirq),
3879	.resume_noirq = pm_sleep_ptr(ti_sci_resume_noirq),
3880	.complete = pm_sleep_ptr(ti_sci_pm_complete),
3881};
3882
3883/* Description for K2G */
3884static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
3885	.default_host_id = 2,
3886	/* Conservative duration */
3887	.max_rx_timeout_ms = 1000,
3888	/* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
3889	.max_msgs = 20,
3890	.max_msg_size = 64,
3891};
3892
3893/* Description for AM654 */
3894static const struct ti_sci_desc ti_sci_pmmc_am654_desc = {
3895	.default_host_id = 12,
3896	/* Conservative duration */
3897	.max_rx_timeout_ms = 10000,
3898	/* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
3899	.max_msgs = 20,
3900	.max_msg_size = 60,
3901};
3902
3903static const struct of_device_id ti_sci_of_match[] = {
3904	{.compatible = "ti,k2g-sci", .data = &ti_sci_pmmc_k2g_desc},
3905	{.compatible = "ti,am654-sci", .data = &ti_sci_pmmc_am654_desc},
3906	{ /* Sentinel */ },
3907};
3908MODULE_DEVICE_TABLE(of, ti_sci_of_match);
3909
3910static int ti_sci_probe(struct platform_device *pdev)
3911{
3912	struct device *dev = &pdev->dev;
3913	const struct ti_sci_desc *desc;
3914	struct ti_sci_xfer *xfer;
3915	struct ti_sci_info *info = NULL;
3916	struct ti_sci_xfers_info *minfo;
3917	struct mbox_client *cl;
3918	int ret = -EINVAL;
3919	int i;
3920	u32 h_id;
3921
3922	desc = device_get_match_data(dev);
3923
3924	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
3925	if (!info)
3926		return -ENOMEM;
3927
3928	info->dev = dev;
3929	info->desc = desc;
3930	ret = of_property_read_u32(dev->of_node, "ti,host-id", &h_id);
3931	/* if the property is not present in DT, use a default from desc */
3932	if (ret < 0) {
3933		info->host_id = info->desc->default_host_id;
3934	} else {
3935		if (!h_id) {
3936			dev_warn(dev, "Host ID 0 is reserved for firmware\n");
3937			info->host_id = info->desc->default_host_id;
3938		} else {
3939			info->host_id = h_id;
3940		}
3941	}
3942
3943	INIT_LIST_HEAD(&info->node);
3944	minfo = &info->minfo;
3945
3946	/*
3947	 * Pre-allocate messages
3948	 * NEVER allocate more than what we can indicate in hdr.seq
3949	 * if we have data description bug, force a fix..
3950	 */
3951	if (WARN_ON(desc->max_msgs >=
3952		    1 << 8 * sizeof(((struct ti_sci_msg_hdr *)0)->seq)))
3953		return -EINVAL;
3954
3955	minfo->xfer_block = devm_kcalloc(dev,
3956					 desc->max_msgs,
3957					 sizeof(*minfo->xfer_block),
3958					 GFP_KERNEL);
3959	if (!minfo->xfer_block)
3960		return -ENOMEM;
3961
3962	minfo->xfer_alloc_table = devm_bitmap_zalloc(dev,
3963						     desc->max_msgs,
3964						     GFP_KERNEL);
3965	if (!minfo->xfer_alloc_table)
3966		return -ENOMEM;
3967
3968	/* Pre-initialize the buffer pointer to pre-allocated buffers */
3969	for (i = 0, xfer = minfo->xfer_block; i < desc->max_msgs; i++, xfer++) {
3970		xfer->xfer_buf = devm_kcalloc(dev, 1, desc->max_msg_size,
3971					      GFP_KERNEL);
3972		if (!xfer->xfer_buf)
3973			return -ENOMEM;
3974
3975		xfer->tx_message.buf = xfer->xfer_buf;
3976		init_completion(&xfer->done);
3977	}
3978
3979	ret = ti_sci_debugfs_create(pdev, info);
3980	if (ret)
3981		dev_warn(dev, "Failed to create debug file\n");
3982
3983	platform_set_drvdata(pdev, info);
3984
3985	cl = &info->cl;
3986	cl->dev = dev;
3987	cl->tx_block = false;
3988	cl->rx_callback = ti_sci_rx_callback;
3989	cl->knows_txdone = true;
3990
3991	spin_lock_init(&minfo->xfer_lock);
3992	sema_init(&minfo->sem_xfer_count, desc->max_msgs);
3993
3994	info->chan_rx = mbox_request_channel_byname(cl, "rx");
3995	if (IS_ERR(info->chan_rx)) {
3996		ret = PTR_ERR(info->chan_rx);
3997		goto out;
3998	}
3999
4000	info->chan_tx = mbox_request_channel_byname(cl, "tx");
4001	if (IS_ERR(info->chan_tx)) {
4002		ret = PTR_ERR(info->chan_tx);
4003		goto out;
4004	}
4005	ret = ti_sci_cmd_get_revision(info);
4006	if (ret) {
4007		dev_err(dev, "Unable to communicate with TISCI(%d)\n", ret);
4008		goto out;
4009	}
4010
4011	ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps);
4012	dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s\n",
4013		info->fw_caps & MSG_FLAG_CAPS_GENERIC ? "Generic" : "",
4014		info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO ? " Partial-IO" : "",
4015		info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ? " DM-Managed" : "",
4016		info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : "",
4017		info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ? " IO-Isolation" : ""
4018	);
4019
4020	ti_sci_setup_ops(info);
4021
4022	ret = devm_register_restart_handler(dev, tisci_reboot_handler, info);
4023	if (ret) {
4024		dev_err(dev, "reboot registration fail(%d)\n", ret);
4025		goto out;
4026	}
4027
4028	if (info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO) {
4029		ret = devm_register_sys_off_handler(dev,
4030						    SYS_OFF_MODE_POWER_OFF,
4031						    SYS_OFF_PRIO_FIRMWARE,
4032						    ti_sci_sys_off_handler,
4033						    info);
4034		if (ret) {
4035			dev_err(dev, "Failed to register sys_off_handler %pe\n",
4036				ERR_PTR(ret));
4037			goto out;
4038		}
4039	}
4040
4041	dev_info(dev, "ABI: %d.%d (firmware rev 0x%04x '%s')\n",
4042		 info->handle.version.abi_major, info->handle.version.abi_minor,
4043		 info->handle.version.firmware_revision,
4044		 info->handle.version.firmware_description);
4045
4046	mutex_lock(&ti_sci_list_mutex);
4047	list_add_tail(&info->node, &ti_sci_list);
4048	mutex_unlock(&ti_sci_list_mutex);
4049
4050	ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
4051	if (ret) {
4052		dev_err(dev, "platform_populate failed %pe\n", ERR_PTR(ret));
4053		goto out;
4054	}
4055	return 0;
4056
4057out:
4058	if (!IS_ERR(info->chan_tx))
4059		mbox_free_channel(info->chan_tx);
4060	if (!IS_ERR(info->chan_rx))
4061		mbox_free_channel(info->chan_rx);
4062	debugfs_remove(info->d);
4063	return ret;
4064}
4065
4066static struct platform_driver ti_sci_driver = {
4067	.probe = ti_sci_probe,
4068	.driver = {
4069		   .name = "ti-sci",
4070		   .of_match_table = ti_sci_of_match,
4071		   .suppress_bind_attrs = true,
4072		   .pm = &ti_sci_pm_ops,
4073	},
4074};
4075module_platform_driver(ti_sci_driver);
4076
4077MODULE_LICENSE("GPL v2");
4078MODULE_DESCRIPTION("TI System Control Interface(SCI) driver");
4079MODULE_AUTHOR("Nishanth Menon");
4080MODULE_ALIAS("platform:ti-sci");
~/ Read-only file preview.