Commit 3dc8dcb0 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'qcom-drivers-for-5.4' of...

Merge tag 'qcom-drivers-for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into arm/drivers

Qualcomm ARM Based Driver Updates for v5.4

* Add AOSS QMP support
* Various fixups for Qualcomm SCM
* Add socinfo driver
* Add SoC serial number attribute and associated APIs
* Add SM8150 and SC7180 support in Qualcomm SCM
* Fixup max processor count in SMEM

* tag 'qcom-drivers-for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux:
  soc: qcom: aoss: Add AOSS QMP support
  dt-bindings: soc: qcom: aoss: Add SM8150 and SC7180 support
  dt-bindings: firmware: scm: Add SM8150 and SC7180 support
  dt-bindings: firmware: scm: re-order compatible list
  soc: qcom: smem: Update max processor count
  soc: qcom: socinfo: Annotate switch cases with fall through
  soc: qcom: Extend AOSS QMP driver to support resources that are used to wake up the SoC.
  soc: qcom: socinfo: Expose image information
  soc: qcom: socinfo: Expose custom attributes
  soc: qcom: Add socinfo driver
  base: soc: Export soc_device_register/unregister APIs
  base: soc: Add serial_number attribute to soc
  firmware: qcom_scm: Cleanup code in qcom_scm_assign_mem()
  firmware: qcom_scm: Fix some typos in docs and printks
  firmware: qcom_scm: Use proper types for dma mappings
parents ef92bfda 17095102
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -26,6 +26,13 @@ Description:
		Read-only attribute common to all SoCs. Contains SoC family name
		(e.g. DB8500).

What:		/sys/devices/socX/serial_number
Date:		January 2019
contact:	Bjorn Andersson <bjorn.andersson@linaro.org>
Description:
		Read-only attribute supported by most SoCs. Contains the SoC's
		serial number, if available.

What:		/sys/devices/socX/soc_id
Date:		January 2012
contact:	Lee Jones <lee.jones@linaro.org>
+3 −1
Original line number Diff line number Diff line
@@ -9,14 +9,16 @@ Required properties:
- compatible: must contain one of the following:
 * "qcom,scm-apq8064"
 * "qcom,scm-apq8084"
 * "qcom,scm-ipq4019"
 * "qcom,scm-msm8660"
 * "qcom,scm-msm8916"
 * "qcom,scm-msm8960"
 * "qcom,scm-msm8974"
 * "qcom,scm-msm8996"
 * "qcom,scm-msm8998"
 * "qcom,scm-ipq4019"
 * "qcom,scm-sc7180"
 * "qcom,scm-sdm845"
 * "qcom,scm-sm8150"
 and:
 * "qcom,scm"
- clocks: Specifies clocks needed by the SCM interface, if any:
+4 −1
Original line number Diff line number Diff line
@@ -15,7 +15,10 @@ power-domains.
- compatible:
	Usage: required
	Value type: <string>
	Definition: must be "qcom,sdm845-aoss-qmp"
	Definition: must be one of:
		    "qcom,sc7180-aoss-qmp"
		    "qcom,sdm845-aoss-qmp"
		    "qcom,sm8150-aoss-qmp"

- reg:
	Usage: required
