Merge "msm: wlan: Update regulatory database for SA"
diff --git a/arch/arm/configs/msm8909-perf_defconfig b/arch/arm/configs/msm8909-perf_defconfig
index 3f8ba5f..b4ae846 100644
--- a/arch/arm/configs/msm8909-perf_defconfig
+++ b/arch/arm/configs/msm8909-perf_defconfig
@@ -258,6 +258,7 @@
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_QPNP_POWER_ON=y
+CONFIG_STMVL53L0X=y
CONFIG_INPUT_UINPUT=y
CONFIG_SERIAL_MSM_HS=y
CONFIG_SERIAL_MSM_SMD=y
@@ -429,6 +430,8 @@
CONFIG_WCNSS_CORE_PRONTO=y
CONFIG_WCNSS_REGISTER_DUMP_ON_BITE=y
CONFIG_CNSS_CRYPTO=y
+CONFIG_IIO=y
+CONFIG_INV_ICM20602_IIO=y
CONFIG_PWM=y
CONFIG_PWM_QPNP=y
CONFIG_QTI_MPM=y
diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig
index 009ead2..4d1bda0 100644
--- a/arch/arm/configs/msm8909_defconfig
+++ b/arch/arm/configs/msm8909_defconfig
@@ -308,11 +308,18 @@
CONFIG_QPNP_LINEAR_CHARGER=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_THERMAL=y
+CONFIG_THERMAL_WRITABLE_TRIPS=y
+CONFIG_THERMAL_GOV_USER_SPACE=y
+CONFIG_THERMAL_GOV_LOW_LIMITS=y
+CONFIG_CPU_THERMAL=y
+CONFIG_DEVFREQ_THERMAL=y
CONFIG_THERMAL_QPNP=y
CONFIG_THERMAL_QPNP_ADC_TM=y
CONFIG_THERMAL_TSENS=y
CONFIG_MSM_BCL_PERIPHERAL_CTL=y
CONFIG_QTI_THERMAL_LIMITS_DCVS=y
+CONFIG_QTI_QMI_COOLING_DEVICE=y
+CONFIG_REGULATOR_COOLING_DEVICE=y
CONFIG_MFD_QCOM_RPM=y
CONFIG_MFD_SPMI_PMIC=y
CONFIG_MFD_SYSCON=y
diff --git a/arch/arm/configs/msm8909w-perf_defconfig b/arch/arm/configs/msm8909w-perf_defconfig
index 3094af9..0e56f7f 100644
--- a/arch/arm/configs/msm8909w-perf_defconfig
+++ b/arch/arm/configs/msm8909w-perf_defconfig
@@ -448,6 +448,7 @@
CONFIG_QTI_MPM=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_BINDER_IPC_32BIT=y
CONFIG_STM=y
CONFIG_SENSORS_SSC=y
CONFIG_MSM_TZ_LOG=y
diff --git a/arch/arm/configs/msm8909w_defconfig b/arch/arm/configs/msm8909w_defconfig
index 2abc5c0..8351322 100644
--- a/arch/arm/configs/msm8909w_defconfig
+++ b/arch/arm/configs/msm8909w_defconfig
@@ -440,6 +440,7 @@
CONFIG_QTI_MPM=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_BINDER_IPC_32BIT=y
CONFIG_SENSORS_SSC=y
CONFIG_MSM_TZ_LOG=y
CONFIG_EXT4_FS=y
diff --git a/arch/arm64/boot/dts/qcom/sdm845-670-usb-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-670-usb-common.dtsi
index 9b88356..c53367a 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-670-usb-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-670-usb-common.dtsi
@@ -141,7 +141,9 @@
0x198 /* PLL_BIAS_CONTROL_2 */
0x228 /* QUSB2PHY_SQ_CTRL1 */
0x22c /* QUSB2PHY_SQ_CTRL2 */
- 0x27c>; /* QUSB2PHY_DEBUG_CTRL1 */
+ 0x27c /* QUSB2PHY_DEBUG_CTRL1 */
+ 0x280 /* QUSB2PHY_DEBUG_CTRL2 */
+ 0x2a0>; /* QUSB2PHY_STAT5 */
qcom,qusb-phy-init-seq =
/* <value reg_offset> */
@@ -431,7 +433,9 @@
0x198 /* PLL_BIAS_CONTROL_2 */
0x228 /* QUSB2PHY_SQ_CTRL1 */
0x22c /* QUSB2PHY_SQ_CTRL2 */
- 0x27c>; /* QUSB2PHY_DEBUG_CTRL1 */
+ 0x27c /* QUSB2PHY_DEBUG_CTRL1 */
+ 0x280 /* QUSB2PHY_DEBUG_CTRL2 */
+ 0x2a0>; /* QUSB2PHY_STAT5 */
qcom,qusb-phy-init-seq =
/* <value reg_offset> */
diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig
index 8004333..f3c1e7b 100644
--- a/arch/arm64/configs/msm8953-perf_defconfig
+++ b/arch/arm64/configs/msm8953-perf_defconfig
@@ -471,6 +471,7 @@
CONFIG_USB_DWC3_MSM=y
CONFIG_USB_SERIAL=y
CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_LINK_LAYER_TEST=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_DUAL_ROLE_USB_INTF=y
CONFIG_USB_MSM_SSPHY_QMP=y
diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig
index 3cc3576..8401173c 100644
--- a/arch/arm64/configs/msm8953_defconfig
+++ b/arch/arm64/configs/msm8953_defconfig
@@ -481,6 +481,7 @@
CONFIG_USB_DWC3_MSM=y
CONFIG_USB_SERIAL=y
CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_LINK_LAYER_TEST=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_DUAL_ROLE_USB_INTF=y
CONFIG_USB_MSM_SSPHY_QMP=y
diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig
index 01de42c..bb2a5b5 100644
--- a/drivers/android/Kconfig
+++ b/drivers/android/Kconfig
@@ -32,9 +32,9 @@
therefore logically separated from the other devices.
config ANDROID_BINDER_IPC_32BIT
- bool
+ bool "Android Binder IPC 32BIT Driver"
depends on !64BIT && ANDROID_BINDER_IPC
- default y
+ default n
---help---
The Binder API has been changed to support both 32 and 64bit
applications in a mixed environment.
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 8643667..19f2289 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -1,7 +1,7 @@
/*
* QTI 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
@@ -6118,13 +6118,15 @@
int qce_close(void *handle)
{
struct qce_device *pce_dev = (struct qce_device *) handle;
+ int ret = -1;
if (handle == NULL)
return -ENODEV;
mutex_lock(&qce_iomap_mutex);
- qce_enable_clk(pce_dev);
- qce_sps_exit(pce_dev);
+ ret = qce_enable_clk(pce_dev);
+ if (!ret)
+ qce_sps_exit(pce_dev);
if (pce_dev->iobase)
iounmap(pce_dev->iobase);
@@ -6137,7 +6139,8 @@
if (pce_dev->enable_s1_smmu)
qce_iommu_release_iomapping(pce_dev);
- qce_disable_clk(pce_dev);
+ if (!ret)
+ qce_disable_clk(pce_dev);
__qce_deinit_clk(pce_dev);
mutex_unlock(&qce_iomap_mutex);
kfree(handle);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index d9839e7..a0a0daf 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1462,6 +1462,9 @@
int dp_display_get_num_of_displays(void)
{
+ if (!g_dp_display)
+ return 0;
+
return 1;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 8af8298..cb4e82d 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -6189,6 +6189,7 @@
unsigned long flags;
bool found = false;
int ret, i = 0;
+ bool add_event = false;
crtc = to_sde_crtc(crtc_drm);
spin_lock_irqsave(&crtc->spin_lock, flags);
@@ -6238,11 +6239,24 @@
}
INIT_LIST_HEAD(&node->irq.list);
+
+ mutex_lock(&crtc->crtc_lock);
ret = node->func(crtc_drm, true, &node->irq);
+ if (!ret) {
+ spin_lock_irqsave(&crtc->spin_lock, flags);
+ list_add_tail(&node->list, &crtc->user_event_list);
+ add_event = true;
+ spin_unlock_irqrestore(&crtc->spin_lock, flags);
+ }
+ mutex_unlock(&crtc->crtc_lock);
+
sde_power_resource_enable(&priv->phandle, kms->core_client,
false);
}
+ if (add_event)
+ return 0;
+
if (!ret) {
spin_lock_irqsave(&crtc->spin_lock, flags);
list_add_tail(&node->list, &crtc->user_event_list);
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 696b15c..ed0e7b8 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -2664,7 +2664,15 @@
SDE_DEBUG("info.is_connected = %s, info.is_primary = %s\n",
((info.is_connected) ? "true" : "false"),
((info.is_primary) ? "true" : "false"));
- break;
+
+ /**
+ * Since we are supporting one DSI for splash, use the display
+ * which is marked as primary.
+ */
+ if (!info.is_primary)
+ continue;
+ else
+ break;
}
if (!encoder) {
diff --git a/drivers/leds/leds-qpnp-wled.c b/drivers/leds/leds-qpnp-wled.c
index 861d987..d272ca6 100644
--- a/drivers/leds/leds-qpnp-wled.c
+++ b/drivers/leds/leds-qpnp-wled.c
@@ -22,6 +22,7 @@
#include <linux/spmi.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/leds-qpnp-wled.h>
@@ -420,6 +421,7 @@
bool prev_state;
bool stepper_en;
bool ovp_irq_disabled;
+ bool secure_mode;
bool auto_calib_enabled;
bool auto_calib_done;
bool module_dis_perm;
@@ -936,6 +938,46 @@
return count;
}
+/* sysfs function for irqs enable/disable */
+static ssize_t qpnp_wled_irq_control(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct qpnp_wled *wled = dev_get_drvdata(dev);
+ int val, rc;
+
+ rc = kstrtouint(buf, 0, &val);
+ if (rc < 0)
+ return rc;
+
+ if (val != 0 && val != 1)
+ return count;
+
+ mutex_lock(&wled->lock);
+ /* Disable irqs */
+ if (val == 1 && !wled->secure_mode) {
+ if (wled->ovp_irq > 0)
+ disable_irq(wled->ovp_irq);
+
+ if (wled->sc_irq > 0)
+ disable_irq(wled->sc_irq);
+
+ wled->secure_mode = true;
+ } else if (val == 0 && wled->secure_mode) {
+ if (wled->ovp_irq > 0)
+ enable_irq(wled->ovp_irq);
+
+ if (wled->sc_irq > 0)
+ enable_irq(wled->sc_irq);
+
+ wled->secure_mode = false;
+ }
+
+ mutex_unlock(&wled->lock);
+
+ return count;
+}
+
/* sysfs show function for dim mode */
static ssize_t qpnp_wled_dim_mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -1055,6 +1097,7 @@
__ATTR(ramp_ms, 0664, qpnp_wled_ramp_ms_show, qpnp_wled_ramp_ms_store),
__ATTR(ramp_step, 0664, qpnp_wled_ramp_step_show,
qpnp_wled_ramp_step_store),
+ __ATTR(secure_mode, 0664, NULL, qpnp_wled_irq_control),
};
/* worker for setting wled brightness */
@@ -1066,6 +1109,12 @@
wled = container_of(work, struct qpnp_wled, work);
mutex_lock(&wled->lock);
+
+ if (wled->secure_mode) {
+ pr_debug("Can not set brightness in secure_mode\n ");
+ goto unlock_mutex;
+ }
+
level = wled->cdev.brightness;
if (wled->brt_map_table) {
@@ -2162,6 +2211,7 @@
/* setup ovp and sc irqs */
if (wled->ovp_irq >= 0) {
+ irq_set_status_flags(wled->ovp_irq, IRQ_DISABLE_UNLAZY);
rc = devm_request_threaded_irq(&wled->pdev->dev, wled->ovp_irq,
NULL, qpnp_wled_ovp_irq_handler, IRQF_ONESHOT,
"qpnp_wled_ovp_irq", wled);
@@ -2182,6 +2232,7 @@
if (wled->sc_irq >= 0) {
wled->sc_cnt = 0;
+ irq_set_status_flags(wled->sc_irq, IRQ_DISABLE_UNLAZY);
rc = devm_request_threaded_irq(&wled->pdev->dev, wled->sc_irq,
NULL, qpnp_wled_sc_irq_handler, IRQF_ONESHOT,
"qpnp_wled_sc_irq", wled);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 8a773e4..5bfb8e4 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -6205,15 +6205,17 @@
}
IPADBG("AP/USB SMMU atomic set\n");
- if (iommu_domain_set_attr(cb->mapping->domain,
+ if (smmu_info.fast_map) {
+ if (iommu_domain_set_attr(cb->mapping->domain,
DOMAIN_ATTR_FAST,
&fast)) {
- IPAERR("couldn't set fast map\n");
- arm_iommu_release_mapping(cb->mapping);
- cb->valid = false;
- return -EIO;
+ IPAERR("couldn't set fast map\n");
+ arm_iommu_release_mapping(cb->mapping);
+ cb->valid = false;
+ return -EIO;
+ }
+ IPADBG("SMMU fast map set\n");
}
- IPADBG("SMMU fast map set\n");
}
pr_info("IPA smmu_info.s1_bypass_arr[AP]=%d smmu_info.fast_map=%d\n",
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
index 7065e2c..2716d4a 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
@@ -1516,6 +1516,8 @@
ipa3_ctx->nat_mem.pdn_mem.size,
ipa3_ctx->nat_mem.pdn_mem.base,
ipa3_ctx->nat_mem.pdn_mem.phys_base);
+ ipa3_ctx->nat_mem.pdn_mem.base = NULL;
+ ipa3_ctx->nat_mem.dev.is_mem_allocated = false;
}
ipa3_nat_ipv6ct_free_mem(&ipa3_ctx->nat_mem.dev);
diff --git a/drivers/platform/msm/mhi_dev/mhi.h b/drivers/platform/msm/mhi_dev/mhi.h
index 26baa64..6cb2d7d 100644
--- a/drivers/platform/msm/mhi_dev/mhi.h
+++ b/drivers/platform/msm/mhi_dev/mhi.h
@@ -14,9 +14,8 @@
#define __MHI_H
#include <linux/msm_ep_pcie.h>
-#include <linux/types.h>
#include <linux/ipc_logging.h>
-#include <linux/dma-mapping.h>
+#include <linux/msm_mhi_dev.h>
/**
* MHI control data structures alloted by the host, including
@@ -276,8 +275,6 @@
#define MHI_MASK_ROWS_CH_EV_DB 4
#define TRB_MAX_DATA_SIZE 8192
#define MHI_CTRL_STATE 100
-#define IPA_DMA_SYNC 1
-#define IPA_DMA_ASYNC 0
/*maximum trasnfer completion events buffer*/
#define MAX_TR_EVENTS 50
@@ -360,13 +357,6 @@
MHI_DEV_POLL,
};
-enum mhi_ctrl_info {
- MHI_STATE_CONFIGURED = 0,
- MHI_STATE_CONNECTED = 1,
- MHI_STATE_DISCONNECTED = 2,
- MHI_STATE_INVAL,
-};
-
enum mhi_dev_tr_compl_evt_type {
SEND_EVENT_BUFFER,
SEND_EVENT_RD_OFFSET,
@@ -420,38 +410,6 @@
#define MHI_DEV_MMIO_RANGE 0xc80
-enum cb_reason {
- MHI_DEV_TRE_AVAILABLE = 0,
- MHI_DEV_CTRL_UPDATE,
-};
-
-struct mhi_dev_client_cb_reason {
- uint32_t ch_id;
- enum cb_reason reason;
-};
-
-struct mhi_dev_client {
- struct list_head list;
- struct mhi_dev_channel *channel;
- void (*event_trigger)(struct mhi_dev_client_cb_reason *cb);
-
- /* mhi_dev calls are fully synchronous -- only one call may be
- * active per client at a time for now.
- */
- struct mutex write_lock;
- wait_queue_head_t wait;
-
- /* trace logs */
- spinlock_t tr_lock;
- unsigned int tr_head;
- unsigned int tr_tail;
- struct mhi_dev_trace *tr_log;
-
- /* client buffers */
- struct mhi_dev_iov *iov;
- uint32_t nr_iov;
-};
-
struct ring_cache_req {
struct completion *done;
void *context;
@@ -609,32 +567,15 @@
/* MHI state info */
enum mhi_ctrl_info ctrl_info;
- /*Register for interrupt */
+ /*Register for interrupt*/
bool mhi_int;
bool mhi_int_en;
-
/* Registered client callback list */
struct list_head client_cb_list;
struct kobj_uevent_env kobj_env;
};
-struct mhi_req {
- u32 chan;
- u32 mode;
- u32 chain;
- void *buf;
- dma_addr_t dma;
- u32 snd_cmpl;
- void *context;
- size_t len;
- size_t actual_len;
- uint32_t rd_offset;
- struct mhi_dev_client *client;
- struct list_head list;
- union mhi_dev_ring_element_type *el;
- void (*client_cb)(void *req);
-};
enum mhi_msg_level {
MHI_MSG_VERBOSE = 0x0,
@@ -660,70 +601,8 @@
} \
} while (0)
-/* SW channel client list */
-enum mhi_client_channel {
- MHI_CLIENT_LOOPBACK_OUT = 0,
- MHI_CLIENT_LOOPBACK_IN = 1,
- MHI_CLIENT_SAHARA_OUT = 2,
- MHI_CLIENT_SAHARA_IN = 3,
- MHI_CLIENT_DIAG_OUT = 4,
- MHI_CLIENT_DIAG_IN = 5,
- MHI_CLIENT_SSR_OUT = 6,
- MHI_CLIENT_SSR_IN = 7,
- MHI_CLIENT_QDSS_OUT = 8,
- MHI_CLIENT_QDSS_IN = 9,
- MHI_CLIENT_EFS_OUT = 10,
- MHI_CLIENT_EFS_IN = 11,
- MHI_CLIENT_MBIM_OUT = 12,
- MHI_CLIENT_MBIM_IN = 13,
- MHI_CLIENT_QMI_OUT = 14,
- MHI_CLIENT_QMI_IN = 15,
- MHI_CLIENT_IP_CTRL_0_OUT = 16,
- MHI_CLIENT_IP_CTRL_0_IN = 17,
- MHI_CLIENT_IP_CTRL_1_OUT = 18,
- MHI_CLIENT_IP_CTRL_1_IN = 19,
- MHI_CLIENT_DCI_OUT = 20,
- MHI_CLIENT_DCI_IN = 21,
- MHI_CLIENT_IP_CTRL_3_OUT = 22,
- MHI_CLIENT_IP_CTRL_3_IN = 23,
- MHI_CLIENT_IP_CTRL_4_OUT = 24,
- MHI_CLIENT_IP_CTRL_4_IN = 25,
- MHI_CLIENT_IP_CTRL_5_OUT = 26,
- MHI_CLIENT_IP_CTRL_5_IN = 27,
- MHI_CLIENT_IP_CTRL_6_OUT = 28,
- MHI_CLIENT_IP_CTRL_6_IN = 29,
- MHI_CLIENT_IP_CTRL_7_OUT = 30,
- MHI_CLIENT_IP_CTRL_7_IN = 31,
- MHI_CLIENT_DUN_OUT = 32,
- MHI_CLIENT_DUN_IN = 33,
- MHI_CLIENT_IP_SW_0_OUT = 34,
- MHI_CLIENT_IP_SW_0_IN = 35,
- MHI_CLIENT_ADB_OUT = 36,
- MHI_CLIENT_ADB_IN = 37,
- MHI_CLIENT_IP_SW_2_OUT = 38,
- MHI_CLIENT_IP_SW_2_IN = 39,
- MHI_CLIENT_IP_SW_3_OUT = 40,
- MHI_CLIENT_IP_SW_3_IN = 41,
- MHI_CLIENT_CSVT_OUT = 42,
- MHI_CLIENT_CSVT_IN = 43,
- MHI_CLIENT_SMCT_OUT = 44,
- MHI_CLIENT_SMCT_IN = 45,
- MHI_CLIENT_IP_SW_4_OUT = 46,
- MHI_CLIENT_IP_SW_4_IN = 47,
- MHI_MAX_SOFTWARE_CHANNELS,
- MHI_CLIENT_TEST_OUT = 60,
- MHI_CLIENT_TEST_IN = 61,
- MHI_CLIENT_RESERVED_1_LOWER = 62,
- MHI_CLIENT_RESERVED_1_UPPER = 99,
- MHI_CLIENT_IP_HW_0_OUT = 100,
- MHI_CLIENT_IP_HW_0_IN = 101,
- MHI_CLIENT_RESERVED_2_LOWER = 102,
- MHI_CLIENT_RESERVED_2_UPPER = 127,
- MHI_MAX_CHANNELS = 102,
- MHI_CLIENT_INVALID = 0xFFFFFFFF
-};
-/* Use ID 0 for legacy /dev/mhi_ctrl. Channel 0 is used for internal only */
+/* Use ID 0 for legacy /dev/mhi_ctrl. Channel 0 used for internal only */
#define MHI_DEV_UEVENT_CTRL 0
struct mhi_dev_uevent_info {
@@ -736,58 +615,6 @@
uint32_t buf_size;
};
-struct mhi_dev_client_cb_data {
- void *user_data;
- enum mhi_client_channel channel;
- enum mhi_ctrl_info ctrl_info;
-};
-
-typedef void (*mhi_state_cb)(struct mhi_dev_client_cb_data *cb_dat);
-
-struct mhi_dev_ready_cb_info {
- struct list_head list;
- mhi_state_cb cb;
- struct mhi_dev_client_cb_data cb_data;
-};
-
-/**
- * mhi_dev_open_channel() - Channel open for a given client done prior
- * to read/write.
- * @chan_id: Software Channel ID for the assigned client.
- * @handle_client: Structure device for client handle.
- * @notifier: Client issued callback notification.
- */
-int mhi_dev_open_channel(uint32_t chan_id,
- struct mhi_dev_client **handle_client,
- void (*event_trigger)(struct mhi_dev_client_cb_reason *cb));
-/**
- * mhi_dev_close_channel() - Channel close for a given client.
- */
-int mhi_dev_close_channel(struct mhi_dev_client *handle_client);
-
-/**
- * mhi_dev_read_channel() - Channel read for a given client
- * @mreq: mreq is the client argument which includes meta info
- * like write data location, buffer len, read offset, mode,
- * chain and client call back function which will be invoked
- * when data read is completed.
- */
-int mhi_dev_read_channel(struct mhi_req *mreq);
-
-/**
- * mhi_dev_write_channel() - Channel write for a given software client.
- * @wreq wreq is the client argument which includes meta info like
- * client handle, read data location, buffer length, mode,
- * and client call back function which will free the packet.
- * when data write is completed.
- */
-int mhi_dev_write_channel(struct mhi_req *wreq);
-
-/**
- * mhi_dev_channel_isempty() - Checks if there is any pending TRE's to process.
- * @handle_client: Client Handle issued during mhi_dev_open_channel
- */
-int mhi_dev_channel_isempty(struct mhi_dev_client *handle);
struct mhi_dev_trace {
unsigned int timestamp;
@@ -1065,7 +892,7 @@
int mhi_dev_mmio_enable_erdb_interrupts(struct mhi_dev *dev);
/**
- * mhi_dev_mmio_mask_erdb_interrupts() - Mask all Event doorbell
+ *mhi_dev_mmio_mask_erdb_interrupts() - Mask all Event doorbell
* interrupts.
* @dev: MHI device structure.
*/
@@ -1256,43 +1083,8 @@
*/
int mhi_dev_net_interface_init(void);
-/**
- * mhi_dev_net_exit() - Clean up and close MHI Network interface module.
- */
-void mhi_dev_net_exit(void);
-
-/**
- * mhi_dev_notify_a7_event() - Used by PCIe driver to notify A7 MHI device
- * interrupt after doorbell is received. Used by PCIe driver when MHI
- * A7 interrupts are routed to PCIe instead of MHI device.
- */
void mhi_dev_notify_a7_event(struct mhi_dev *mhi);
-/**
- * mhi_ctrl_state_info() - Provide MHI state info
- * @idx: Channel number idx. Look at channel_state_info and
- * pass the index for the corresponding channel.
- * @info: Return the control info.
- * MHI_STATE=CONFIGURED - MHI device is present but not ready
- * for data traffic.
- * MHI_STATE=CONNECTED - MHI device is ready for data transfer.
- * MHI_STATE=DISCONNECTED - MHI device has its pipes suspended.
- * exposes device nodes for the supported MHI software
- * channels.
- */
-int mhi_ctrl_state_info(uint32_t idx, uint32_t *info);
-
-/**
- * uci_ctrl_update() - Update UCI once TRE's are available for clients to
- * consume.
- */
void uci_ctrl_update(struct mhi_dev_client_cb_reason *reason);
-/**
- * mhi_register_state_cb() - Clients can register and receive callback after
- * MHI channel is connected or disconnected.
- */
-int mhi_register_state_cb(void (*mhi_state_cb)
- (struct mhi_dev_client_cb_data *cb_data), void *data,
- enum mhi_client_channel channel);
-#endif /* _MHI_H_ */
+#endif /* _MHI_H */
diff --git a/drivers/platform/msm/mhi_dev/mhi_sm.h b/drivers/platform/msm/mhi_dev/mhi_sm.h
index 01e127b..4b9307d 100644
--- a/drivers/platform/msm/mhi_dev/mhi_sm.h
+++ b/drivers/platform/msm/mhi_dev/mhi_sm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015,2017-2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015,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
diff --git a/drivers/regulator/qpnp-labibb-regulator.c b/drivers/regulator/qpnp-labibb-regulator.c
index 88c5697..d72af20 100644
--- a/drivers/regulator/qpnp-labibb-regulator.c
+++ b/drivers/regulator/qpnp-labibb-regulator.c
@@ -597,6 +597,7 @@
struct device *dev;
struct platform_device *pdev;
struct regmap *regmap;
+ struct class labibb_class;
struct pmic_revid_data *pmic_rev_id;
u16 lab_base;
u16 ibb_base;
@@ -624,6 +625,8 @@
bool notify_lab_vreg_ok_sts;
bool detect_lab_sc;
bool sc_detected;
+ /* Tracks the secure UI mode entry/exit */
+ bool secure_mode;
u32 swire_2nd_cmd_delay;
u32 swire_ibb_ps_enable_delay;
};
@@ -2463,6 +2466,9 @@
int rc;
struct qpnp_labibb *labibb = rdev_get_drvdata(rdev);
+ if (labibb->secure_mode)
+ return 0;
+
if (labibb->sc_detected) {
pr_info("Short circuit detected: disabled LAB/IBB rails\n");
return 0;
@@ -2500,6 +2506,9 @@
u8 val;
struct qpnp_labibb *labibb = rdev_get_drvdata(rdev);
+ if (labibb->secure_mode)
+ return 0;
+
if (labibb->lab_vreg.vreg_enabled && !labibb->swire_control) {
if (!labibb->standalone)
@@ -2693,7 +2702,7 @@
u8 val;
struct qpnp_labibb *labibb = rdev_get_drvdata(rdev);
- if (labibb->swire_control)
+ if (labibb->swire_control || labibb->secure_mode)
return 0;
if (min_uV < labibb->lab_vreg.min_volt) {
@@ -3072,6 +3081,8 @@
}
if (is_lab_vreg_ok_irq_available(labibb)) {
+ irq_set_status_flags(labibb->lab_vreg.lab_vreg_ok_irq,
+ IRQ_DISABLE_UNLAZY);
rc = devm_request_threaded_irq(labibb->dev,
labibb->lab_vreg.lab_vreg_ok_irq, NULL,
lab_vreg_ok_handler,
@@ -3085,6 +3096,8 @@
}
if (labibb->lab_vreg.lab_sc_irq != -EINVAL) {
+ irq_set_status_flags(labibb->lab_vreg.lab_sc_irq,
+ IRQ_DISABLE_UNLAZY);
rc = devm_request_threaded_irq(labibb->dev,
labibb->lab_vreg.lab_sc_irq, NULL,
labibb_sc_err_handler,
@@ -3568,6 +3581,9 @@
int rc = 0;
struct qpnp_labibb *labibb = rdev_get_drvdata(rdev);
+ if (labibb->secure_mode)
+ return 0;
+
if (labibb->sc_detected) {
pr_info("Short circuit detected: disabled LAB/IBB rails\n");
return 0;
@@ -3593,6 +3609,9 @@
int rc;
struct qpnp_labibb *labibb = rdev_get_drvdata(rdev);
+ if (labibb->secure_mode)
+ return 0;
+
if (labibb->ibb_vreg.vreg_enabled && !labibb->swire_control) {
if (!labibb->standalone)
@@ -3626,7 +3645,7 @@
struct qpnp_labibb *labibb = rdev_get_drvdata(rdev);
- if (labibb->swire_control)
+ if (labibb->swire_control || labibb->secure_mode)
return 0;
rc = labibb->ibb_ver_ops->set_voltage(labibb, min_uV, max_uV);
@@ -3855,6 +3874,8 @@
}
if (labibb->ibb_vreg.ibb_sc_irq != -EINVAL) {
+ irq_set_status_flags(labibb->ibb_vreg.ibb_sc_irq,
+ IRQ_DISABLE_UNLAZY);
rc = devm_request_threaded_irq(labibb->dev,
labibb->ibb_vreg.ibb_sc_irq, NULL,
labibb_sc_err_handler,
@@ -4016,6 +4037,49 @@
return rc;
}
+static ssize_t qpnp_labibb_irq_control(struct class *c,
+ struct class_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct qpnp_labibb *labibb = container_of(c, struct qpnp_labibb,
+ labibb_class);
+ int val, rc;
+
+ rc = kstrtouint(buf, 0, &val);
+ if (rc < 0)
+ return rc;
+
+ if (val != 0 && val != 1)
+ return count;
+
+ /* Disable irqs */
+ if (val == 1 && !labibb->secure_mode) {
+ if (labibb->lab_vreg.lab_vreg_ok_irq > 0)
+ disable_irq(labibb->lab_vreg.lab_vreg_ok_irq);
+ if (labibb->lab_vreg.lab_sc_irq > 0)
+ disable_irq(labibb->lab_vreg.lab_sc_irq);
+ if (labibb->ibb_vreg.ibb_sc_irq > 0)
+ disable_irq(labibb->ibb_vreg.ibb_sc_irq);
+ labibb->secure_mode = true;
+ } else if (val == 0 && labibb->secure_mode) {
+ if (labibb->lab_vreg.lab_vreg_ok_irq > 0)
+ enable_irq(labibb->lab_vreg.lab_vreg_ok_irq);
+ if (labibb->lab_vreg.lab_sc_irq > 0)
+ enable_irq(labibb->lab_vreg.lab_sc_irq);
+ if (labibb->ibb_vreg.ibb_sc_irq > 0)
+ enable_irq(labibb->ibb_vreg.ibb_sc_irq);
+ labibb->secure_mode = false;
+ }
+
+ return count;
+}
+
+static struct class_attribute labibb_attributes[] = {
+ [0] = __ATTR(secure_mode, 0664, NULL,
+ qpnp_labibb_irq_control),
+ __ATTR_NULL,
+};
+
static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
{
struct qpnp_labibb *labibb;
@@ -4208,6 +4272,17 @@
CLOCK_MONOTONIC, HRTIMER_MODE_REL);
labibb->sc_err_check_timer.function = labibb_check_sc_err_count;
dev_set_drvdata(&pdev->dev, labibb);
+
+ labibb->labibb_class.name = "lcd_bias";
+ labibb->labibb_class.owner = THIS_MODULE;
+ labibb->labibb_class.class_attrs = labibb_attributes;
+
+ rc = class_register(&labibb->labibb_class);
+ if (rc < 0) {
+ pr_err("Failed to register labibb class rc=%d\n", rc);
+ return rc;
+ }
+
pr_info("LAB/IBB registered successfully, lab_vreg enable=%d ibb_vreg enable=%d swire_control=%d\n",
labibb->lab_vreg.vreg_enabled,
labibb->ibb_vreg.vreg_enabled,
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 0963aa3..10ae7eb 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -256,6 +256,7 @@
#define DWC3_GUSB3PIPECTL_DISRXDETINP3 (1 << 28)
#define DWC3_GUSB3PIPECTL_UX_EXIT_PX (1 << 27)
#define DWC3_GUSB3PIPECTL_REQP1P2P3 (1 << 24)
+#define DWC3_GUSB3PIPECTL_DISRXDETU3 (1 << 22)
#define DWC3_GUSB3PIPECTL_DEP1P2P3(n) ((n) << 19)
#define DWC3_GUSB3PIPECTL_DEP1P2P3_MASK DWC3_GUSB3PIPECTL_DEP1P2P3(7)
#define DWC3_GUSB3PIPECTL_DEP1P2P3_EN DWC3_GUSB3PIPECTL_DEP1P2P3(1)
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index f99b2bd..9bcfa38 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -2347,6 +2347,12 @@
/* Suspend SS PHY */
if (dwc->maximum_speed == USB_SPEED_SUPER) {
+ if (mdwc->in_host_mode) {
+ u32 reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
+
+ reg |= DWC3_GUSB3PIPECTL_DISRXDETU3;
+ dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
+ }
/* indicate phy about SS mode */
if (dwc3_msm_is_superspeed(mdwc))
mdwc->ss_phy->flags |= DEVICE_IN_SS_MODE;
@@ -2531,6 +2537,13 @@
usb_phy_set_suspend(mdwc->ss_phy, 0);
mdwc->ss_phy->flags &= ~DEVICE_IN_SS_MODE;
mdwc->lpm_flags &= ~MDWC3_SS_PHY_SUSPEND;
+
+ if (mdwc->in_host_mode) {
+ u32 reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
+
+ reg &= ~DWC3_GUSB3PIPECTL_DISRXDETU3;
+ dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
+ }
}
mdwc->hs_phy->flags &= ~(PHY_HSFS_MODE | PHY_LS_MODE);
diff --git a/drivers/usb/phy/phy-msm-qusb-v2.c b/drivers/usb/phy/phy-msm-qusb-v2.c
index 6dfca9c..a17974c 100644
--- a/drivers/usb/phy/phy-msm-qusb-v2.c
+++ b/drivers/usb/phy/phy-msm-qusb-v2.c
@@ -76,6 +76,12 @@
/* PERIPH_SS_PHY_REFGEN_NORTH_BG_CTRL register bits */
#define BANDGAP_BYPASS BIT(0)
+/* DEBUG_CTRL2 register value to program VSTATUS MUX for PHY status */
+#define DEBUG_CTRL2_MUX_PLL_LOCK_STATUS 0x4
+
+/* STAT5 register bits */
+#define VSTATUS_PLL_LOCK_STATUS_MASK BIT(0)
+
enum qusb_phy_reg {
PORT_TUNE1,
PLL_COMMON_STATUS_ONE,
@@ -87,6 +93,8 @@
SQ_CTRL1,
SQ_CTRL2,
DEBUG_CTRL1,
+ DEBUG_CTRL2,
+ STAT5,
USB2_PHY_REG_MAX,
};
@@ -470,6 +478,18 @@
__func__);
}
+static bool qusb_phy_pll_locked(struct qusb_phy *qphy)
+{
+ u32 val;
+
+ writel_relaxed(DEBUG_CTRL2_MUX_PLL_LOCK_STATUS,
+ qphy->base + qphy->phy_reg[DEBUG_CTRL2]);
+
+ val = readl_relaxed(qphy->base + qphy->phy_reg[STAT5]);
+
+ return (val & VSTATUS_PLL_LOCK_STATUS_MASK);
+}
+
static void qusb_phy_host_init(struct usb_phy *phy)
{
u8 reg;
@@ -748,18 +768,12 @@
writel_relaxed(intr_mask,
qphy->base + qphy->phy_reg[INTR_CTRL]);
- /* hold core PLL into reset */
- writel_relaxed(CORE_PLL_EN_FROM_RESET |
- CORE_RESET | CORE_RESET_MUX,
- qphy->base +
- qphy->phy_reg[PLL_CORE_INPUT_OVERRIDE]);
-
if (linestate & (LINESTATE_DP | LINESTATE_DM)) {
/* enable phy auto-resume */
writel_relaxed(0x91,
qphy->base + qphy->phy_reg[TEST1]);
- /* flush the previous write before next write */
- wmb();
+ /* Delay recommended between TEST1 writes */
+ usleep_range(10, 20);
writel_relaxed(0x90,
qphy->base + qphy->phy_reg[TEST1]);
}
@@ -788,12 +802,26 @@
writel_relaxed(0x00,
qphy->base + qphy->phy_reg[INTR_CTRL]);
- /* bring core PLL out of reset */
- writel_relaxed(CORE_PLL_EN_FROM_RESET, qphy->base +
- qphy->phy_reg[PLL_CORE_INPUT_OVERRIDE]);
+ /* Reset PLL if needed */
+ if (!qusb_phy_pll_locked(qphy)) {
+ dev_dbg(phy->dev, "%s: reset PLL\n", __func__);
+ /* hold core PLL into reset */
+ writel_relaxed(CORE_PLL_EN_FROM_RESET |
+ CORE_RESET | CORE_RESET_MUX,
+ qphy->base +
+ qphy->phy_reg[PLL_CORE_INPUT_OVERRIDE]);
- /* Makes sure that above write goes through */
- wmb();
+ /* Wait for PLL to get reset */
+ usleep_range(10, 20);
+
+ /* bring core PLL out of reset */
+ writel_relaxed(CORE_PLL_EN_FROM_RESET,
+ qphy->base +
+ qphy->phy_reg[PLL_CORE_INPUT_OVERRIDE]);
+
+ /* Makes sure that above write goes through */
+ wmb();
+ }
} else { /* Cable connect case */
qusb_phy_enable_clocks(qphy, true);
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_debug.c b/drivers/video/fbdev/msm/mdss_mdp_debug.c
index bd4ee23..e7bd94a 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_debug.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_debug.c
@@ -1140,7 +1140,7 @@
struct mdss_mdp_pipe *pipe;
int i, cnt = 0;
- if (!mixer)
+ if (!mixer || !mfd)
return;
seq_printf(s, "\n%s Mixer #%d res=%dx%d roi[%d, %d, %d, %d] %s\n",
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
index 947a3fe..0ffe89c 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c
@@ -1677,6 +1677,11 @@
/* re-assign to have the correct order in the context */
ctx = (struct mdss_mdp_cmd_ctx *) ctl->intf_ctx[MASTER_CTX];
+ if (!sctl) {
+ pr_err("invalid sctl\n");
+ goto exit;
+ }
+
sctx = (struct mdss_mdp_cmd_ctx *) sctl->intf_ctx[MASTER_CTX];
if (!ctx || !sctx) {
pr_err("invalid %s %s\n",
@@ -1784,6 +1789,11 @@
/* re-assign to have the correct order in the context */
ctx = (struct mdss_mdp_cmd_ctx *) ctl->intf_ctx[MASTER_CTX];
+ if (!sctl) {
+ pr_err("invalid sctl\n");
+ goto exit;
+ }
+
sctx = (struct mdss_mdp_cmd_ctx *) sctl->intf_ctx[MASTER_CTX];
if (!ctx || !sctx) {
pr_err("%s ERROR invalid %s %s\n", __func__,
diff --git a/include/linux/msm_mhi_dev.h b/include/linux/msm_mhi_dev.h
new file mode 100644
index 0000000..b96591b
--- /dev/null
+++ b/include/linux/msm_mhi_dev.h
@@ -0,0 +1,259 @@
+/* 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSM_MHI_DEV_H
+#define __MSM_MHI_DEV_H
+
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+
+#define IPA_DMA_SYNC 1
+#define IPA_DMA_ASYNC 0
+
+enum cb_reason {
+ MHI_DEV_TRE_AVAILABLE = 0,
+ MHI_DEV_CTRL_UPDATE,
+};
+
+struct mhi_dev_client_cb_reason {
+ uint32_t ch_id;
+ enum cb_reason reason;
+};
+
+struct mhi_dev_client {
+ struct list_head list;
+ struct mhi_dev_channel *channel;
+ void (*event_trigger)(struct mhi_dev_client_cb_reason *cb);
+
+ /* mhi_dev calls are fully synchronous -- only one call may be
+ * active per client at a time for now.
+ */
+ struct mutex write_lock;
+ wait_queue_head_t wait;
+
+ /* trace logs */
+ spinlock_t tr_lock;
+ unsigned int tr_head;
+ unsigned int tr_tail;
+ struct mhi_dev_trace *tr_log;
+
+ /* client buffers */
+ struct mhi_dev_iov *iov;
+ uint32_t nr_iov;
+};
+
+enum mhi_ctrl_info {
+ MHI_STATE_CONFIGURED = 0,
+ MHI_STATE_CONNECTED = 1,
+ MHI_STATE_DISCONNECTED = 2,
+ MHI_STATE_INVAL,
+};
+
+struct mhi_req {
+ u32 chan;
+ u32 mode;
+ u32 chain;
+ void *buf;
+ dma_addr_t dma;
+ u32 snd_cmpl;
+ void *context;
+ size_t len;
+ size_t actual_len;
+ uint32_t rd_offset;
+ struct mhi_dev_client *client;
+ struct list_head list;
+ union mhi_dev_ring_element_type *el;
+ void (*client_cb)(void *req);
+};
+
+/* SW channel client list */
+enum mhi_client_channel {
+ MHI_CLIENT_LOOPBACK_OUT = 0,
+ MHI_CLIENT_LOOPBACK_IN = 1,
+ MHI_CLIENT_SAHARA_OUT = 2,
+ MHI_CLIENT_SAHARA_IN = 3,
+ MHI_CLIENT_DIAG_OUT = 4,
+ MHI_CLIENT_DIAG_IN = 5,
+ MHI_CLIENT_SSR_OUT = 6,
+ MHI_CLIENT_SSR_IN = 7,
+ MHI_CLIENT_QDSS_OUT = 8,
+ MHI_CLIENT_QDSS_IN = 9,
+ MHI_CLIENT_EFS_OUT = 10,
+ MHI_CLIENT_EFS_IN = 11,
+ MHI_CLIENT_MBIM_OUT = 12,
+ MHI_CLIENT_MBIM_IN = 13,
+ MHI_CLIENT_QMI_OUT = 14,
+ MHI_CLIENT_QMI_IN = 15,
+ MHI_CLIENT_IP_CTRL_0_OUT = 16,
+ MHI_CLIENT_IP_CTRL_0_IN = 17,
+ MHI_CLIENT_IP_CTRL_1_OUT = 18,
+ MHI_CLIENT_IP_CTRL_1_IN = 19,
+ MHI_CLIENT_DCI_OUT = 20,
+ MHI_CLIENT_DCI_IN = 21,
+ MHI_CLIENT_IP_CTRL_3_OUT = 22,
+ MHI_CLIENT_IP_CTRL_3_IN = 23,
+ MHI_CLIENT_IP_CTRL_4_OUT = 24,
+ MHI_CLIENT_IP_CTRL_4_IN = 25,
+ MHI_CLIENT_IP_CTRL_5_OUT = 26,
+ MHI_CLIENT_IP_CTRL_5_IN = 27,
+ MHI_CLIENT_IP_CTRL_6_OUT = 28,
+ MHI_CLIENT_IP_CTRL_6_IN = 29,
+ MHI_CLIENT_IP_CTRL_7_OUT = 30,
+ MHI_CLIENT_IP_CTRL_7_IN = 31,
+ MHI_CLIENT_DUN_OUT = 32,
+ MHI_CLIENT_DUN_IN = 33,
+ MHI_CLIENT_IP_SW_0_OUT = 34,
+ MHI_CLIENT_IP_SW_0_IN = 35,
+ MHI_CLIENT_ADB_OUT = 36,
+ MHI_CLIENT_ADB_IN = 37,
+ MHI_CLIENT_IP_SW_2_OUT = 38,
+ MHI_CLIENT_IP_SW_2_IN = 39,
+ MHI_CLIENT_IP_SW_3_OUT = 40,
+ MHI_CLIENT_IP_SW_3_IN = 41,
+ MHI_CLIENT_CSVT_OUT = 42,
+ MHI_CLIENT_CSVT_IN = 43,
+ MHI_CLIENT_SMCT_OUT = 44,
+ MHI_CLIENT_SMCT_IN = 45,
+ MHI_CLIENT_IP_SW_4_OUT = 46,
+ MHI_CLIENT_IP_SW_4_IN = 47,
+ MHI_MAX_SOFTWARE_CHANNELS,
+ MHI_CLIENT_TEST_OUT = 60,
+ MHI_CLIENT_TEST_IN = 61,
+ MHI_CLIENT_RESERVED_1_LOWER = 62,
+ MHI_CLIENT_RESERVED_1_UPPER = 99,
+ MHI_CLIENT_IP_HW_0_OUT = 100,
+ MHI_CLIENT_IP_HW_0_IN = 101,
+ MHI_CLIENT_RESERVED_2_LOWER = 102,
+ MHI_CLIENT_RESERVED_2_UPPER = 127,
+ MHI_MAX_CHANNELS = 102,
+ MHI_CLIENT_INVALID = 0xFFFFFFFF
+};
+
+struct mhi_dev_client_cb_data {
+ void *user_data;
+ enum mhi_client_channel channel;
+ enum mhi_ctrl_info ctrl_info;
+};
+
+typedef void (*mhi_state_cb)(struct mhi_dev_client_cb_data *cb_dat);
+
+struct mhi_dev_ready_cb_info {
+ struct list_head list;
+ mhi_state_cb cb;
+ struct mhi_dev_client_cb_data cb_data;
+};
+
+#if defined(CONFIG_MSM_MHI_DEV)
+/**
+ * mhi_dev_open_channel() - Channel open for a given client done prior
+ * to read/write.
+ * @chan_id: Software Channel ID for the assigned client.
+ * @handle_client: Structure device for client handle.
+ * @notifier: Client issued callback notification.
+ */
+int mhi_dev_open_channel(uint32_t chan_id,
+ struct mhi_dev_client **handle_client,
+ void (*event_trigger)(struct mhi_dev_client_cb_reason *cb));
+
+/**
+ * mhi_dev_close_channel() - Channel close for a given client.
+ */
+int mhi_dev_close_channel(struct mhi_dev_client *handle_client);
+
+/**
+ * mhi_dev_read_channel() - Channel read for a given client
+ * @mreq: mreq is the client argument which includes meta info
+ * like write data location, buffer len, read offset, mode,
+ * chain and client call back function which will be invoked
+ * when data read is completed.
+ */
+int mhi_dev_read_channel(struct mhi_req *mreq);
+
+/**
+ * mhi_dev_write_channel() - Channel write for a given software client.
+ * @wreq wreq is the client argument which includes meta info like
+ * client handle, read data location, buffer length, mode,
+ * and client call back function which will free the packet.
+ * when data write is completed.
+ */
+int mhi_dev_write_channel(struct mhi_req *wreq);
+
+/**
+ * mhi_dev_channel_isempty() - Checks if there is any pending TRE's to process.
+ * @handle_client: Client Handle issued during mhi_dev_open_channel
+ */
+int mhi_dev_channel_isempty(struct mhi_dev_client *handle);
+
+/**
+ * mhi_ctrl_state_info() - Provide MHI state info
+ * @idx: Channel number idx. Look at channel_state_info and
+ * pass the index for the corresponding channel.
+ * @info: Return the control info.
+ * MHI_STATE=CONFIGURED - MHI device is present but not ready
+ * for data traffic.
+ * MHI_STATE=CONNECTED - MHI device is ready for data transfer.
+ * MHI_STATE=DISCONNECTED - MHI device has its pipes suspended.
+ * exposes device nodes for the supported MHI software
+ * channels.
+ */
+int mhi_ctrl_state_info(uint32_t idx, uint32_t *info);
+
+/**
+ * mhi_register_state_cb() - Clients can register and receive callback after
+ * MHI channel is connected or disconnected.
+ */
+int mhi_register_state_cb(void (*mhi_state_cb)
+ (struct mhi_dev_client_cb_data *cb_data), void *data,
+ enum mhi_client_channel channel);
+
+#else
+static inline int mhi_dev_open_channel(uint32_t chan_id,
+ struct mhi_dev_client **handle_client,
+ void (*event_trigger)(struct mhi_dev_client_cb_reason *cb))
+{
+ return -EINVAL;
+};
+
+static inline int mhi_dev_close_channel(struct mhi_dev_client *handle_client)
+{
+ return -EINVAL;
+};
+
+static inline int mhi_dev_read_channel(struct mhi_req *mreq)
+{
+ return -EINVAL;
+};
+
+static inline int mhi_dev_write_channel(struct mhi_req *wreq)
+{
+ return -EINVAL;
+};
+
+static inline int mhi_dev_channel_isempty(struct mhi_dev_client *handle)
+{
+ return -EINVAL;
+};
+
+static inline int mhi_ctrl_state_info(uint32_t idx, uint32_t *info)
+{
+ return -EINVAL;
+};
+
+static inline int mhi_register_state_cb(void (*mhi_state_cb)
+ (struct mhi_dev_client_cb_data *cb_data), void *data,
+ enum mhi_client_channel channel)
+{
+ return -EINVAL;
+};
+#endif
+
+#endif /* _MSM_MHI_DEV_H*/
diff --git a/mm/cma.c b/mm/cma.c
index e97ad01..1ccfaa1 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -466,7 +466,8 @@
bitmap_maxno, start, bitmap_count, mask,
offset);
if (bitmap_no >= bitmap_maxno) {
- if (retry_after_sleep < max_retries) {
+ if ((retry_after_sleep < max_retries) &&
+ (ret == -EBUSY)) {
start = 0;
/*
* update max retries if available free regions