OSDN Git Service

Merge "mdss: mdp: Add null check for ctl"
authorLinux Build Service Account <lnxbuild@localhost>
Fri, 28 Sep 2018 12:48:48 +0000 (05:48 -0700)
committerGerrit - the friendly Code Review server <code-review@localhost>
Fri, 28 Sep 2018 12:48:48 +0000 (05:48 -0700)
17 files changed:
arch/arm/boot/dts/qcom/dsi-panel-lgd-incell-sw49106-fhd-video.dtsi
arch/arm/boot/dts/qcom/msm8996-cv2x.dtsi
arch/arm/boot/dts/qcom/sdm630-cdp.dtsi
arch/arm/boot/dts/qcom/sdm630-mdss-panels.dtsi
arch/arm/boot/dts/qcom/sdm630-mtp.dtsi
arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-ivi.dts
arch/arm64/configs/msm-auto-perf_defconfig
arch/arm64/configs/msm-auto_defconfig
drivers/crypto/msm/qce50.c
drivers/iommu/iommu-debug.c
drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
drivers/soc/qcom/hab/hab_mem_linux.c
drivers/soc/qcom/wcd-dsp-glink.c
drivers/soundwire/soundwire.c [changed mode: 0755->0644]
drivers/soundwire/swr-wcd-ctrl.c
drivers/video/fbdev/msm/msm_dba/adv7533.c
sound/soc/codecs/wsa881x.c

index 8db5317..7eb677d 100644 (file)
                qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
                qcom,mdss-dsi-off-command-state = "dsi_lp_mode";
                qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
-               qcom,mdss-dsi-reset-sequence = <1 200>, <0 200>, <1 200>;
+               qcom,mdss-dsi-reset-sequence = <1 400>, <0 400>, <1 400>;
                qcom,mdss-dsi-tx-eot-append;
                qcom,mdss-dsi-post-init-delay = <1>;
        };
index 8be20b4..5a266cd 100644 (file)
                };
        };
 
-       aliases {
-               mhi_rmnet0 = &mhi_rmnet_0;
-               mhi_rmnet1 = &mhi_rmnet_1;
-               mhi_uci0 = &mhi_uci;
-               mhi0 = &mhi;
-       };
-
        gpio-leds {
                compatible = "gpio-leds";
 
                gpio = <&tlmm 125 0>;
        };
 
-       mhi_rmnet_0: qcom,mhi-rmnet@0 {
-               compatible = "qcom,mhi-rmnet";
-               cell-index = <0>;
-               qcom,mhi = <&mhi>;
-               qcom,mhi-rx-channel = <101>;
-               qcom,mhi-tx-channel = <100>;
-               qcom,mhi-mru = <0x4000>;
-               status = "okay";
-       };
-
-       mhi_rmnet_1: qcom,mhi-rmnet@1 {
-               compatible = "qcom,mhi-rmnet";
-               cell-index = <1>;
-               qcom,mhi = <&mhi>;
-               qcom,mhi-rx-channel = <47>;
-               qcom,mhi-tx-channel = <46>;
-               qcom,mhi-mru = <0x4000>;
-               qcom,interface-name = "mhi_swip";
-               status = "okay";
-       };
-
-       mhi_uci: qcom,mhi-uci {
-               compatible = "qcom,mhi-uci";
-               qcom,mhi-uci-channels = <0 0xffff>,
-                                       <1 0x1000>,
-                                       <2 0xffff>,
-                                       <3 0xffff>,
-                                       <10 0xffff>,
-                                       <11 0x1000>,
-                                       <14 0xffff>,
-                                       <15 0x1000>,
-                                       <16 0xffff>,
-                                       <17 0x1000>,
-                                       <18 0xffff>,
-                                       <19 0x1000>,
-                                       <22 0xffff>,
-                                       <23 0x1000>,
-                                       <24 0xffff>,
-                                       <25 0x1000>,
-                                       <32 0xffff>,
-                                       <33 0x1000>;
-               qcom,mhi-uci-ctrlchan = <18>;
-               qcom,mhi = <&mhi>;
-               status = "okay";
-       };
-
        qcom,diagfwd-usb {
                compatible = "qcom,diagfwd-usb";
                status = "okay";
        /delete-property/ qcom,l1ss-supported;
 };
 
