in stratix10-svc.c [803:871]
int stratix10_svc_send(struct stratix10_svc_chan *chan, void *msg)
{
struct stratix10_svc_client_msg
*p_msg = (struct stratix10_svc_client_msg *)msg;
struct stratix10_svc_data_mem *p_mem;
struct stratix10_svc_data *p_data;
int ret = 0;
unsigned int cpu = 0;
p_data = kzalloc(sizeof(*p_data), GFP_KERNEL);
if (!p_data)
return -ENOMEM;
/* first client will create kernel thread */
if (!chan->ctrl->task) {
chan->ctrl->task =
kthread_create_on_node(svc_normal_to_secure_thread,
(void *)chan->ctrl,
cpu_to_node(cpu),
"svc_smc_hvc_thread");
if (IS_ERR(chan->ctrl->task)) {
dev_err(chan->ctrl->dev,
"failed to create svc_smc_hvc_thread\n");
kfree(p_data);
return -EINVAL;
}
kthread_bind(chan->ctrl->task, cpu);
wake_up_process(chan->ctrl->task);
}
pr_debug("%s: sent P-va=%p, P-com=%x, P-size=%u\n", __func__,
p_msg->payload, p_msg->command,
(unsigned int)p_msg->payload_length);
if (list_empty(&svc_data_mem)) {
if (p_msg->command == COMMAND_RECONFIG) {
struct stratix10_svc_command_config_type *ct =
(struct stratix10_svc_command_config_type *)
p_msg->payload;
p_data->flag = ct->flags;
}
} else {
list_for_each_entry(p_mem, &svc_data_mem, node)
if (p_mem->vaddr == p_msg->payload) {
p_data->paddr = p_mem->paddr;
break;
}
}
p_data->command = p_msg->command;
p_data->arg[0] = p_msg->arg[0];
p_data->arg[1] = p_msg->arg[1];
p_data->arg[2] = p_msg->arg[2];
p_data->size = p_msg->payload_length;
p_data->chan = chan;
pr_debug("%s: put to FIFO pa=0x%016x, cmd=%x, size=%u\n", __func__,
(unsigned int)p_data->paddr, p_data->command,
(unsigned int)p_data->size);
ret = kfifo_in_spinlocked(&chan->ctrl->svc_fifo, p_data,
sizeof(*p_data),
&chan->ctrl->svc_fifo_lock);
kfree(p_data);
if (!ret)
return -ENOBUFS;
return 0;
}