Commit 30b7ea5e authored by Stephen Boyd's avatar Stephen Boyd Committed by Andy Gross

soc: qcom: smd_rpm: Handle big endian CPUs

The smd rpm structures are always in little endian, but this
driver is not capable of being used on big endian CPUs. Annotate
the little endian data members and update the code to do the
proper byte swapping.

Cc: Bjorn Andersson <bjorn.andersson@sonymobile.com>
Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
Reviewed-by: default avatarBjorn Andersson <bjorn.andersson@sonymobile.com>
Signed-off-by: default avatarAndy Gross <agross@codeaurora.org>
parent 50e1b29b
......@@ -45,8 +45,8 @@ struct qcom_smd_rpm {
* @length: length of the payload
*/
struct qcom_rpm_header {
u32 service_type;
u32 length;
__le32 service_type;
__le32 length;
};
/**
......@@ -58,11 +58,11 @@ struct qcom_rpm_header {
* @data_len: length of the payload following this header
*/
struct qcom_rpm_request {
u32 msg_id;
u32 flags;
u32 type;
u32 id;
u32 data_len;
__le32 msg_id;
__le32 flags;
__le32 type;
__le32 id;
__le32 data_len;
};
/**
......@@ -75,10 +75,10 @@ struct qcom_rpm_request {
* Multiple of these messages can be stacked in an rpm message.
*/
struct qcom_rpm_message {
u32 msg_type;
u32 length;
__le32 msg_type;
__le32 length;
union {
u32 msg_id;
__le32 msg_id;
u8 message[0];
};
};
......@@ -122,14 +122,14 @@ int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
mutex_lock(&rpm->lock);
pkt->hdr.service_type = RPM_SERVICE_TYPE_REQUEST;
pkt->hdr.length = sizeof(struct qcom_rpm_request) + count;
pkt->hdr.service_type = cpu_to_le32(RPM_SERVICE_TYPE_REQUEST);
pkt->hdr.length = cpu_to_le32(sizeof(struct qcom_rpm_request) + count);
pkt->req.msg_id = msg_id++;
pkt->req.flags = BIT(state);
pkt->req.type = type;
pkt->req.id = id;
pkt->req.data_len = count;
pkt->req.msg_id = cpu_to_le32(msg_id++);
pkt->req.flags = cpu_to_le32(BIT(state));
pkt->req.type = cpu_to_le32(type);
pkt->req.id = cpu_to_le32(id);
pkt->req.data_len = cpu_to_le32(count);
memcpy(pkt->payload, buf, count);
ret = qcom_smd_send(rpm->rpm_channel, pkt, sizeof(*pkt));
......@@ -154,27 +154,29 @@ static int qcom_smd_rpm_callback(struct qcom_smd_device *qsdev,
size_t count)
{
const struct qcom_rpm_header *hdr = data;
size_t hdr_length = le32_to_cpu(hdr->length);
const struct qcom_rpm_message *msg;
struct qcom_smd_rpm *rpm = dev_get_drvdata(&qsdev->dev);
const u8 *buf = data + sizeof(struct qcom_rpm_header);
const u8 *end = buf + hdr->length;
const u8 *end = buf + hdr_length;
char msgbuf[32];
int status = 0;
u32 len;
u32 len, msg_length;
if (hdr->service_type != RPM_SERVICE_TYPE_REQUEST ||
hdr->length < sizeof(struct qcom_rpm_message)) {
if (le32_to_cpu(hdr->service_type) != RPM_SERVICE_TYPE_REQUEST ||
hdr_length < sizeof(struct qcom_rpm_message)) {
dev_err(&qsdev->dev, "invalid request\n");
return 0;
}
while (buf < end) {
msg = (struct qcom_rpm_message *)buf;
switch (msg->msg_type) {
msg_length = le32_to_cpu(msg->length);
switch (le32_to_cpu(msg->msg_type)) {
case RPM_MSG_TYPE_MSG_ID:
break;
case RPM_MSG_TYPE_ERR:
len = min_t(u32, ALIGN(msg->length, 4), sizeof(msgbuf));
len = min_t(u32, ALIGN(msg_length, 4), sizeof(msgbuf));
memcpy_fromio(msgbuf, msg->message, len);
msgbuf[len - 1] = 0;
......@@ -185,7 +187,7 @@ static int qcom_smd_rpm_callback(struct qcom_smd_device *qsdev,
break;
}
buf = PTR_ALIGN(buf + 2 * sizeof(u32) + msg->length, 4);
buf = PTR_ALIGN(buf + 2 * sizeof(u32) + msg_length, 4);
}
rpm->ack_status = status;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment