Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ead67421 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'qcom-soc-for-4.4' of git://codeaurora.org/quic/kernel/agross-msm into next/drivers

Pull "Qualcomm ARM Based SoC Updates for 4.4" from Andy Gross:

* Implement id_table driver matching in SMD
* Avoid NULL pointer exception on remove of SMEM
* Reorder SMEM/SMD configs
* Make qcom_smem_get() return a pointer
* Handle big endian CPUs correctly in SMEM
* Represent SMD channel layout in structures
* Use __iowrite32_copy() in SMD
* Remove use of VLAIs in SMD
* Handle big endian CPUs correctly in SMD/RPM
* Handle big endian CPUs corretly in SMD
* Reject sending SMD packets that are too large
* Fix endianness issue in SCM __qcom_scm_is_call_available
* Add missing prototype for qcom_scm_is_available()
* Correct SMEM items for upper channels
* Use architecture level to build SCM correctly
* Delete unneeded of_node_put in SMD
* Correct active/slep state flagging in SMD/RPM
* Move RPM message ram out of SMEM DT node

* tag 'qcom-soc-for-4.4' of git://codeaurora.org/quic/kernel/agross-msm:
  soc: qcom: smem: Move RPM message ram out of smem DT node
  soc: qcom: smd-rpm: Correct the active vs sleep state flagging
  soc: qcom: smd: delete unneeded of_node_put
  firmware: qcom-scm: build for correct architecture level
  soc: qcom: smd: Correct SMEM items for upper channels
  qcom-scm: add missing prototype for qcom_scm_is_available()
  qcom-scm: fix endianess issue in __qcom_scm_is_call_available
  soc: qcom: smd: Reject send of too big packets
  soc: qcom: smd: Handle big endian CPUs
  soc: qcom: smd_rpm: Handle big endian CPUs
  soc: qcom: smd: Remove use of VLAIS
  soc: qcom: smd: Use __iowrite32_copy() instead of open-coding it
  soc: qcom: smd: Represent channel layout in structures
  soc: qcom: smem: Handle big endian CPUs
  soc: qcom: Make qcom_smem_get() return a pointer
  soc: qcom: Reorder SMEM/SMD configs
  soc: qcom: smem: Avoid NULL pointer exception on remove
  soc: qcom: smd: Implement id_table driver matching
parents 41e602e8 d0bfd7c9
Loading
Loading
Loading
Loading
+11 −6
Original line number Diff line number Diff line
@@ -100,6 +100,15 @@
		clock-frequency = <19200000>;
	};

	smem {
		compatible = "qcom,smem";

		memory-region = <&smem_region>;
		qcom,rpm-msg-ram = <&rpm_msg_ram>;

		hwlocks = <&tcsr_mutex 3>;
	};

	soc: soc {
		#address-cells = <1>;
		#size-cells = <1>;
@@ -250,13 +259,9 @@
			#hwlock-cells = <1>;
		};

		smem@fa00000 {
			compatible = "qcom,smem";

			memory-region = <&smem_region>;
		rpm_msg_ram: memory@fc428000 {
			compatible = "qcom,rpm-msg-ram";
			reg = <0xfc428000 0x4000>;

			hwlocks = <&tcsr_mutex 3>;
		};

		blsp1_uart2: serial@f991e000 {
+1 −1
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
obj-$(CONFIG_QCOM_SCM)		+= qcom_scm.o
obj-$(CONFIG_QCOM_SCM_64)	+= qcom_scm-64.o
obj-$(CONFIG_QCOM_SCM_32)	+= qcom_scm-32.o
CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch armv7-a\n.arch_extension sec,-DREQUIRES_SEC=1) -march=armv7-a

obj-y				+= broadcom/
obj-$(CONFIG_GOOGLE_FIRMWARE)	+= google/
+3 −3
Original line number Diff line number Diff line
@@ -480,15 +480,15 @@ void __qcom_scm_cpu_power_down(u32 flags)
int __qcom_scm_is_call_available(u32 svc_id, u32 cmd_id)
{
	int ret;
	u32 svc_cmd = (svc_id << 10) | cmd_id;
	u32 ret_val = 0;
	__le32 svc_cmd = cpu_to_le32((svc_id << 10) | cmd_id);
	__le32 ret_val = 0;

	ret = qcom_scm_call(QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD, &svc_cmd,
			sizeof(svc_cmd), &ret_val, sizeof(ret_val));
	if (ret)
		return ret;

	return ret_val;
	return le32_to_cpu(ret_val);
}

int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
+8 −8
Original line number Diff line number Diff line
@@ -19,6 +19,14 @@ config QCOM_PM
	  modes. It interface with various system drivers to put the cores in
	  low power modes.

config QCOM_SMEM
	tristate "Qualcomm Shared Memory Manager (SMEM)"
	depends on ARCH_QCOM
	help
	  Say y here to enable support for the Qualcomm Shared Memory Manager.
	  The driver provides an interface to items in a heap shared among all
	  processors in a Qualcomm platform.

config QCOM_SMD
	tristate "Qualcomm Shared Memory Driver (SMD)"
	depends on QCOM_SMEM
@@ -40,11 +48,3 @@ config QCOM_SMD_RPM

	  Say M here if you want to include support for the Qualcomm RPM as a
	  module. This will build a module called "qcom-smd-rpm".

config QCOM_SMEM
	tristate "Qualcomm Shared Memory Manager (SMEM)"
	depends on ARCH_QCOM
	help
	  Say y here to enable support for the Qualcomm Shared Memory Manager.
	  The driver provides an interface to items in a heap shared among all
	  processors in a Qualcomm platform.
+38 −30
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/of_platform.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/slab.h>

#include <linux/soc/qcom/smd.h>
#include <linux/soc/qcom/smd-rpm.h>
@@ -44,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;
};

/**
@@ -57,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;
};

/**
@@ -74,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];
	};
};
@@ -104,30 +105,34 @@ int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
	static unsigned msg_id = 1;
	int left;
	int ret;

	struct {
		struct qcom_rpm_header hdr;
		struct qcom_rpm_request req;
		u8 payload[count];
	} pkt;
		u8 payload[];
	} *pkt;
	size_t size = sizeof(*pkt) + count;

	/* SMD packets to the RPM may not exceed 256 bytes */
	if (WARN_ON(sizeof(pkt) >= 256))
	if (WARN_ON(size >= 256))
		return -EINVAL;

	pkt = kmalloc(size, GFP_KERNEL);
	if (!pkt)
		return -ENOMEM;

	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;
	memcpy(pkt.payload, buf, count);
	pkt->req.msg_id = cpu_to_le32(msg_id++);
	pkt->req.flags = cpu_to_le32(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));
	ret = qcom_smd_send(rpm->rpm_channel, pkt, sizeof(*pkt));
	if (ret)
		goto out;

@@ -138,6 +143,7 @@ int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
		ret = rpm->ack_status;

out:
	kfree(pkt);
	mutex_unlock(&rpm->lock);
	return ret;
}
@@ -148,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;

@@ -179,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;
Loading