int msm_smp2p_deinit_rmt_lpb_proc(int remote_pid)
{
	int ret = 0;
	int tmp;
	struct smp2p_loopback_ctx *ctx;

	if (remote_pid >= SMP2P_NUM_PROCS)
		return -EINVAL;

	ctx = &remote_loopback[remote_pid];

	
	remote_loopback[remote_pid].out_is_active = false;
	remote_loopback[remote_pid].in_is_active = false;
	flush_work(&ctx->rmt_lpb_work);

	
	tmp = msm_smp2p_out_close(&remote_loopback[remote_pid].out);
	remote_loopback[remote_pid].out = NULL;
	if (tmp) {
		SMP2P_ERR("%s: outbound 'smp2p':%d close failed %d\n",
				__func__, remote_pid, tmp);
		ret = tmp;
	}

	tmp = msm_smp2p_in_unregister(remote_pid,
		SMP2P_RLPB_ENTRY_NAME, &remote_loopback[remote_pid].in_nb);
	if (tmp) {
		SMP2P_ERR("%s: inbound 'smp2p':%d close failed %d\n",
				__func__, remote_pid, tmp);
		ret = tmp;
	}

	return ret;
}
static int msm_smp2p_init_rmt_lpb(struct  smp2p_loopback_ctx *ctx,
			int pid, const char *entry)
{
	int ret = 0;
	int tmp;

	if (!ctx || !entry || pid > SMP2P_NUM_PROCS)
		return -EINVAL;

	ctx->in_nb.notifier_call = smp2p_rmt_in_edge_notify;
	ctx->out_nb.notifier_call = smp2p_rmt_out_edge_notify;
	ctx->proc_id = pid;
	ctx->in_is_active = true;
	ctx->out_is_active = true;
	tmp = msm_smp2p_out_open(pid, entry, &ctx->out_nb,
						&ctx->out);
	if (tmp) {
		SMP2P_ERR("%s: open failed outbound entry '%s':%d - ret %d\n",
				__func__, entry, pid, tmp);
		ret = tmp;
	}

	tmp = msm_smp2p_in_register(ctx->proc_id,
				SMP2P_RLPB_ENTRY_NAME,
				&ctx->in_nb);
	if (tmp) {
		SMP2P_ERR("%s: unable to open inbound entry '%s':%d - ret %d\n",
				__func__, entry, pid, tmp);
		ret = tmp;
	}

	return ret;
}
/**
 * smp2p_remote_mock_init - Initialize the remote mock and loopback objects.
 *
 * @returns: 0 for success
 */
static int __init smp2p_remote_mock_init(void)
{
	int i;
	struct smp2p_interrupt_config *int_cfg;

	smp2p_init_header(&remote_mock.remote_item.header,
			SMP2P_REMOTE_MOCK_PROC, SMP2P_APPS_PROC,
			0, 0);
	remote_mock.rx_interrupt_count = 0;
	remote_mock.rx_interrupt = smp2p_remote_mock_rx_interrupt;
	remote_mock.tx_interrupt = smp2p_remote_mock_tx_interrupt;
	remote_mock.item_exists = false;
	init_completion(&remote_mock.cb_completion);
	remote_mock.initialized = true;

	for (i = 0; i < SMP2P_NUM_PROCS; i++) {
		INIT_WORK(&(remote_loopback[i].rmt_lpb_work),
				smp2p_rmt_lpb_worker);
		if (i == SMP2P_REMOTE_MOCK_PROC)
			/* do not register loopback for remote mock proc */
			continue;

		int_cfg = smp2p_get_interrupt_config();
		if (!int_cfg) {
			SMP2P_ERR("Remote processor config unavailable\n");
			return 0;
		}
		if (!int_cfg[i].is_configured)
			continue;

		msm_smp2p_init_rmt_lpb(&remote_loopback[i],
			i, SMP2P_RLPB_ENTRY_NAME);
	}
	return 0;
}
static int __init smp2p_sleepstate_init(void)
{
	int ret;
	ret = platform_driver_register(&smp2p_sleepstate_driver);
	if (ret) {
		SMP2P_ERR("%s: smp2p_sleepstate_driver register failed %d\n",
			 __func__, ret);
		return ret;
	}

	return 0;
}
static void remote_spinlock_test(struct smp2p_loopback_ctx *ctx)
{
	uint32_t test_request;
	uint32_t test_response;
	unsigned long flags;
	int n;
	unsigned lock_count = 0;
	remote_spinlock_t *smem_spinlock;

	test_request = 0x0;
	SMP2P_SET_RMT_CMD_TYPE_REQ(test_request);
	smem_spinlock = smem_get_remote_spinlock();
	if (!smem_spinlock) {
		pr_err("%s: unable to get remote spinlock\n", __func__);
		return;
	}

	for (;;) {
		remote_spin_lock_irqsave(smem_spinlock, flags);
		++lock_count;
		SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_RSPIN_LOCKED);
		(void)msm_smp2p_out_write(ctx->out, test_request);

		for (n = 0; n < 10000; ++n) {
			(void)msm_smp2p_in_read(ctx->proc_id,
					"smp2p", &test_response);
			test_response = SMP2P_GET_RMT_CMD(test_response);

			if (test_response == SMP2P_LB_CMD_RSPIN_END)
				break;

			if (test_response != SMP2P_LB_CMD_RSPIN_UNLOCKED)
				SMP2P_ERR("%s: invalid spinlock command %x\n",
					__func__, test_response);
		}

		if (test_response == SMP2P_LB_CMD_RSPIN_END) {
			SMP2P_SET_RMT_CMD_TYPE_RESP(test_request);
			SMP2P_SET_RMT_CMD(test_request,
					SMP2P_LB_CMD_RSPIN_END);
			SMP2P_SET_RMT_DATA(test_request, lock_count);
			(void)msm_smp2p_out_write(ctx->out, test_request);
			break;
		}

		SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_RSPIN_UNLOCKED);
		(void)msm_smp2p_out_write(ctx->out, test_request);
		remote_spin_unlock_irqrestore(smem_spinlock, flags);
	}
	remote_spin_unlock_irqrestore(smem_spinlock, flags);
}
static int smp2p_sleepstate_probe(struct platform_device *pdev)
{
	int ret;
	struct device_node *node = pdev->dev.of_node;

	slst_gpio_base_id = of_get_gpio(node, 0);
	if (slst_gpio_base_id == -EPROBE_DEFER) {
		return slst_gpio_base_id;
	} else if (slst_gpio_base_id < 0) {
		SMP2P_ERR("%s: Error to get gpio %d\n",
				__func__, slst_gpio_base_id);
		return slst_gpio_base_id;
	}


	gpio_set_value(slst_gpio_base_id + PROC_AWAKE_ID, 1);

	ret = register_pm_notifier(&sleepstate_pm_nb);
	if (ret)
		SMP2P_ERR("%s: power state notif error %d\n", __func__, ret);

	return 0;
}