-&mdm3 {
-       pinctrl-names = "mdm_active", "mdm_suspend";
-       pinctrl-0 = <&ap2mdm_active &mdm2ap_active>;
-       pinctrl-1 = <&ap2mdm_sleep &mdm2ap_sleep>;
-       interrupt-map = <0 &tlmm 108 0x3
-                       1 &tlmm 106 0x3
-                       2 &tlmm 112 0x3>;
-       qcom,mdm2ap-errfatal-gpio = <&tlmm 108 0x00>;
-       qcom,ap2mdm-errfatal-gpio = <&tlmm 109 0x00>;
-       qcom,mdm2ap-status-gpio   = <&tlmm 106 0x00>;
-       qcom,ap2mdm-status-gpio   = <&tlmm 107 0x00>;
-       qcom,ap2mdm-soft-reset-gpio = <&pm8994_mpps 2 0x00>;
-       qcom,ap2mdm-vddmin-gpio = <&tlmm 111 0x00>;
-       qcom,mdm2ap-vddmin-gpio = <&tlmm 112 0x00>;
-       qcom,mdm-auto-boot;
-       qcom,ignore-ssr-failure;
-       qcom,mdm-link-info = "0302_02.01.00";
-       qcom,mdm-statusline-not-a-powersource;
-       qcom,mdm-userspace-handle-shutdown;
-       qcom,pil-force-shutdown;
-       qcom,shutdown-timeout-ms = <30000>;
-       qcom,reset-time-ms = <16203>;
-       status = "okay";
-};
-
-&mhi {
-       qcom,mhi-address-window = <0x0 0x80000000 0x1 0xffffffff>;
-       qcom,pci-dev_id = <0x0302>;
-       qcom,pci-domain = <2>;
-       qcom,pci-bus = <1>;
-       qcom,pci-slot = <0>;
-       esoc-names = "mdm";
-       esoc-0 = <&mdm3>;
-       qcom,msm-bus,name = "mhi";
-       qcom,msm-bus,num-cases = <2>;
-       qcom,msm-bus,num-paths = <1>;
-       qcom,msm-bus,vectors-KBps =
-               <100 512 0 0>,
-               <100 512 1200000000 650000000>;
-       mhi-chan-cfg-0 = <0x0 0x80 0x2 0x92>;
-       mhi-chan-cfg-1 = <0x1 0x80 0x2 0xa2>;
-       mhi-chan-cfg-2 = <0x2 0x80 0x1 0x91>;
-       mhi-chan-cfg-3 = <0x3 0x80 0x1 0xa1>;
-       mhi-chan-cfg-4 = <0x4 0x80 0x2 0x92>;
-       mhi-chan-cfg-5 = <0x5 0x80 0x2 0xa2>;
-       mhi-chan-cfg-6 = <0x6 0xa 0x2 0x92>;
-       mhi-chan-cfg-7 = <0x7 0xa 0x2 0xa2>;
-       mhi-chan-cfg-10 = <0xa 0x80 0x1 0x92>;
-       mhi-chan-cfg-11 = <0xb 0x80 0x1 0xa2>;
-       mhi-chan-cfg-14 = <0xe 0x40 0x1 0x92>;
-       mhi-chan-cfg-15 = <0xf 0x40 0x1 0xa2>;
-       mhi-chan-cfg-16 = <0x10 0x40 0x1 0x92>;
-       mhi-chan-cfg-17 = <0x11 0x40 0x1 0xa2>;
-       mhi-chan-cfg-18 = <0x12 0x40 0x1 0x92>;
-       mhi-chan-cfg-19 = <0x13 0x40 0x1 0xa2>;
-       mhi-chan-cfg-20 = <0x14 0xa 0x2 0x92>;
-       mhi-chan-cfg-21 = <0x15 0xa 0x2 0xa2>;
-       mhi-chan-cfg-22 = <0x16 0x40 0x2 0x92>;
-       mhi-chan-cfg-23 = <0x17 0x40 0x2 0xa2>;
-       mhi-chan-cfg-24 = <0x18 0xa 0x1 0x91>;
-       mhi-chan-cfg-25 = <0x19 0xa 0x1 0xa1>;
-       mhi-chan-cfg-32 = <0x20 0x80 0x2 0x92>;
-       mhi-chan-cfg-33 = <0x21 0x80 0x2 0xa2>;
-       mhi-chan-cfg-34 = <0x22 0x80 0x2 0x92>;
-       mhi-chan-cfg-35 = <0x23 0x80 0x2 0xa2>;
-       mhi-chan-cfg-46 = <0x2e 0x80 0x2 0x412>;
-       mhi-chan-cfg-47 = <0x2f 0x80 0x3 0x422>;
-       mhi-chan-cfg-100 = <0x64 0x80 0x4 0x652>;
-       mhi-chan-cfg-101 = <0x65 0x80 0x5 0x762>;
-       mhi-event-rings = <6>;
-       mhi-event-cfg-0 = <0x80 0x0 0x1 0 1 0x11>;
-       mhi-event-cfg-1 = <0x80 0x1 0x1 0 1 0x11>;
-       mhi-event-cfg-2 = <0x80 0x2 0x5 0 2 0x11>;
-       mhi-event-cfg-3 = <0x100 0x3 0x1 47 1 0x48>;
-       mhi-event-cfg-4 = <0x100 0x4 0x1 100 1 0x69>;
-       mhi-event-cfg-5 = <0x100 0x5 0x1 101 1 0x68>;
-       status = "okay";
-};
-
 &pm8994_gpios {
        gpio@c700 { /* GPIO 8 - WLAN_EN */
                qcom,mode = <1>;                /* Digital output*/
index fd10945..6b409c0 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-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
        qcom,panel-roi-alignment = <2 2 4 2 1080 2>;
 };
 
+&dsi_lgd_incell_sw49106_fhd_video {
+       qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+       qcom,mdss-dsi-bl-min-level = <1>;
+       qcom,mdss-dsi-bl-max-level = <4095>;
+       qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+};
+
 &pm660l_pwm_4 {
        qcom,dtest-line = <2>;   /* DTEST2 */
        qcom,dtest-output = <2>; /* OUTPUT PWM */
index 4e3ebd4..16cfbd0 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-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
@@ -17,6 +17,7 @@
 #include "dsi-panel-truly-1080p-video.dtsi"
 #include "dsi-panel-rm67195-amoled-fhd-cmd.dtsi"
 #include "dsi-panel-sharp-split-link-wuxga-video.dtsi"
+#include "dsi-panel-lgd-incell-sw49106-fhd-video.dtsi"
 
 &soc {
        dsi_panel_pwr_supply: dsi_panel_pwr_supply {
        qcom,mdss-dsi-pan-enable-dynamic-fps;
        qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp";
 };
+
+&dsi_lgd_incell_sw49106_fhd_video {
+       qcom,mdss-dsi-panel-timings-phy-v2 = [24 1f 08 09 05 03 04 a0
+               24 1f 08 09 05 03 04 a0
+               24 1f 08 09 05 03 04 a0
+               24 1f 08 09 05 03 04 a0
+               24 1b 08 09 05 03 04 a0];
+       qcom,mdss-dsi-t-clk-post = <0x0d>;
+       qcom,mdss-dsi-t-clk-pre = <0x30>;
+};
index fd7cc8a..19d1cb4 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-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
 &dsi_rm67195_amoled_fhd_cmd {
        qcom,panel-supply-entries = <&dsi_panel_pwr_supply_labibb_amoled>;
 };
+
+&dsi_lgd_incell_sw49106_fhd_video {
+       qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+       qcom,mdss-dsi-bl-min-level = <1>;
+       qcom,mdss-dsi-bl-max-level = <4095>;
+       qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+};
index 5f622b4..ae2ec05 100644 (file)
        qcom,msm-id = <246 0x0>;
 };
 
+&ion {
+       /delete-node/ qcom,ion-heap@25;
+
+       system_heap: qcom,ion-heap@25 {
+               reg = <25>;
+               qcom,ion-heap-type = "SYSTEM";
+       };
+
+       audio_heap: qcom,ion-heap@28 {
+               reg = <28>;
+               memory-region = <&ion_audio>;
+               qcom,ion-heap-type = "CARVEOUT";
+       };
+};
+
 &reserved_memory {
                pmem_shared: pmem_shared_region@1154ca000 {
                        reg = <0x1 0x154ca000 0x0 0x154ca000>;
                        label = "pmem_shared_mem";
                };
 
-               ion_system: ion_system_region@12a994000 {
-                       reg = <0x1 0x2a994000 0x0 0x154ca000>;
-                       label = "ion_system_mem";
+               ion_audio: ion_audio_region {
+                       reg = <0 0xf0000000 0 0x00400000>;
+                       label = "ion_audio_mem";
                };
 };
index 475fa24..0f624b6 100644 (file)
@@ -511,7 +511,6 @@ CONFIG_REMOTE_SPINLOCK_MSM=y
 CONFIG_IOMMU_IO_PGTABLE_FAST=y
 CONFIG_ARM_SMMU=y
 CONFIG_IOMMU_DEBUG=y
-CONFIG_IOMMU_TESTS=y
 CONFIG_MSM_PASR=y
 CONFIG_MSM_SMEM=y
 CONFIG_QPNP_HAPTIC=y
index 49416b3..39a9b67 100644 (file)
@@ -519,7 +519,6 @@ CONFIG_IOMMU_IO_PGTABLE_FAST_SELFTEST=y
 CONFIG_ARM_SMMU=y
 CONFIG_IOMMU_DEBUG=y
 CONFIG_IOMMU_DEBUG_TRACKING=y
-CONFIG_IOMMU_TESTS=y
 CONFIG_MSM_PASR=y
 CONFIG_MSM_SMEM=y
 CONFIG_QPNP_HAPTIC=y
index b44f926..598b1aa 100644 (file)
@@ -1,6 +1,6 @@
 /* Qualcomm Crypto Engine driver.
  *
- * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-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
@@ -2440,6 +2440,9 @@ static int _qce_sps_add_sg_data(struct qce_device *pce_dev,
        struct sps_iovec *iovec = sps_bam_pipe->iovec +
                                                sps_bam_pipe->iovec_count;
 
+       if (!sg_src)
+               return -ENOENT;
+
        while (nbytes > 0) {
                len = min(nbytes, sg_dma_len(sg_src));
                nbytes -= len;
index 566572a..e442534 100644 (file)
@@ -30,7 +30,7 @@
 #include <asm/dma-iommu.h>
 #include "iommu-debug.h"
 
-#if defined(CONFIG_IOMMU_DEBUG_TRACKING) || defined(CONFIG_IOMMU_TESTS)
+#if defined(CONFIG_IOMMU_TESTS)
 
 static const char *iommu_debug_attr_to_string(enum iommu_attr attr)
 {
index 58bfdb7..bf5296e 100644 (file)
@@ -570,15 +570,13 @@ static long msm_buf_mngr_subdev_ioctl(struct v4l2_subdev *sd,
                k_ioctl = *ptr;
                switch (k_ioctl.id) {
                case MSM_CAMERA_BUF_MNGR_IOCTL_ID_GET_BUF_BY_IDX: {
+                       struct msm_buf_mngr_info buf_info, *tmp = NULL;
 
                        if (k_ioctl.size != sizeof(struct msm_buf_mngr_info))
                                return -EINVAL;
                        if (!k_ioctl.ioctl_ptr)
                                return -EINVAL;
-#ifndef CONFIG_COMPAT
-                       {
-                               struct msm_buf_mngr_info buf_info, *tmp = NULL;
-
+                       if (!is_compat_task()) {
                                MSM_CAM_GET_IOCTL_ARG_PTR(&tmp,
                                        &k_ioctl.ioctl_ptr, sizeof(tmp));
                                if (copy_from_user(&buf_info, tmp,
@@ -587,7 +585,7 @@ static long msm_buf_mngr_subdev_ioctl(struct v4l2_subdev *sd,
                                }
                                k_ioctl.ioctl_ptr = (uintptr_t)&buf_info;
                        }
-#endif
+
                        argp = &k_ioctl;
                        rc = msm_cam_buf_mgr_ops(cmd, argp);
                        }
index da41536..428d3e7 100644 (file)
@@ -79,6 +79,7 @@ static int habmem_get_dma_pages_from_va(unsigned long address,
        vma = find_vma(current->mm, address);
        if (!vma || !vma->vm_file) {
                pr_err("cannot find vma\n");
+               rc = -EBADF;
                goto err;
        }
 
@@ -86,6 +87,7 @@ static int habmem_get_dma_pages_from_va(unsigned long address,
        fd = iterate_fd(current->files, 0, match_file, vma->vm_file);
        if (fd == 0) {
                pr_err("iterate_fd failed\n");
+               rc = -EBADF;
                goto err;
        }
 
@@ -93,10 +95,16 @@ static int habmem_get_dma_pages_from_va(unsigned long address,
        page_offset = offset/PAGE_SIZE;
 
        dmabuf = dma_buf_get(fd - 1);
+       if (IS_ERR_OR_NULL(dmabuf)) {
+               pr_err("dma_buf_get failed fd %d ret %pK\n", fd, dmabuf);
+               rc = -EBADF;
+               goto err;
+       }
 
        attach = dma_buf_attach(dmabuf, hab_driver.dev);
        if (IS_ERR_OR_NULL(attach)) {
                pr_err("dma_buf_attach failed\n");
+               rc = -EBADF;
                goto err;
        }
 
@@ -104,6 +112,7 @@ static int habmem_get_dma_pages_from_va(unsigned long address,
 
        if (IS_ERR_OR_NULL(sg_table)) {
                pr_err("dma_buf_map_attachment failed\n");
+               rc = -EBADF;
                goto err;
        }
 
@@ -154,12 +163,16 @@ static int habmem_get_dma_pages_from_fd(int32_t fd,
        int i, j, rc = 0;
 
        dmabuf = dma_buf_get(fd);
-       if (IS_ERR(dmabuf))
-               return PTR_ERR(dmabuf);
+       if (IS_ERR_OR_NULL(dmabuf)) {
+               pr_err("dma_buf_get failed fd %d ret %pK\n", fd, dmabuf);
+               rc = -EBADF;
+               goto err;
+       }
 
        attach = dma_buf_attach(dmabuf, hab_driver.dev);
        if (IS_ERR_OR_NULL(attach)) {
                pr_err("dma_buf_attach failed\n");
+               rc = -EBADF;
                goto err;
        }
 
@@ -167,6 +180,7 @@ static int habmem_get_dma_pages_from_fd(int32_t fd,
 
        if (IS_ERR_OR_NULL(sg_table)) {
                pr_err("dma_buf_map_attachment failed\n");
+               rc = -EBADF;
                goto err;
        }
 
index ee88a8a..50cef91 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-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
@@ -89,6 +89,9 @@ struct wdsp_glink_ch {
        /* Wait for ch connect state before sending any command */
        wait_queue_head_t ch_connect_wait;
 
+       /* Wait for ch local and remote disconnect before channel free */
+       wait_queue_head_t ch_free_wait;
+
        /*
         * Glink channel configuration. This has to be the last
         * member of the strucuture as it has variable size
@@ -338,7 +341,7 @@ static void wdsp_glink_notify_state(void *handle, const void *priv,
        mutex_lock(&ch->mutex);
        ch->channel_state = event;
        if (event == GLINK_CONNECTED) {
-               dev_dbg(wpriv->dev, "%s: glink channel: %s connected\n",
+               dev_info(wpriv->dev, "%s: glink channel: %s connected\n",
                        __func__, ch->ch_cfg.name);
 
                for (i = 0; i < ch->ch_cfg.no_of_intents; i++) {
@@ -360,31 +363,29 @@ static void wdsp_glink_notify_state(void *handle, const void *priv,
                                ch->ch_cfg.name);
 
                wake_up(&ch->ch_connect_wait);
-               mutex_unlock(&ch->mutex);
        } else if (event == GLINK_LOCAL_DISCONNECTED) {
                /*
                 * Don't use dev_dbg here as dev may not be valid if channel
                 * closed from driver close.
                 */
-               pr_debug("%s: channel: %s disconnected locally\n",
+               pr_info("%s: channel: %s disconnected locally\n",
                         __func__, ch->ch_cfg.name);
                mutex_unlock(&ch->mutex);
-
-               if (ch->free_mem) {
-                       kfree(ch);
-                       ch = NULL;
-               }
+               ch->free_mem = true;
+               wake_up(&ch->ch_free_wait);
+               return;
        } else if (event == GLINK_REMOTE_DISCONNECTED) {
-               dev_dbg(wpriv->dev, "%s: remote channel: %s disconnected remotely\n",
+               pr_info("%s: remote channel: %s disconnected remotely\n",
                         __func__, ch->ch_cfg.name);
-               mutex_unlock(&ch->mutex);
                /*
                 * If remote disconnect happens, local side also has
                 * to close the channel as per glink design in a
                 * separate work_queue.
                 */
-               queue_work(wpriv->work_queue, &ch->lcl_ch_cls_wrk);
+               if (wpriv && wpriv->work_queue != NULL)
+                       queue_work(wpriv->work_queue, &ch->lcl_ch_cls_wrk);
        }
+       mutex_unlock(&ch->mutex);
 }
 
 /*
@@ -399,11 +400,11 @@ static int wdsp_glink_close_ch(struct wdsp_glink_ch *ch)
        mutex_lock(&wpriv->glink_mutex);
        if (ch->handle) {
                ret = glink_close(ch->handle);
+               ch->handle = NULL;
                if (IS_ERR_VALUE(ret)) {
                        dev_err(wpriv->dev, "%s: glink_close is failed, ret = %d\n",
                                 __func__, ret);
                } else {
-                       ch->handle = NULL;
                        dev_dbg(wpriv->dev, "%s: ch %s is closed\n", __func__,
                                ch->ch_cfg.name);
                }
@@ -451,6 +452,7 @@ static int wdsp_glink_open_ch(struct wdsp_glink_ch *ch)
                        ch->handle = NULL;
                        ret = -EINVAL;
                }
+               ch->free_mem = false;
        } else {
                dev_err(wpriv->dev, "%s: ch %s is already opened\n", __func__,
                        ch->ch_cfg.name);
@@ -492,7 +494,7 @@ static int wdsp_glink_open_all_ch(struct wdsp_glink_priv *wpriv)
 
 err_open:
        for (j = 0; j < i; j++)
-               if (wpriv->ch[i])
+               if (wpriv->ch[j])
                        wdsp_glink_close_ch(wpriv->ch[j]);
 
 done:
@@ -631,6 +633,7 @@ static int wdsp_glink_ch_info_init(struct wdsp_glink_priv *wpriv,
                        goto err_ch_mem;
                }
                ch[i]->channel_state = GLINK_LOCAL_DISCONNECTED;
+               ch[i]->free_mem = true;
                memcpy(&ch[i]->ch_cfg, payload, ch_cfg_size);
                payload += ch_cfg_size;
 
@@ -654,6 +657,7 @@ static int wdsp_glink_ch_info_init(struct wdsp_glink_priv *wpriv,
                INIT_WORK(&ch[i]->lcl_ch_open_wrk, wdsp_glink_lcl_ch_open_wrk);
                INIT_WORK(&ch[i]->lcl_ch_cls_wrk, wdsp_glink_lcl_ch_cls_wrk);
                init_waitqueue_head(&ch[i]->ch_connect_wait);
+               init_waitqueue_head(&ch[i]->ch_free_wait);
        }
 
        INIT_WORK(&wpriv->ch_open_cls_wrk, wdsp_glink_ch_open_cls_wrk);
@@ -1060,36 +1064,48 @@ static int wdsp_glink_release(struct inode *inode, struct file *file)
                goto done;
        }
 
+       dev_info(wpriv->dev, "%s: closing wdsp_glink driver\n", __func__);
        if (wpriv->glink_state.handle)
                glink_unregister_link_state_cb(wpriv->glink_state.handle);
 
        flush_workqueue(wpriv->work_queue);
-       destroy_workqueue(wpriv->work_queue);
-
        /*
-        * Clean up glink channel memory in channel state
-        * callback only if close channels are called from here.
+        * Wait for channel local and remote disconnect state notifications
+        * before freeing channel memory.
         */
-       if (wpriv->ch) {
-               for (i = 0; i < wpriv->no_of_channels; i++) {
-                       if (wpriv->ch[i]) {
-                               wpriv->ch[i]->free_mem = true;
-                               /*
-                                * Channel handle NULL means channel is already
-                                * closed. Free the channel memory here itself.
-                                */
-                               if (!wpriv->ch[i]->handle) {
-                                       kfree(wpriv->ch[i]);
-                                       wpriv->ch[i] = NULL;
-                               } else {
-                                       wdsp_glink_close_ch(wpriv->ch[i]);
-                               }
+       for (i = 0; i < wpriv->no_of_channels; i++) {
+               if (wpriv->ch && wpriv->ch[i]) {
+                       /*
+                        * Only close glink channel from here if REMOTE has
+                        * not already disconnected it
+                        */
+                       wdsp_glink_close_ch(wpriv->ch[i]);
+
+                       ret = wait_event_timeout(wpriv->ch[i]->ch_free_wait,
+                                       (wpriv->ch[i]->free_mem == true),
+                                       msecs_to_jiffies(TIMEOUT_MS));
+                       if (!ret) {
+                               pr_err("%s: glink ch %s failed to notify states properly %d\n",
+                                       __func__, wpriv->ch[i]->ch_cfg.name,
+                                       wpriv->ch[i]->channel_state);
+                               ret = -EINVAL;
+                               goto done;
                        }
                }
+       }
 
-               kfree(wpriv->ch);
-               wpriv->ch = NULL;
+       flush_workqueue(wpriv->work_queue);
+       destroy_workqueue(wpriv->work_queue);
+       wpriv->work_queue = NULL;
+
+       for (i = 0; i < wpriv->no_of_channels; i++) {
+               if (wpriv->ch && wpriv->ch[i]) {
+                       kfree(wpriv->ch[i]);
+                       wpriv->ch[i] = NULL;
+               }
        }
+       kfree(wpriv->ch);
+       wpriv->ch = NULL;
 
        mutex_destroy(&wpriv->glink_mutex);
        mutex_destroy(&wpriv->rsp_mutex);
old mode 100755 (executable)
new mode 100644 (file)
index 6354565..0e8cc39
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-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
@@ -241,7 +241,7 @@ int swr_remove_from_group(struct swr_device *dev, u8 dev_num)
        if (!dev->group_id)
                return 0;
 
-       if (master->gr_sid == dev_num)
+       if (master->gr_sid != dev_num)
                return 0;
 
        if (master->remove_from_group && master->remove_from_group(master))
index 1dcaba2..a8458b9 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-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
@@ -1727,6 +1727,8 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
                    (swrm->state == SWR_MSTR_UP)) {
                        dev_dbg(swrm->dev, "%s: SWR master is already UP: %d\n",
                                __func__, swrm->state);
+                       list_for_each_entry(swr_dev, &mstr->devices, dev_list)
+                               swr_reset_device(swr_dev);
                } else {
                        pm_runtime_mark_last_busy(&pdev->dev);
                        mutex_unlock(&swrm->reslock);
index a21b6db..7878276 100644 (file)
@@ -1530,6 +1530,7 @@ static void adv7533_video_setup(struct adv7533 *pdata,
 {
        u32 h_total, hpw, hfp, hbp;
        u32 v_total, vpw, vfp, vbp;
+       int dsi_pixel_clock_divider = 0x00;
 
        if (!pdata || !cfg) {
                pr_err("%s: invalid input\n", __func__);
@@ -1557,6 +1558,26 @@ static void adv7533_video_setup(struct adv7533 *pdata,
                v_total, cfg->v_active, cfg->v_front_porch,
                cfg->v_pulse_width, cfg->v_back_porch);
 
+       /* 0x16: dsi pclk divider control.
+        * bit2: 1 = manual dsi pclk divider control; 0 = automatic dsi
+        *   pclk divider generation.
+        * bit3-7: the signal sets the dsi pclk divider setting when bit2
+        *   is enable.
+        *
+        * If bit2=0 means automatically select dsi pclk divider, so
+        * other bits(divider factor) has no impact.
+        *
+        * If bit2=1, the divider factor should be related to lane num below
+        * 4lanes : divide by 3; 3lanes : divide by 4; 2lanes : divide by 6
+        * So the value of 0x16 can be set as follow:
+        * 4 lanes : 0x1C(00011 100)
+        * 3 lanes : 0x24(00100 100)
+        * 2 lanes : 0x34(00110 100)
+        *
+        * Here, use automatic dsi pclk divider generation, so set 0x00
+        * to cec 0x16 register for all lanes numbers.
+        */
+       adv7533_write(pdata, I2C_ADDR_CEC_DSI, 0x16, dsi_pixel_clock_divider);
 
        /* h_width */
        adv7533_write(pdata, I2C_ADDR_CEC_DSI, 0x28, ((h_total & 0xFF0) >> 4));
index e4f6df0..0c672fd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-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
@@ -76,6 +76,7 @@ struct swr_port {
 enum {
        WSA881X_DEV_DOWN,
        WSA881X_DEV_UP,
+       WSA881X_DEV_READY,
 };
 
 /*
@@ -99,6 +100,7 @@ struct wsa881x_priv {
        int version;
        struct mutex bg_lock;
        struct mutex res_lock;
+       struct mutex temp_lock;
        struct snd_info_entry *entry;
        struct snd_info_entry *version_entry;
        int state;
@@ -464,6 +466,17 @@ static const struct file_operations codec_debug_ops = {
        .read = codec_debug_read,
 };
 
+static void wsa881x_regcache_sync(struct wsa881x_priv *wsa881x)
+{
+       mutex_lock(&wsa881x->res_lock);
+       if (wsa881x->state != WSA881X_DEV_READY) {
+               regcache_mark_dirty(wsa881x->regmap);
+               regcache_sync(wsa881x->regmap);
+               wsa881x->state = WSA881X_DEV_READY;
+       }
+       mutex_unlock(&wsa881x->res_lock);
+}
+
 static const struct reg_sequence wsa881x_pre_pmu_pa[] = {
        {WSA881X_SPKR_DRV_GAIN, 0x41, 0},
        {WSA881X_SPKR_MISC_CTL1, 0x01, 0},
@@ -790,7 +803,9 @@ static int wsa881x_rdac_event(struct snd_soc_dapm_widget *w,
 
        switch (event) {
        case SND_SOC_DAPM_PRE_PMU:
+               mutex_lock(&wsa881x->temp_lock);
                wsa881x_resource_acquire(codec, ENABLE);
+               mutex_unlock(&wsa881x->temp_lock);
                wsa881x_boost_ctrl(codec, ENABLE);
                break;
        case SND_SOC_DAPM_POST_PMD:
@@ -798,7 +813,9 @@ static int wsa881x_rdac_event(struct snd_soc_dapm_widget *w,
                                            wsa881x->swr_slave->dev_num,
                                            false);
                wsa881x_boost_ctrl(codec, DISABLE);
+               mutex_lock(&wsa881x->temp_lock);
                wsa881x_resource_acquire(codec, DISABLE);
+               mutex_unlock(&wsa881x->temp_lock);
                break;
        }
        return 0;
@@ -1042,13 +1059,8 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec,
                        return -EINVAL;
                }
        }
-       mutex_lock(&wsa881x->res_lock);
-       if (!wsa881x->clk_cnt) {
-               regcache_mark_dirty(wsa881x->regmap);
-               regcache_sync(wsa881x->regmap);
-       }
-       mutex_unlock(&wsa881x->res_lock);
-
+       wsa881x_regcache_sync(wsa881x);
+       mutex_lock(&wsa881x->temp_lock);
        wsa881x_resource_acquire(codec, ENABLE);
 
        snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x00);
@@ -1061,6 +1073,7 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec,
        wsa_temp_reg->d2_lsb = snd_soc_read(codec, WSA881X_OTP_REG_4);
 
        wsa881x_resource_acquire(codec, DISABLE);
+       mutex_unlock(&wsa881x->temp_lock);
 
        return 0;
 }
@@ -1076,7 +1089,6 @@ static int wsa881x_probe(struct snd_soc_codec *codec)
        dev = wsa881x->swr_slave;
        wsa881x->codec = codec;
        mutex_init(&wsa881x->bg_lock);
-       mutex_init(&wsa881x->res_lock);
        wsa881x_init(codec);
        snprintf(wsa881x->tz_pdata.name, sizeof(wsa881x->tz_pdata.name),
                "%s.%x", "wsatz", (u8)dev->addr);
@@ -1098,7 +1110,6 @@ static int wsa881x_remove(struct snd_soc_codec *codec)
        if (wsa881x->tz_pdata.tz_dev)
                wsa881x_deinit_thermal(wsa881x->tz_pdata.tz_dev);
        mutex_destroy(&wsa881x->bg_lock);
-       mutex_destroy(&wsa881x->res_lock);
 
        return 0;
 }
@@ -1224,6 +1235,8 @@ static int wsa881x_swr_probe(struct swr_device *pdev)
        if (wsa881x->wsa_rst_np)
                pin_state_current = msm_cdc_pinctrl_get_state(
                                                wsa881x->wsa_rst_np);
+       mutex_init(&wsa881x->res_lock);
+       mutex_init(&wsa881x->temp_lock);
        wsa881x_gpio_ctrl(wsa881x, true);
        wsa881x->state = WSA881X_DEV_UP;
 
@@ -1303,6 +1316,8 @@ static int wsa881x_swr_remove(struct swr_device *pdev)
                return -EINVAL;
        }
        debugfs_remove_recursive(debugfs_wsa881x_dent);
+       mutex_destroy(&wsa881x->res_lock);
+       mutex_destroy(&wsa881x->temp_lock);
        snd_soc_unregister_codec(&pdev->dev);
        if (wsa881x->pd_gpio)
                gpio_free(wsa881x->pd_gpio);
@@ -1361,6 +1376,11 @@ static int wsa881x_swr_reset(struct swr_device *pdev)
                dev_err(&pdev->dev, "%s: wsa881x is NULL\n", __func__);
                return -EINVAL;
        }
+       if (wsa881x->state == WSA881X_DEV_READY) {
+               dev_dbg(&pdev->dev, "%s: device already active\n", __func__);
+               return 0;
+       }
+
        wsa881x->bg_cnt = 0;
        wsa881x->clk_cnt = 0;
        while (swr_get_logical_dev_num(pdev, pdev->addr, &devnum) && retry--) {
@@ -1368,8 +1388,7 @@ static int wsa881x_swr_reset(struct swr_device *pdev)
                usleep_range(1000, 1100);
        }
        pdev->dev_num = devnum;
-       regcache_mark_dirty(wsa881x->regmap);
-       regcache_sync(wsa881x->regmap);
+       wsa881x_regcache_sync(wsa881x);
        return 0;
 }