From: Stephen Boyd Date: Wed, 2 Sep 2015 22:46:50 +0000 (-0700) Subject: soc: qcom: smd_rpm: Handle big endian CPUs X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=30b7ea5eda0afb13164b2d7049a56645cfc1d47b;p=GitHub%2Fexynos8895%2Fandroid_kernel_samsung_universal8895.git 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 Signed-off-by: Stephen Boyd Reviewed-by: Bjorn Andersson Signed-off-by: Andy Gross --- diff --git a/drivers/soc/qcom/smd-rpm.c b/drivers/soc/qcom/smd-rpm.c index 7709579d63d0..d4cbaa3d4629 100644 --- a/drivers/soc/qcom/smd-rpm.c +++ b/drivers/soc/qcom/smd-rpm.c @@ -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;