summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi14
-rw-r--r--arch/arm/boot/dts/qcom/msm8996.dtsi8
-rw-r--r--arch/arm64/configs/msm-auto-perf_defconfig10
-rw-r--r--arch/arm64/configs/msm-auto_defconfig10
-rw-r--r--drivers/iio/imu/Kconfig1
-rw-r--r--drivers/iio/imu/Makefile1
-rw-r--r--drivers/input/Kconfig2
-rw-r--r--drivers/input/Makefile2
-rw-r--r--drivers/media/platform/msm/ais/msm_buf_mgr/msm_generic_buf_mgr.c19
-rw-r--r--drivers/soc/qcom/glink_smem_native_xprt.c2
-rw-r--r--drivers/soc/qcom/hab/hab.c66
-rw-r--r--drivers/soc/qcom/hab/hab.h5
-rw-r--r--drivers/soc/qcom/hab/hab_mem_linux.c9
-rw-r--r--drivers/soc/qcom/hab/hab_mimex.c12
-rw-r--r--drivers/soc/qcom/hab/hab_msg.c27
-rw-r--r--drivers/soc/qcom/hab/hab_open.c12
-rw-r--r--drivers/soc/qcom/hab/hab_stat.c9
-rw-r--r--drivers/soc/qcom/hab/hab_vchan.c65
-rw-r--r--drivers/soc/qcom/hab/qvm_comm.c5
-rw-r--r--drivers/soc/qcom/socinfo.c1
-rw-r--r--sound/soc/soc-ops.c4
21 files changed, 170 insertions, 114 deletions
diff --git a/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi
index 0982ead00f8c..3e2e7bbf56f6 100644
--- a/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi
@@ -2839,5 +2839,19 @@
bias-pull-down; /* PULL down */
};
};
+
+ pinctrl_pps: ppsgrp {
+ mux {
+ pins = "gpio128";
+ function = "nav_dr";
+ };
+
+ config {
+ pins = "gpio128";
+ drive-strength = <16>;
+ bias-pull-down;
+ };
+ };
+
};
};
diff --git a/arch/arm/boot/dts/qcom/msm8996.dtsi b/arch/arm/boot/dts/qcom/msm8996.dtsi
index 95b100e10e5b..2750b77e29a7 100644
--- a/arch/arm/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8996.dtsi
@@ -4018,6 +4018,14 @@
qcom,save-reg;
};
+
+ pps {
+ compatible = "pps-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pps>;
+ gpios = <&tlmm 128 0>;
+ status = "okay";
+ };
};
&gdsc_venus {
diff --git a/arch/arm64/configs/msm-auto-perf_defconfig b/arch/arm64/configs/msm-auto-perf_defconfig
index 6f631287652a..fe6727a1eb25 100644
--- a/arch/arm64/configs/msm-auto-perf_defconfig
+++ b/arch/arm64/configs/msm-auto-perf_defconfig
@@ -317,6 +317,11 @@ CONFIG_INPUT_HBTP_INPUT=y
CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_GPIO=y
+CONFIG_BOSCH_DRIVER_LOG_FUNC=y
+CONFIG_SENSORS_BMA2X2=y
+CONFIG_SENSORS_BMA2X2_ENABLE_INT1=y
+CONFIG_SENSORS_BMG=y
+CONFIG_SENSORS_BMG_FIFO=y
# CONFIG_SERIO_SERPORT is not set
# CONFIG_VT is not set
# CONFIG_LEGACY_PTYS is not set
@@ -576,6 +581,11 @@ CONFIG_DEVFREQ_GOV_MEMLAT=y
CONFIG_DEVFREQ_SIMPLE_DEV=y
CONFIG_QCOM_DEVFREQ_DEVBW=y
CONFIG_EXTCON=y
+CONFIG_IIO=y
+CONFIG_INV_MPU_IIO_IAM20680=y
+CONFIG_INV_MPU_IIO_I2C=y
+CONFIG_INV_MPU_IIO_SPI=y
+CONFIG_INV_TESTING=y
CONFIG_PWM=y
CONFIG_PWM_QPNP=y
CONFIG_ARM_GIC_V3_ACL=y
diff --git a/arch/arm64/configs/msm-auto_defconfig b/arch/arm64/configs/msm-auto_defconfig
index a45fc1ce832a..2b1b13c992e7 100644
--- a/arch/arm64/configs/msm-auto_defconfig
+++ b/arch/arm64/configs/msm-auto_defconfig
@@ -318,6 +318,11 @@ CONFIG_INPUT_HBTP_INPUT=y
CONFIG_INPUT_QPNP_POWER_ON=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_GPIO=y
+CONFIG_BOSCH_DRIVER_LOG_FUNC=y
+CONFIG_SENSORS_BMA2X2=y
+CONFIG_SENSORS_BMA2X2_ENABLE_INT1=y
+CONFIG_SENSORS_BMG=y
+CONFIG_SENSORS_BMG_FIFO=y
# CONFIG_SERIO_SERPORT is not set
# CONFIG_VT is not set
# CONFIG_LEGACY_PTYS is not set
@@ -585,6 +590,11 @@ CONFIG_DEVFREQ_GOV_MEMLAT=y
CONFIG_DEVFREQ_SIMPLE_DEV=y
CONFIG_QCOM_DEVFREQ_DEVBW=y
CONFIG_EXTCON=y
+CONFIG_IIO=y
+CONFIG_INV_MPU_IIO_IAM20680=y
+CONFIG_INV_MPU_IIO_I2C=y
+CONFIG_INV_MPU_IIO_SPI=y
+CONFIG_INV_TESTING=y
CONFIG_PWM=y
CONFIG_PWM_QPNP=y
CONFIG_ARM_GIC_V3_ACL=y
diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
index 5e610f7de5aa..903beab85e7e 100644
--- a/drivers/iio/imu/Kconfig
+++ b/drivers/iio/imu/Kconfig
@@ -37,6 +37,7 @@ config KMX61
be called kmx61.
source "drivers/iio/imu/inv_mpu6050/Kconfig"
+source "drivers/iio/imu/inv_mpu/Kconfig"
endmenu
diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
index e1e6e3d70e26..54c282cca986 100644
--- a/drivers/iio/imu/Makefile
+++ b/drivers/iio/imu/Makefile
@@ -14,5 +14,6 @@ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o
obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o
obj-y += inv_mpu6050/
+obj-y += inv_mpu/
obj-$(CONFIG_KMX61) += kmx61.o
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 2557dcda7621..5987a6c2261b 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -214,6 +214,8 @@ source "drivers/input/touchscreen/Kconfig"
source "drivers/input/misc/Kconfig"
+source "drivers/input/sensors/bmi160/Kconfig"
+
endif
menu "Hardware I/O ports"
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 2a6d05ab9170..45286b8e4769 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -28,4 +28,4 @@ obj-$(CONFIG_INPUT_MISC) += misc/
obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o
obj-$(CONFIG_INPUT_KEYRESET) += keyreset.o
obj-$(CONFIG_INPUT_KEYCOMBO) += keycombo.o
-
+obj-y += sensors/bmi160/
diff --git a/drivers/media/platform/msm/ais/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/ais/msm_buf_mgr/msm_generic_buf_mgr.c
index 66751b1f0657..db41cada4328 100644
--- a/drivers/media/platform/msm/ais/msm_buf_mgr/msm_generic_buf_mgr.c
+++ b/drivers/media/platform/msm/ais/msm_buf_mgr/msm_generic_buf_mgr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -554,15 +554,16 @@ static long msm_buf_mngr_subdev_ioctl(struct v4l2_subdev *sd,
return -EINVAL;
if (!k_ioctl.ioctl_ptr)
return -EINVAL;
-
- MSM_CAM_GET_IOCTL_ARG_PTR(&tmp, &k_ioctl.ioctl_ptr,
- sizeof(tmp));
- if (copy_from_user(&buf_info, (void __user *)tmp,
- sizeof(struct msm_buf_mngr_info))) {
- return -EFAULT;
+ if (!is_compat_task()) {
+ MSM_CAM_GET_IOCTL_ARG_PTR(&tmp,
+ &k_ioctl.ioctl_ptr, sizeof(tmp));
+ if (copy_from_user(&buf_info,
+ (void __user *)tmp,
+ sizeof(struct msm_buf_mngr_info))) {
+ return -EFAULT;
+ }
+ k_ioctl.ioctl_ptr = (uintptr_t)&buf_info;
}
- k_ioctl.ioctl_ptr = (uintptr_t)&buf_info;
-
argp = (void *)&k_ioctl;
rc = msm_cam_buf_mgr_ops(cmd, argp);
}
diff --git a/drivers/soc/qcom/glink_smem_native_xprt.c b/drivers/soc/qcom/glink_smem_native_xprt.c
index c78c8a00aa21..e532f071c9ee 100644
--- a/drivers/soc/qcom/glink_smem_native_xprt.c
+++ b/drivers/soc/qcom/glink_smem_native_xprt.c
@@ -2442,6 +2442,7 @@ static int glink_smem_native_probe(struct platform_device *pdev)
}
einfo->irq_line = irq_line;
+ einfo->in_ssr = true;
rc = request_irq(irq_line, irq_handler,
IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND | IRQF_SHARED,
node->name, einfo);
@@ -2450,7 +2451,6 @@ static int glink_smem_native_probe(struct platform_device *pdev)
rc);
goto request_irq_fail;
}
- einfo->in_ssr = true;
rc = enable_irq_wake(irq_line);
if (rc < 0)
pr_err("%s: enable_irq_wake() failed on %d\n", __func__,
diff --git a/drivers/soc/qcom/hab/hab.c b/drivers/soc/qcom/hab/hab.c
index ebe7dfc4a5b6..24461d2c957b 100644
--- a/drivers/soc/qcom/hab/hab.c
+++ b/drivers/soc/qcom/hab/hab.c
@@ -209,14 +209,15 @@ void hab_ctx_free(struct kref *ref)
* the local ioctl access based on ctx
*/
struct virtual_channel *hab_get_vchan_fromvcid(int32_t vcid,
- struct uhab_context *ctx)
+ struct uhab_context *ctx, int ignore_remote)
{
struct virtual_channel *vchan;
read_lock(&ctx->ctx_lock);
list_for_each_entry(vchan, &ctx->vchannels, node) {
if (vcid == vchan->id) {
- if (vchan->otherend_closed || vchan->closed ||
+ if ((ignore_remote ? 0 : vchan->otherend_closed) ||
+ vchan->closed ||
!kref_get_unless_zero(&vchan->refcount)) {
pr_debug("failed to inc vcid %x remote %x session %d refcnt %d close_flg remote %d local %d\n",
vchan->id, vchan->otherend_id,
@@ -550,7 +551,7 @@ long hab_vchan_send(struct uhab_context *ctx,
return -EINVAL;
}
- vchan = hab_get_vchan_fromvcid(vcid, ctx);
+ vchan = hab_get_vchan_fromvcid(vcid, ctx, 0);
if (!vchan || vchan->otherend_closed) {
ret = -ENODEV;
goto err;
@@ -597,9 +598,9 @@ int hab_vchan_recv(struct uhab_context *ctx,
int ret = 0;
int nonblocking_flag = flags & HABMM_SOCKET_RECV_FLAGS_NON_BLOCKING;
- vchan = hab_get_vchan_fromvcid(vcid, ctx);
+ vchan = hab_get_vchan_fromvcid(vcid, ctx, 1);
if (!vchan) {
- pr_err("vcid %X, vchan %p ctx %p\n", vcid, vchan, ctx);
+ pr_err("vcid %X vchan 0x%pK ctx %pK\n", vcid, vchan, ctx);
return -ENODEV;
}
@@ -719,24 +720,20 @@ void hab_vchan_close(struct uhab_context *ctx, int32_t vcid)
write_lock(&ctx->ctx_lock);
list_for_each_entry_safe(vchan, tmp, &ctx->vchannels, node) {
if (vchan->id == vcid) {
- write_unlock(&ctx->ctx_lock);
+ /* local close starts */
+ vchan->closed = 1;
+
+ /* vchan is not in this ctx anymore */
+ list_del(&vchan->node);
+ ctx->vcnt--;
+
pr_debug("vcid %x remote %x session %d refcnt %d\n",
vchan->id, vchan->otherend_id,
vchan->session_id, get_refcnt(vchan->refcount));
- /*
- * only set when vc close is called locally by user
- * explicity. Used to block remote msg. if forked once
- * before, this local close is skipped due to child
- * usage. if forked but not closed locally, the local
- * context could NOT be closed, vchan can be prolonged
- * by arrived remote msgs
- */
- if (vchan->forked)
- vchan->forked = 0;
- else {
- vchan->closed = 1;
- hab_vchan_stop_notify(vchan);
- }
+
+ write_unlock(&ctx->ctx_lock);
+ /* unblocking blocked in-calls */
+ hab_vchan_stop_notify(vchan);
hab_vchan_put(vchan); /* there is a lock inside */
write_lock(&ctx->ctx_lock);
break;
@@ -1079,25 +1076,14 @@ static int hab_release(struct inode *inodep, struct file *filep)
write_lock(&ctx->ctx_lock);
/* notify remote side on vchan closing */
list_for_each_entry_safe(vchan, tmp, &ctx->vchannels, node) {
- list_del(&vchan->node); /* vchan is not in this ctx anymore */
+ /* local close starts */
+ vchan->closed = 1;
- if (!vchan->closed) { /* locally hasn't closed yet */
- if (!kref_get_unless_zero(&vchan->refcount)) {
- pr_err("vchan %x %x refcnt %d mismanaged closed %d remote closed %d\n",
- vchan->id,
- vchan->otherend_id,
- get_refcnt(vchan->refcount),
- vchan->closed, vchan->otherend_closed);
- continue; /* vchan is already being freed */
- } else {
- hab_vchan_stop_notify(vchan);
- /* put for notify. shouldn't cause free */
- hab_vchan_put(vchan);
- }
- } else
- continue;
+ list_del(&vchan->node); /* vchan is not in this ctx anymore */
+ ctx->vcnt--;
write_unlock(&ctx->ctx_lock);
+ hab_vchan_stop_notify(vchan);
hab_vchan_put(vchan); /* there is a lock inside */
write_lock(&ctx->ctx_lock);
}
@@ -1117,12 +1103,6 @@ static int hab_release(struct inode *inodep, struct file *filep)
hab_ctx_put(ctx);
filep->private_data = NULL;
- /* ctx leak check */
- if (get_refcnt(ctx->refcount))
- pr_warn("pending ctx release owner %d refcnt %d total %d\n",
- ctx->owner, get_refcnt(ctx->refcount),
- hab_driver.ctx_cnt);
-
return 0;
}
@@ -1134,7 +1114,7 @@ static long hab_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
struct hab_recv *recv_param;
struct hab_send *send_param;
struct hab_info *info_param;
- struct hab_message *msg;
+ struct hab_message *msg = NULL;
void *send_data;
unsigned char data[256] = { 0 };
long ret = 0;
diff --git a/drivers/soc/qcom/hab/hab.h b/drivers/soc/qcom/hab/hab.h
index cbc049e89d63..a2df3b64cce6 100644
--- a/drivers/soc/qcom/hab/hab.h
+++ b/drivers/soc/qcom/hab/hab.h
@@ -214,6 +214,7 @@ struct physical_channel {
/* debug only */
uint32_t sequence_tx;
uint32_t sequence_rx;
+ uint32_t status;
/* vchans on this pchan */
struct list_head vchannels;
@@ -255,8 +256,8 @@ struct hab_export_ack_recvd {
};
struct hab_message {
- size_t sizebytes;
struct list_head node;
+ size_t sizebytes;
uint32_t data[];
};
@@ -493,7 +494,7 @@ struct virtual_channel *hab_vchan_get(struct physical_channel *pchan,
void hab_vchan_put(struct virtual_channel *vchan);
struct virtual_channel *hab_get_vchan_fromvcid(int32_t vcid,
- struct uhab_context *ctx);
+ struct uhab_context *ctx, int ignore_remote);
struct physical_channel *hab_pchan_alloc(struct hab_device *habdev,
int otherend_id);
struct physical_channel *hab_pchan_find_domid(struct hab_device *dev,
diff --git a/drivers/soc/qcom/hab/hab_mem_linux.c b/drivers/soc/qcom/hab/hab_mem_linux.c
index 60156c6b00f0..670efdea212f 100644
--- a/drivers/soc/qcom/hab/hab_mem_linux.c
+++ b/drivers/soc/qcom/hab/hab_mem_linux.c
@@ -53,6 +53,14 @@ static struct pages_list *pages_list_create(
if (!pfn_table)
return ERR_PTR(-EINVAL);
+ pfn = pfn_table->first_pfn;
+ if (pfn_valid(pfn) == 0 || page_is_ram(pfn) == 0) {
+ pr_err("imp sanity failed pfn %lx valid %d ram %d pchan %s\n",
+ pfn, pfn_valid(pfn),
+ page_is_ram(pfn), exp->pchan->name);
+ return ERR_PTR(-EINVAL);
+ }
+
size = exp->payload_count * sizeof(struct page *);
pages = kmalloc(size, GFP_KERNEL);
if (!pages)
@@ -64,7 +72,6 @@ static struct pages_list *pages_list_create(
return ERR_PTR(-ENOMEM);
}
- pfn = pfn_table->first_pfn;
for (i = 0; i < pfn_table->nregions; i++) {
for (j = 0; j < pfn_table->region[i].size; j++) {
pages[k] = pfn_to_page(pfn+j);
diff --git a/drivers/soc/qcom/hab/hab_mimex.c b/drivers/soc/qcom/hab/hab_mimex.c
index efa4bb383ec6..b03739974390 100644
--- a/drivers/soc/qcom/hab/hab_mimex.c
+++ b/drivers/soc/qcom/hab/hab_mimex.c
@@ -246,7 +246,7 @@ int hab_mem_export(struct uhab_context *ctx,
if (!ctx || !param || !param->buffer)
return -EINVAL;
- vchan = hab_get_vchan_fromvcid(param->vcid, ctx);
+ vchan = hab_get_vchan_fromvcid(param->vcid, ctx, 0);
if (!vchan || !vchan->pchan) {
ret = -ENODEV;
goto err;
@@ -277,8 +277,8 @@ int hab_mem_export(struct uhab_context *ctx,
&pdata_size);
}
if (ret < 0) {
- pr_err("habmem_hyp_grant failed size=%d ret=%d\n",
- pdata_size, ret);
+ pr_err("habmem_hyp_grant vc %x failed size=%d ret=%d\n",
+ param->vcid, pdata_size, ret);
goto err;
}
@@ -313,7 +313,7 @@ int hab_mem_unexport(struct uhab_context *ctx,
return -EINVAL;
/* refcnt on the access */
- vchan = hab_get_vchan_fromvcid(param->vcid, ctx);
+ vchan = hab_get_vchan_fromvcid(param->vcid, ctx, 1);
if (!vchan || !vchan->pchan) {
ret = -ENODEV;
goto err_novchan;
@@ -360,7 +360,7 @@ int hab_mem_import(struct uhab_context *ctx,
if (!ctx || !param)
return -EINVAL;
- vchan = hab_get_vchan_fromvcid(param->vcid, ctx);
+ vchan = hab_get_vchan_fromvcid(param->vcid, ctx, 0);
if (!vchan || !vchan->pchan) {
ret = -ENODEV;
goto err_imp;
@@ -420,7 +420,7 @@ int hab_mem_unimport(struct uhab_context *ctx,
if (!ctx || !param)
return -EINVAL;
- vchan = hab_get_vchan_fromvcid(param->vcid, ctx);
+ vchan = hab_get_vchan_fromvcid(param->vcid, ctx, 1);
if (!vchan || !vchan->pchan) {
if (vchan)
hab_vchan_put(vchan);
diff --git a/drivers/soc/qcom/hab/hab_msg.c b/drivers/soc/qcom/hab/hab_msg.c
index 71010be414d5..40ff1a9d6415 100644
--- a/drivers/soc/qcom/hab/hab_msg.c
+++ b/drivers/soc/qcom/hab/hab_msg.c
@@ -27,6 +27,12 @@ hab_msg_alloc(struct physical_channel *pchan, size_t sizebytes)
{
struct hab_message *message;
+ if (sizebytes > HAB_HEADER_SIZE_MASK) {
+ pr_err("pchan %s send size too large %zd\n",
+ pchan->name, sizebytes);
+ return NULL;
+ }
+
message = kzalloc(sizeof(*message) + sizebytes, GFP_ATOMIC);
if (!message)
return NULL;
@@ -153,6 +159,12 @@ static int hab_receive_create_export_ack(struct physical_channel *pchan,
pr_err("exp ack size %zu is not as arrived %zu\n",
sizeof(ack_recvd->ack), sizebytes);
+ if (sizebytes > HAB_HEADER_SIZE_MASK) {
+ pr_err("pchan %s read size too large %zd\n",
+ pchan->name, sizebytes);
+ return -EINVAL;
+ }
+
if (physical_channel_read(pchan,
&ack_recvd->ack,
sizebytes) != sizebytes)
@@ -169,6 +181,11 @@ static void hab_msg_drop(struct physical_channel *pchan, size_t sizebytes)
{
uint8_t *data = NULL;
+ if (sizebytes > HAB_HEADER_SIZE_MASK) {
+ pr_err("%s read size too large %zd\n", pchan->name, sizebytes);
+ return;
+ }
+
data = kmalloc(sizebytes, GFP_ATOMIC);
if (data == NULL)
return;
@@ -210,7 +227,7 @@ int hab_msg_recv(struct physical_channel *pchan,
*/
vchan = hab_vchan_get(pchan, header);
if (!vchan) {
- pr_info("vchan is not found, payload type %d, vchan id %x, sizebytes %zx, session %d\n",
+ pr_debug("vchan not found type %d vcid %x sz %zx sesn %d\n",
payload_type, vchan_id, sizebytes, session_id);
if (sizebytes) {
@@ -275,6 +292,12 @@ int hab_msg_recv(struct physical_channel *pchan,
break;
case HAB_PAYLOAD_TYPE_EXPORT:
+ if (sizebytes > HAB_HEADER_SIZE_MASK) {
+ pr_err("%s exp size too large %zd\n",
+ pchan->name, sizebytes);
+ break;
+ }
+
exp_desc = kzalloc(sizebytes, GFP_ATOMIC);
if (!exp_desc)
break;
@@ -313,7 +336,7 @@ int hab_msg_recv(struct physical_channel *pchan,
case HAB_PAYLOAD_TYPE_CLOSE:
/* remote request close */
- pr_info("remote request close vcid %pK %X other id %X session %d refcnt %d\n",
+ pr_debug("remote close vcid %pK %X other id %X session %d refcnt %d\n",
vchan, vchan->id, vchan->otherend_id,
session_id, get_refcnt(vchan->refcount));
hab_vchan_stop(vchan);
diff --git a/drivers/soc/qcom/hab/hab_open.c b/drivers/soc/qcom/hab/hab_open.c
index f09a1df8aa57..bc2b774883f4 100644
--- a/drivers/soc/qcom/hab/hab_open.c
+++ b/drivers/soc/qcom/hab/hab_open.c
@@ -47,6 +47,12 @@ int hab_open_request_add(struct physical_channel *pchan,
struct hab_open_request *request;
struct timeval tv;
+ if (sizebytes > HAB_HEADER_SIZE_MASK) {
+ pr_err("pchan %s request size too large %zd\n",
+ pchan->name, sizebytes);
+ return -EINVAL;
+ }
+
node = kzalloc(sizeof(*node), GFP_ATOMIC);
if (!node)
return -ENOMEM;
@@ -187,6 +193,12 @@ int hab_open_receive_cancel(struct physical_channel *pchan,
int bfound = 0;
struct timeval tv;
+ if (sizebytes > HAB_HEADER_SIZE_MASK) {
+ pr_err("pchan %s cancel size too large %zd\n",
+ pchan->name, sizebytes);
+ return -EINVAL;
+ }
+
if (physical_channel_read(pchan, &data, sizebytes) != sizebytes)
return -EIO;
diff --git a/drivers/soc/qcom/hab/hab_stat.c b/drivers/soc/qcom/hab/hab_stat.c
index f0a4207bc871..b78e5e7e9867 100644
--- a/drivers/soc/qcom/hab/hab_stat.c
+++ b/drivers/soc/qcom/hab/hab_stat.c
@@ -61,14 +61,17 @@ int hab_stat_show_vchan(struct hab_driver *driver,
continue;
ret = hab_stat_buffer_print(buf, size,
- "mmid %s role %d local %d remote %d vcnt %d:\n",
+ "nm %s r %d lc %d rm %d sq_t %d sq_r %d st 0x%x vn %d:\n",
pchan->name, pchan->is_be, pchan->vmid_local,
- pchan->vmid_remote, pchan->vcnt);
+ pchan->vmid_remote, pchan->sequence_tx,
+ pchan->sequence_rx, pchan->status, pchan->vcnt);
read_lock(&pchan->vchans_lock);
list_for_each_entry(vc, &pchan->vchannels, pnode) {
ret = hab_stat_buffer_print(buf, size,
- "%08X ", vc->id);
+ "%08X(%d:%d) ", vc->id,
+ get_refcnt(vc->refcount),
+ vc->otherend_closed);
}
ret = hab_stat_buffer_print(buf, size, "\n");
read_unlock(&pchan->vchans_lock);
diff --git a/drivers/soc/qcom/hab/hab_vchan.c b/drivers/soc/qcom/hab/hab_vchan.c
index 8d818b8fafb1..a95d6c7451c9 100644
--- a/drivers/soc/qcom/hab/hab_vchan.c
+++ b/drivers/soc/qcom/hab/hab_vchan.c
@@ -85,9 +85,6 @@ hab_vchan_free(struct kref *ref)
}
spin_unlock_bh(&vchan->rx_lock);
- /* the release vchan from ctx was done earlier in vchan close() */
- hab_ctx_put(ctx); /* now ctx is not needed from this vchan's view */
-
/* release vchan from pchan. no more msg for this vchan */
write_lock_bh(&pchan->vchans_lock);
list_for_each_entry_safe(vc, vc_tmp, &pchan->vchannels, pnode) {
@@ -100,6 +97,9 @@ hab_vchan_free(struct kref *ref)
}
write_unlock_bh(&pchan->vchans_lock);
+ /* the release vchan from ctx was done earlier in vchan close() */
+ hab_ctx_put(ctx); /* now ctx is not needed from this vchan's view */
+
/* release idr at the last so same idr will not be used early */
spin_lock_bh(&pchan->vid_lock);
idr_remove(&pchan->vchan_idr, HAB_VCID_GET_ID(vchan->id));
@@ -167,6 +167,7 @@ hab_vchan_get(struct physical_channel *pchan, struct hab_header *header)
return vchan;
}
+/* wake up local waiting Q, so stop-vchan can be processed */
void hab_vchan_stop(struct virtual_channel *vchan)
{
if (vchan) {
@@ -190,6 +191,7 @@ void hab_vchans_stop(struct physical_channel *pchan)
read_unlock(&pchan->vchans_lock);
}
+/* send vchan close to remote and stop receiving anything locally */
void hab_vchan_stop_notify(struct virtual_channel *vchan)
{
hab_send_close_msg(vchan);
@@ -204,15 +206,22 @@ static int hab_vchans_per_pchan_empty(struct physical_channel *pchan)
empty = list_empty(&pchan->vchannels);
if (!empty) {
struct virtual_channel *vchan;
+ int vcnt = pchan->vcnt;
list_for_each_entry(vchan, &pchan->vchannels, pnode) {
- pr_err("vchan %pK id %x remote id %x session %d ref %d closed %d remote close %d\n",
- vchan, vchan->id, vchan->otherend_id,
- vchan->session_id,
- get_refcnt(vchan->refcount), vchan->closed,
- vchan->otherend_closed);
+ /* discount open-pending unpaired vchan */
+ if (!vchan->session_id)
+ vcnt--;
+ else
+ pr_err("vchan %pK %x rm %x sn %d rf %d clsd %d rm clsd %d\n",
+ vchan, vchan->id,
+ vchan->otherend_id,
+ vchan->session_id,
+ get_refcnt(vchan->refcount),
+ vchan->closed, vchan->otherend_closed);
}
-
+ if (!vcnt)
+ empty = 1;/* unpaired vchan can exist at init time */
}
read_unlock(&pchan->vchans_lock);
@@ -265,48 +274,18 @@ int hab_vchan_find_domid(struct virtual_channel *vchan)
return vchan ? vchan->pchan->dom_id : -1;
}
-/* this sould be only called once after refcnt is zero */
-static void hab_vchan_schedule_free(struct kref *ref)
-{
- struct virtual_channel *vchanin =
- container_of(ref, struct virtual_channel, refcount);
- struct uhab_context *ctx = vchanin->ctx;
- struct virtual_channel *vchan, *tmp;
- int bnotify = 0;
-
- /*
- * similar logic is in ctx free. if ctx free runs first,
- * this is skipped
- */
- write_lock_bh(&ctx->ctx_lock);
- list_for_each_entry_safe(vchan, tmp, &ctx->vchannels, node) {
- if (vchan == vchanin) {
- pr_debug("vchan free refcnt = %d\n",
- get_refcnt(vchan->refcount));
- ctx->vcnt--;
- list_del(&vchan->node);
- bnotify = 1;
- break;
- }
- }
- write_unlock_bh(&ctx->ctx_lock);
-
- if (bnotify)
- hab_vchan_stop_notify(vchan);
-
- hab_vchan_free(ref);
-}
-
void hab_vchan_put(struct virtual_channel *vchan)
{
if (vchan)
- kref_put(&vchan->refcount, hab_vchan_schedule_free);
+ kref_put(&vchan->refcount, hab_vchan_free);
}
int hab_vchan_query(struct uhab_context *ctx, int32_t vcid, uint64_t *ids,
char *names, size_t name_size, uint32_t flags)
{
- struct virtual_channel *vchan = hab_get_vchan_fromvcid(vcid, ctx);
+ struct virtual_channel *vchan;
+
+ vchan = hab_get_vchan_fromvcid(vcid, ctx, 1);
if (!vchan)
return -EINVAL;
diff --git a/drivers/soc/qcom/hab/qvm_comm.c b/drivers/soc/qcom/hab/qvm_comm.c
index cce24d72c28e..ab57f2758aed 100644
--- a/drivers/soc/qcom/hab/qvm_comm.c
+++ b/drivers/soc/qcom/hab/qvm_comm.c
@@ -56,6 +56,7 @@ int physical_channel_send(struct physical_channel *pchan,
return -EAGAIN; /* not enough free space */
}
+ header->sequence = pchan->sequence_tx + 1;
header->signature = HAB_HEAD_SIGNATURE;
if (hab_pipe_write(dev->pipe_ep,
@@ -92,7 +93,7 @@ int physical_channel_send(struct physical_channel *pchan,
hab_pipe_write_commit(dev->pipe_ep);
spin_unlock_bh(&dev->io_lock);
habhyp_notify(dev);
-
+ ++pchan->sequence_tx;
return 0;
}
@@ -117,6 +118,8 @@ void physical_channel_rx_dispatch(unsigned long data)
header.sequence);
}
+ pchan->sequence_rx = header.sequence;
+
hab_msg_recv(pchan, &header);
}
spin_unlock_bh(&pchan->rxbuf_lock);
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index 7604affe63a8..b20cf2d65a6a 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -539,6 +539,7 @@ static struct msm_soc_info cpu_of_id[] = {
[312] = {MSM_CPU_8996, "APQ8096pro"},
[315] = {MSM_CPU_8996, "MSM8996pro"},
[316] = {MSM_CPU_8996, "APQ8096pro"},
+ [387] = {MSM_CPU_8996, "APQ8096A"},
/* 8976 ID */
[266] = {MSM_CPU_8976, "MSM8976"},
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
index c48d8c8d9766..92ccddea1fc5 100644
--- a/sound/soc/soc-ops.c
+++ b/sound/soc/soc-ops.c
@@ -379,7 +379,7 @@ int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol,
unsigned int rshift = mc->rshift;
int max = mc->max;
int min = mc->min;
- int mask = (1 << (fls(min + max) - 1)) - 1;
+ unsigned int mask = (1 << (fls(min + max) - 1)) - 1;
unsigned int val;
int ret;
@@ -424,7 +424,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
unsigned int rshift = mc->rshift;
int max = mc->max;
int min = mc->min;
- int mask = (1 << (fls(min + max) - 1)) - 1;
+ unsigned int mask = (1 << (fls(min + max) - 1)) - 1;
int err = 0;
unsigned int val, val_mask, val2 = 0;