diff options
| -rw-r--r-- | arch/arm/boot/dts/qcom/msm8996-pinctrl.dtsi | 14 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msm8996.dtsi | 8 | ||||
| -rw-r--r-- | arch/arm64/configs/msm-auto-perf_defconfig | 10 | ||||
| -rw-r--r-- | arch/arm64/configs/msm-auto_defconfig | 10 | ||||
| -rw-r--r-- | drivers/iio/imu/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/iio/imu/Makefile | 1 | ||||
| -rw-r--r-- | drivers/input/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/input/Makefile | 2 | ||||
| -rw-r--r-- | drivers/media/platform/msm/ais/msm_buf_mgr/msm_generic_buf_mgr.c | 19 | ||||
| -rw-r--r-- | drivers/soc/qcom/glink_smem_native_xprt.c | 2 | ||||
| -rw-r--r-- | drivers/soc/qcom/hab/hab.c | 66 | ||||
| -rw-r--r-- | drivers/soc/qcom/hab/hab.h | 5 | ||||
| -rw-r--r-- | drivers/soc/qcom/hab/hab_mem_linux.c | 9 | ||||
| -rw-r--r-- | drivers/soc/qcom/hab/hab_mimex.c | 12 | ||||
| -rw-r--r-- | drivers/soc/qcom/hab/hab_msg.c | 27 | ||||
| -rw-r--r-- | drivers/soc/qcom/hab/hab_open.c | 12 | ||||
| -rw-r--r-- | drivers/soc/qcom/hab/hab_stat.c | 9 | ||||
| -rw-r--r-- | drivers/soc/qcom/hab/hab_vchan.c | 65 | ||||
| -rw-r--r-- | drivers/soc/qcom/hab/qvm_comm.c | 5 | ||||
| -rw-r--r-- | drivers/soc/qcom/socinfo.c | 1 | ||||
| -rw-r--r-- | sound/soc/soc-ops.c | 4 |
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; |
