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; }