+9 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ static struct bus_type soc_bus_type = {

static DEVICE_ATTR(machine,  S_IRUGO, soc_info_get,  NULL);
static DEVICE_ATTR(family,   S_IRUGO, soc_info_get,  NULL);
static DEVICE_ATTR(serial_number, S_IRUGO, soc_info_get,  NULL);
static DEVICE_ATTR(soc_id,   S_IRUGO, soc_info_get,  NULL);
static DEVICE_ATTR(revision, S_IRUGO, soc_info_get,  NULL);

@@ -57,6 +58,9 @@ static umode_t soc_attribute_mode(struct kobject *kobj,
	if ((attr == &dev_attr_revision.attr)
	    && (soc_dev->attr->revision != NULL))
		return attr->mode;
	if ((attr == &dev_attr_serial_number.attr)
	    && (soc_dev->attr->serial_number != NULL))
		return attr->mode;
	if ((attr == &dev_attr_soc_id.attr)
	    && (soc_dev->attr->soc_id != NULL))
		return attr->mode;
@@ -77,6 +81,8 @@ static ssize_t soc_info_get(struct device *dev,
		return sprintf(buf, "%s\n", soc_dev->attr->family);
	if (attr == &dev_attr_revision)
		return sprintf(buf, "%s\n", soc_dev->attr->revision);
	if (attr == &dev_attr_serial_number)
		return sprintf(buf, "%s\n", soc_dev->attr->serial_number);
	if (attr == &dev_attr_soc_id)
		return sprintf(buf, "%s\n", soc_dev->attr->soc_id);

@@ -87,6 +93,7 @@ static ssize_t soc_info_get(struct device *dev,
static struct attribute *soc_attr[] = {
	&dev_attr_machine.attr,
	&dev_attr_family.attr,
	&dev_attr_serial_number.attr,
	&dev_attr_soc_id.attr,
	&dev_attr_revision.attr,
	NULL,
@@ -157,6 +164,7 @@ out2:
out1:
	return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(soc_device_register);

/* Ensure soc_dev->attr is freed prior to calling soc_device_unregister. */
void soc_device_unregister(struct soc_device *soc_dev)
@@ -166,6 +174,7 @@ void soc_device_unregister(struct soc_device *soc_dev)
	device_unregister(&soc_dev->dev);
	early_soc_dev_attr = NULL;
}
EXPORT_SYMBOL_GPL(soc_device_unregister);

static int __init soc_bus_register(void)
{
+24 −23
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/init.h>
#include <linux/cpumask.h>
#include <linux/export.h>
#include <linux/dma-direct.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/types.h>
@@ -425,21 +426,23 @@ EXPORT_SYMBOL(qcom_scm_set_remote_state);
 * @mem_sz:   size of the region.
 * @srcvm:    vmid for current set of owners, each set bit in
 *            flag indicate a unique owner
 * @newvm:    array having new owners and corrsponding permission
 * @newvm:    array having new owners and corresponding permission
 *            flags
 * @dest_cnt: number of owners in next set.
 *
 * Return negative errno on failure, 0 on success, with @srcvm updated.
 * Return negative errno on failure or 0 on success with @srcvm updated.
 */
int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
			unsigned int *srcvm,
			struct qcom_scm_vmperm *newvm, int dest_cnt)
			const struct qcom_scm_vmperm *newvm,
			unsigned int dest_cnt)
{
	struct qcom_scm_current_perm_info *destvm;
	struct qcom_scm_mem_map_info *mem_to_map;
	phys_addr_t mem_to_map_phys;
	phys_addr_t dest_phys;
	phys_addr_t ptr_phys;
	dma_addr_t ptr_dma;
	size_t mem_to_map_sz;
	size_t dest_sz;
	size_t src_sz;
@@ -447,52 +450,50 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
	int next_vm;
	__le32 *src;
	void *ptr;
	int ret;
	int len;
	int i;
	int ret, i, b;
	unsigned long srcvm_bits = *srcvm;

	src_sz = hweight_long(*srcvm) * sizeof(*src);
	src_sz = hweight_long(srcvm_bits) * sizeof(*src);
	mem_to_map_sz = sizeof(*mem_to_map);
	dest_sz = dest_cnt * sizeof(*destvm);
	ptr_sz = ALIGN(src_sz, SZ_64) + ALIGN(mem_to_map_sz, SZ_64) +
			ALIGN(dest_sz, SZ_64);

	ptr = dma_alloc_coherent(__scm->dev, ptr_sz, &ptr_phys, GFP_KERNEL);
	ptr = dma_alloc_coherent(__scm->dev, ptr_sz, &ptr_dma, GFP_KERNEL);
	if (!ptr)
		return -ENOMEM;
	ptr_phys = dma_to_phys(__scm->dev, ptr_dma);

	/* Fill source vmid detail */
	src = ptr;
	len = hweight_long(*srcvm);
	for (i = 0; i < len; i++) {
		src[i] = cpu_to_le32(ffs(*srcvm) - 1);
		*srcvm ^= 1 << (ffs(*srcvm) - 1);
	}
	i = 0;
	for_each_set_bit(b, &srcvm_bits, BITS_PER_LONG)
		src[i++] = cpu_to_le32(b);

	/* Fill details of mem buff to map */
	mem_to_map = ptr + ALIGN(src_sz, SZ_64);
	mem_to_map_phys = ptr_phys + ALIGN(src_sz, SZ_64);
	mem_to_map[0].mem_addr = cpu_to_le64(mem_addr);
	mem_to_map[0].mem_size = cpu_to_le64(mem_sz);
	mem_to_map->mem_addr = cpu_to_le64(mem_addr);
	mem_to_map->mem_size = cpu_to_le64(mem_sz);

	next_vm = 0;
	/* Fill details of next vmid detail */
	destvm = ptr + ALIGN(mem_to_map_sz, SZ_64) + ALIGN(src_sz, SZ_64);
	dest_phys = ptr_phys + ALIGN(mem_to_map_sz, SZ_64) + ALIGN(src_sz, SZ_64);
	for (i = 0; i < dest_cnt; i++) {
		destvm[i].vmid = cpu_to_le32(newvm[i].vmid);
		destvm[i].perm = cpu_to_le32(newvm[i].perm);
		destvm[i].ctx = 0;
		destvm[i].ctx_size = 0;
		next_vm |= BIT(newvm[i].vmid);
	for (i = 0; i < dest_cnt; i++, destvm++, newvm++) {
		destvm->vmid = cpu_to_le32(newvm->vmid);
		destvm->perm = cpu_to_le32(newvm->perm);
		destvm->ctx = 0;
		destvm->ctx_size = 0;
		next_vm |= BIT(newvm->vmid);
	}

	ret = __qcom_scm_assign_mem(__scm->dev, mem_to_map_phys, mem_to_map_sz,
				    ptr_phys, src_sz, dest_phys, dest_sz);
	dma_free_coherent(__scm->dev, ALIGN(ptr_sz, SZ_64), ptr, ptr_phys);
	dma_free_coherent(__scm->dev, ptr_sz, ptr, ptr_dma);
	if (ret) {
		dev_err(__scm->dev,
			"Assign memory protection call failed %d.\n", ret);
			"Assign memory protection call failed %d\n", ret);
		return -EINVAL;
	}

Loading