Lines Matching +full:rpmsg +full:- +full:channel +full:- +full:name
1 // SPDX-License-Identifier: GPL-2.0
13 #include <linux/rpmsg.h>
23 * struct cros_ec_rpmsg_response - rpmsg message format from from EC.
36 * struct cros_ec_rpmsg - information about a EC over rpmsg.
38 * @rpdev: rpmsg device we are connected to
41 * @ept: The rpmsg endpoint of this channel.
55 * cros_ec_cmd_xfer_rpmsg - Transfer a message over rpmsg and receive the reply
63 * Return: -EINVAL
68 return -EINVAL; in cros_ec_cmd_xfer_rpmsg()
72 * cros_ec_pkt_xfer_rpmsg - Transfer a packet over rpmsg and receive the reply
82 struct cros_ec_rpmsg *ec_rpmsg = ec_dev->priv; in cros_ec_pkt_xfer_rpmsg()
90 ec_msg->result = 0; in cros_ec_pkt_xfer_rpmsg()
94 dev_dbg(ec_dev->dev, "prepared, len=%d\n", len); in cros_ec_pkt_xfer_rpmsg()
96 reinit_completion(&ec_rpmsg->xfer_ack); in cros_ec_pkt_xfer_rpmsg()
97 ret = rpmsg_send(ec_rpmsg->ept, ec_dev->dout, len); in cros_ec_pkt_xfer_rpmsg()
99 dev_err(ec_dev->dev, "rpmsg send failed\n"); in cros_ec_pkt_xfer_rpmsg()
104 ret = wait_for_completion_timeout(&ec_rpmsg->xfer_ack, timeout); in cros_ec_pkt_xfer_rpmsg()
106 dev_err(ec_dev->dev, "rpmsg send timeout\n"); in cros_ec_pkt_xfer_rpmsg()
107 return -EIO; in cros_ec_pkt_xfer_rpmsg()
111 response = (struct ec_host_response *)ec_dev->din; in cros_ec_pkt_xfer_rpmsg()
112 ec_msg->result = response->result; in cros_ec_pkt_xfer_rpmsg()
118 if (response->data_len > ec_msg->insize) { in cros_ec_pkt_xfer_rpmsg()
119 dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)", in cros_ec_pkt_xfer_rpmsg()
120 response->data_len, ec_msg->insize); in cros_ec_pkt_xfer_rpmsg()
121 ret = -EMSGSIZE; in cros_ec_pkt_xfer_rpmsg()
126 memcpy(ec_msg->data, ec_dev->din + sizeof(*response), in cros_ec_pkt_xfer_rpmsg()
127 response->data_len); in cros_ec_pkt_xfer_rpmsg()
130 for (i = 0; i < sizeof(*response) + response->data_len; i++) in cros_ec_pkt_xfer_rpmsg()
131 sum += ec_dev->din[i]; in cros_ec_pkt_xfer_rpmsg()
134 dev_err(ec_dev->dev, "bad packet checksum, calculated %x\n", in cros_ec_pkt_xfer_rpmsg()
136 ret = -EBADMSG; in cros_ec_pkt_xfer_rpmsg()
140 ret = response->data_len; in cros_ec_pkt_xfer_rpmsg()
142 if (ec_msg->command == EC_CMD_REBOOT_EC) in cros_ec_pkt_xfer_rpmsg()
155 cros_ec_irq_thread(0, dev_get_drvdata(&ec_rpmsg->rpdev->dev)); in cros_ec_rpmsg_host_event_function()
161 struct cros_ec_device *ec_dev = dev_get_drvdata(&rpdev->dev); in cros_ec_rpmsg_callback()
162 struct cros_ec_rpmsg *ec_rpmsg = ec_dev->priv; in cros_ec_rpmsg_callback()
166 dev_warn(ec_dev->dev, "rpmsg received empty response"); in cros_ec_rpmsg_callback()
167 return -EINVAL; in cros_ec_rpmsg_callback()
171 len -= offsetof(struct cros_ec_rpmsg_response, data); in cros_ec_rpmsg_callback()
172 if (resp->type == HOST_COMMAND_MARK) { in cros_ec_rpmsg_callback()
173 if (len > ec_dev->din_size) { in cros_ec_rpmsg_callback()
174 dev_warn(ec_dev->dev, in cros_ec_rpmsg_callback()
176 len, ec_dev->din_size); in cros_ec_rpmsg_callback()
177 len = ec_dev->din_size; in cros_ec_rpmsg_callback()
180 memcpy(ec_dev->din, resp->data, len); in cros_ec_rpmsg_callback()
181 complete(&ec_rpmsg->xfer_ack); in cros_ec_rpmsg_callback()
182 } else if (resp->type == HOST_EVENT_MARK) { in cros_ec_rpmsg_callback()
187 if (ec_rpmsg->probe_done) in cros_ec_rpmsg_callback()
188 schedule_work(&ec_rpmsg->host_event_work); in cros_ec_rpmsg_callback()
190 ec_rpmsg->has_pending_host_event = true; in cros_ec_rpmsg_callback()
192 dev_warn(ec_dev->dev, "rpmsg received invalid type = %d", in cros_ec_rpmsg_callback()
193 resp->type); in cros_ec_rpmsg_callback()
194 return -EINVAL; in cros_ec_rpmsg_callback()
205 strscpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE); in cros_ec_rpmsg_create_ept()
206 chinfo.src = rpdev->src; in cros_ec_rpmsg_create_ept()
214 struct device *dev = &rpdev->dev; in cros_ec_rpmsg_probe()
221 return -ENOMEM; in cros_ec_rpmsg_probe()
225 return -ENOMEM; in cros_ec_rpmsg_probe()
227 ec_dev->dev = dev; in cros_ec_rpmsg_probe()
228 ec_dev->priv = ec_rpmsg; in cros_ec_rpmsg_probe()
229 ec_dev->cmd_xfer = cros_ec_cmd_xfer_rpmsg; in cros_ec_rpmsg_probe()
230 ec_dev->pkt_xfer = cros_ec_pkt_xfer_rpmsg; in cros_ec_rpmsg_probe()
231 ec_dev->phys_name = dev_name(&rpdev->dev); in cros_ec_rpmsg_probe()
232 ec_dev->din_size = sizeof(struct ec_host_response) + in cros_ec_rpmsg_probe()
234 ec_dev->dout_size = sizeof(struct ec_host_request); in cros_ec_rpmsg_probe()
237 ec_rpmsg->rpdev = rpdev; in cros_ec_rpmsg_probe()
238 init_completion(&ec_rpmsg->xfer_ack); in cros_ec_rpmsg_probe()
239 INIT_WORK(&ec_rpmsg->host_event_work, in cros_ec_rpmsg_probe()
242 ec_rpmsg->ept = cros_ec_rpmsg_create_ept(rpdev); in cros_ec_rpmsg_probe()
243 if (!ec_rpmsg->ept) in cros_ec_rpmsg_probe()
244 return -ENOMEM; in cros_ec_rpmsg_probe()
248 rpmsg_destroy_ept(ec_rpmsg->ept); in cros_ec_rpmsg_probe()
249 cancel_work_sync(&ec_rpmsg->host_event_work); in cros_ec_rpmsg_probe()
253 ec_rpmsg->probe_done = true; in cros_ec_rpmsg_probe()
255 if (ec_rpmsg->has_pending_host_event) in cros_ec_rpmsg_probe()
256 schedule_work(&ec_rpmsg->host_event_work); in cros_ec_rpmsg_probe()
263 struct cros_ec_device *ec_dev = dev_get_drvdata(&rpdev->dev); in cros_ec_rpmsg_remove()
264 struct cros_ec_rpmsg *ec_rpmsg = ec_dev->priv; in cros_ec_rpmsg_remove()
267 rpmsg_destroy_ept(ec_rpmsg->ept); in cros_ec_rpmsg_remove()
268 cancel_work_sync(&ec_rpmsg->host_event_work); in cros_ec_rpmsg_remove()
291 { .compatible = "google,cros-ec-rpmsg", },
298 .name = "cros-ec-rpmsg",
309 MODULE_DESCRIPTION("ChromeOS EC multi function device (rpmsg)");