Merge "mdss: Add MDP_SMP_FORCE_ALLOC mdp flag"
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
index bbc9f08..541b50a 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_thermal.txt
@@ -100,6 +100,12 @@
- qcom,efuse-temperature-map: Truth table of efuse value temperature value pair for
different parts. if qcom,default temp is defined, then it can
specify only pairs which deviate from default temperature.
+- qcom,therm-reset-temp: Degree above which the KTM will initiate a secure watchdog reset.
+ When this property is defined, KTM will monitor all the tsens from
+ boot time and will initiate a secure watchdog reset if any of the
+ tsens temperature reaches this threshold. This reset helps in
+ generating more informative crash dumps opposed to the crash dump
+ generated by the hardware reset.
Optional child nodes
- qti,pmic-opt-curr-temp: Threshold temperature for requesting optimum current (request
@@ -139,6 +145,7 @@
qcom,temp-hysteresis = <10>;
qcom,freq-step = <2>;
qcom,freq-control-mask = <0xf>
+ qcom,therm-reset-temp = <115>;
qcom,core-limit-temp = <90>;
qcom,core-temp-hysteresis = <10>;
qcom,core-control-mask = <7>;
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 495117f..f8c9b46 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -1987,6 +1987,7 @@
gpios = <&msmgpio 36 0>, <&msmgpio 37 0>, <&msmgpio 38 0>, <&msmgpio 39 0>, <&msmgpio 40 0>;
qcom,has-48mhz-xo;
qcom,has-pronto-hw;
+ qcom,wcnss-pm = <11 21 1200 1 1>;
};
qcom,ocmem@fdd00000 {
@@ -2263,6 +2264,7 @@
qcom,poll-ms = <250>;
qcom,limit-temp = <60>;
qcom,temp-hysteresis = <10>;
+ qcom,therm-reset-temp = <115>;
qcom,freq-step = <2>;
qcom,freq-control-mask = <0xf>;
qcom,core-limit-temp = <80>;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index 2567657..5227731 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -659,9 +659,9 @@
*cfg_data);
pr_err("hw update across frame boundary,end id %lu\n",
vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id);
- vfe_dev->axi_data.src_info[VFE_PIX_0].last_updt_frm_id =
- vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
}
+ vfe_dev->axi_data.src_info[VFE_PIX_0].last_updt_frm_id =
+ vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id;
break;
}
case VFE_READ: {
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index f5587fc..0de42ae 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -1501,6 +1501,7 @@
void *pkt)
{
u32 rx_req_is_set = 0;
+ struct vidc_hal_cmd_pkt_hdr *cmd_packet;
struct vidc_iface_q_info *q_info;
int result = -EPERM;
@@ -1528,6 +1529,12 @@
goto err_q_null;
}
+ cmd_packet = (struct vidc_hal_cmd_pkt_hdr *)pkt;
+ if ((cmd_packet->packet_type != HFI_CMD_SYS_PC_PREP) &&
+ (cmd_packet->packet_type != HFI_CMD_SYS_RELEASE_RESOURCE)) {
+ device->pc_num_cmds++;
+ }
+
if (!venus_hfi_write_queue(q_info, (u8 *)pkt, &rx_req_is_set)) {
WARN(!mutex_is_locked(&device->clk_pwr_lock),
"Clock/power lock must be acquired");
@@ -2865,15 +2872,24 @@
static void venus_hfi_pm_hndlr(struct work_struct *work)
{
int rc = 0;
+ u32 ctrl_status = 0;
struct venus_hfi_device *device = list_first_entry(
&hal_ctxt.dev_head, struct venus_hfi_device, list);
+
+ if (!device) {
+ dprintk(VIDC_ERR, "%s: NULL device\n", __func__);
+ return;
+ }
+
mutex_lock(&device->clk_pwr_lock);
if (device->clk_state == ENABLED_PREPARED || !device->power_enabled) {
dprintk(VIDC_DBG,
"Clocks status: %d, Power status: %d, ignore power off\n",
device->clk_state, device->power_enabled);
- goto clks_enabled;
+ mutex_unlock(&device->clk_pwr_lock);
+ return;
}
+ device->pc_num_cmds = 0;
mutex_unlock(&device->clk_pwr_lock);
rc = __unset_free_ocmem(device);
@@ -2894,17 +2910,51 @@
}
mutex_lock(&device->clk_pwr_lock);
+ if (device->pc_num_cmds) {
+ dprintk(VIDC_DBG,
+ "ignore power off due to client sent commands = %d\n",
+ device->pc_num_cmds);
+ goto skip_power_off;
+ }
if (device->clk_state == ENABLED_PREPARED) {
dprintk(VIDC_ERR,
"Clocks are still enabled after PC_PREP_DONE, ignore power off");
- goto clks_enabled;
+ goto skip_power_off;
}
rc = venus_hfi_power_off(device);
- if (rc)
+ if (rc) {
dprintk(VIDC_ERR, "Failed venus power off");
-clks_enabled:
+ goto err_power_off;
+ }
+
mutex_unlock(&device->clk_pwr_lock);
+ return;
+
+err_power_off:
+skip_power_off:
+
+ /* Reset PC_READY bit as power_off is skipped, if set by Venus */
+ ctrl_status = venus_hfi_read_register(device, VIDC_CPU_CS_SCIACMDARG0);
+ if (ctrl_status & VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY) {
+ ctrl_status &= ~(VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY);
+ venus_hfi_write_register(device, VIDC_CPU_CS_SCIACMDARG0,
+ ctrl_status, 0);
+ }
+
+ /* Cancel pending delayed works if any */
+ cancel_delayed_work(&venus_hfi_pm_work);
+ dprintk(VIDC_WARN, "Power off skipped (%d, %d)\n",
+ device->clk_state, device->pc_num_cmds);
+
+ mutex_unlock(&device->clk_pwr_lock);
+
+ rc = __alloc_set_ocmem(device, true);
+ if (rc) {
+ dprintk(VIDC_WARN,
+ "Failed to re-allocate OCMEM. Performance will be impacted\n");
+ }
+ return;
}
static int venus_hfi_try_clk_gating(struct venus_hfi_device *device)
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.h b/drivers/media/platform/msm/vidc/venus_hfi.h
index 05d7b6a..a1ed069 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.h
+++ b/drivers/media/platform/msm/vidc/venus_hfi.h
@@ -215,6 +215,7 @@
struct workqueue_struct *venus_pm_workq;
int spur_count;
int reg_count;
+ int pc_num_cmds;
u32 base_addr;
u32 register_base;
u32 register_size;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index b3c20b6..edd71f1 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -780,6 +780,11 @@
#define HFI_TEST_SSR_SW_DIV_BY_ZERO 0x2
#define HFI_TEST_SSR_HW_WDOG_IRQ 0x3
+struct vidc_hal_cmd_pkt_hdr {
+ u32 size;
+ u32 packet_type;
+};
+
struct vidc_hal_msg_pkt_hdr {
u32 size;
u32 packet;
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 3a93469..b091acd 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -1525,6 +1525,30 @@
return ret;
}
+int boundary_checks_offset(struct qseecom_send_modfd_cmd_req *cmd_req,
+ struct qseecom_send_modfd_listener_resp *lstnr_resp,
+ struct qseecom_dev_handle *data, bool listener_svc,
+ int i) {
+ int ret = 0;
+
+ if ((!listener_svc) && (cmd_req->ifd_data[i].fd > 0)) {
+ if (cmd_req->ifd_data[i].cmd_buf_offset >
+ cmd_req->cmd_req_len - sizeof(uint32_t)) {
+ pr_err("Invalid offset 0x%x\n",
+ cmd_req->ifd_data[i].cmd_buf_offset);
+ return ++ret;
+ }
+ } else if ((listener_svc) && (lstnr_resp->ifd_data[i].fd > 0)) {
+ if (lstnr_resp->ifd_data[i].cmd_buf_offset >
+ lstnr_resp->resp_len - sizeof(uint32_t)) {
+ pr_err("Invalid offset 0x%x\n",
+ lstnr_resp->ifd_data[i].cmd_buf_offset);
+ return ++ret;
+ }
+ }
+ return ret;
+}
+
static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
struct qseecom_dev_handle *data,
bool listener_svc)
@@ -1598,6 +1622,10 @@
if (sg_ptr->nents == 1) {
uint32_t *update;
update = (uint32_t *) field;
+
+ if (boundary_checks_offset(cmd_req, lstnr_resp, data,
+ listener_svc, i))
+ goto err;
if (cleanup)
*update = 0;
else
@@ -1607,6 +1635,27 @@
} else {
struct qseecom_sg_entry *update;
int j = 0;
+
+ if ((!listener_svc) && (cmd_req->ifd_data[i].fd > 0)) {
+ if (cmd_req->ifd_data[i].cmd_buf_offset >
+ cmd_req->cmd_req_len -
+ sizeof(struct qseecom_sg_entry)) {
+ pr_err("Invalid offset = 0x%x\n",
+ cmd_req->ifd_data[i].
+ cmd_buf_offset);
+ goto err;
+ }
+ } else if ((listener_svc) &&
+ (lstnr_resp->ifd_data[i].fd > 0)) {
+ if (lstnr_resp->ifd_data[i].cmd_buf_offset >
+ lstnr_resp->resp_len -
+ sizeof(struct qseecom_sg_entry)) {
+ pr_err("Invalid offset = 0x%x\n",
+ lstnr_resp->ifd_data[i].
+ cmd_buf_offset);
+ goto err;
+ }
+ }
update = (struct qseecom_sg_entry *) field;
for (j = 0; j < sg_ptr->nents; j++) {
if (cleanup) {
diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c
index 85e8842..299d3ee 100644
--- a/drivers/slimbus/slim-msm-ngd.c
+++ b/drivers/slimbus/slim-msm-ngd.c
@@ -1154,6 +1154,14 @@
struct slim_device *sbdev;
struct list_head *pos, *next;
int ret, i = 0;
+ ret = qmi_svc_event_notifier_register(SLIMBUS_QMI_SVC_ID,
+ SLIMBUS_QMI_SVC_V1,
+ SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
+ if (ret) {
+ pr_err("Slimbus QMI service registration failed:%d", ret);
+ return ret;
+ }
+
while (!kthread_should_stop()) {
set_current_state(TASK_INTERRUPTIBLE);
wait_for_completion(&dev->qmi.slave_notify);
@@ -1426,14 +1434,6 @@
INIT_WORK(&dev->qmi.ssr_up, ngd_adsp_up);
dev->qmi.nb.notifier_call = ngd_qmi_available;
pm_runtime_get_noresume(dev->dev);
- ret = qmi_svc_event_notifier_register(SLIMBUS_QMI_SVC_ID,
- SLIMBUS_QMI_SVC_V1,
- SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
- if (ret) {
- pr_err("Slimbus QMI service registration failed:%d", ret);
- goto qmi_register_failed;
- }
-
/* Fire up the Rx message queue thread */
dev->rx_msgq_thread = kthread_run(ngd_slim_rx_msgq_thread, dev,
@@ -1458,10 +1458,6 @@
err_notify_thread_create_failed:
kthread_stop(dev->rx_msgq_thread);
err_rx_thread_create_failed:
- qmi_svc_event_notifier_unregister(SLIMBUS_QMI_SVC_ID,
- SLIMBUS_QMI_SVC_V1,
- SLIMBUS_QMI_INS_ID, &dev->qmi.nb);
-qmi_register_failed:
free_irq(dev->irq, dev);
err_request_irq_failed:
slim_del_controller(&dev->ctrl);
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index e5eb9b2..f2fb09d 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -39,6 +39,8 @@
#include <mach/rpm-regulator-smd.h>
#include <linux/regulator/consumer.h>
#include <linux/msm_thermal_ioctl.h>
+#include <mach/rpm-smd.h>
+#include <mach/scm.h>
#define MAX_CURRENT_UA 1000000
#define MAX_RAILS 5
@@ -46,6 +48,7 @@
#define MONITOR_ALL_TSENS -1
#define BYTES_PER_FUSE_ROW 8
#define MAX_EFUSE_VALUE 16
+#define THERM_SECURE_BITE_CMD 8
static struct msm_thermal_data msm_thermal_info;
static struct delayed_work check_temp_work;
@@ -89,6 +92,7 @@
static bool ocr_probed;
static bool interrupt_mode_enable;
static bool msm_thermal_probed;
+static bool therm_reset_enabled;
static int *tsens_id_map;
static DEFINE_MUTEX(vdd_rstr_mutex);
static DEFINE_MUTEX(psm_mutex);
@@ -169,6 +173,7 @@
};
enum msm_thresh_list {
+ MSM_THERM_RESET,
MSM_VDD_RESTRICTION,
MSM_LIST_MAX_NR,
};
@@ -929,6 +934,73 @@
return ret;
}
+static void msm_thermal_bite(int tsens_id, long temp)
+{
+ pr_err("TSENS:%d reached temperature:%ld. System reset\n",
+ tsens_id, temp);
+ scm_call_atomic1(SCM_SVC_BOOT, THERM_SECURE_BITE_CMD, 0);
+}
+
+static int do_therm_reset(void)
+{
+ int ret = 0, i;
+ long temp = 0;
+
+ if (!therm_reset_enabled)
+ return ret;
+
+ for (i = 0; i < thresh[MSM_THERM_RESET].thresh_ct; i++) {
+ ret = therm_get_temp(
+ thresh[MSM_THERM_RESET].thresh_list[i].sensor_id,
+ THERM_TSENS_ID,
+ &temp);
+ if (ret) {
+ pr_err("Unable to read TSENS sensor:%d. err:%d\n",
+ thresh[MSM_THERM_RESET].thresh_list[i].sensor_id,
+ ret);
+ continue;
+ }
+
+ if (temp >= msm_thermal_info.therm_reset_temp_degC)
+ msm_thermal_bite(
+ thresh[MSM_THERM_RESET].thresh_list[i].sensor_id, temp);
+ }
+
+ return ret;
+}
+
+static void therm_reset_notify(struct therm_threshold *thresh_data)
+{
+ long temp;
+ int ret = 0;
+
+ if (!therm_reset_enabled)
+ return;
+
+ if (!thresh_data) {
+ pr_err("Invalid input\n");
+ return;
+ }
+
+ switch (thresh_data->trip_triggered) {
+ case THERMAL_TRIP_CONFIGURABLE_HI:
+ ret = therm_get_temp(thresh_data->sensor_id,
+ THERM_TSENS_ID, &temp);
+ if (ret)
+ pr_err("Unable to read TSENS sensor:%d. err:%d\n",
+ thresh_data->sensor_id, ret);
+ msm_thermal_bite(tsens_id_map[thresh_data->sensor_id],
+ temp);
+ break;
+ case THERMAL_TRIP_CONFIGURABLE_LOW:
+ break;
+ default:
+ pr_err("Invalid trip type\n");
+ break;
+ }
+ set_threshold(thresh_data->sensor_id, thresh_data->threshold);
+}
+
#ifdef CONFIG_SMP
static void __ref do_core_control(long temp)
{
@@ -1266,6 +1338,8 @@
long temp = 0;
int ret = 0;
+ do_therm_reset();
+
ret = therm_get_temp(msm_thermal_info.sensor_id, THERM_TSENS_ID, &temp);
if (ret) {
pr_err("Unable to read TSENS sensor:%d. err:%d\n",
@@ -1740,6 +1814,9 @@
goto init_exit;
}
+ if (therm_reset_enabled)
+ therm_set_threshold(&thresh[MSM_THERM_RESET]);
+
if (vdd_rstr_enabled)
therm_set_threshold(&thresh[MSM_VDD_RESTRICTION]);
@@ -3047,6 +3124,38 @@
return ret;
}
+static int probe_therm_reset(struct device_node *node,
+ struct msm_thermal_data *data,
+ struct platform_device *pdev)
+{
+ char *key = NULL;
+ int ret = 0;
+
+ key = "qcom,therm-reset-temp";
+ ret = of_property_read_u32(node, key, &data->therm_reset_temp_degC);
+ if (ret)
+ goto PROBE_RESET_EXIT;
+
+ ret = init_threshold(MSM_THERM_RESET, MONITOR_ALL_TSENS,
+ data->therm_reset_temp_degC, data->therm_reset_temp_degC - 10,
+ therm_reset_notify);
+ if (ret) {
+ pr_err("Therm reset data structure init failed\n");
+ goto PROBE_RESET_EXIT;
+ }
+
+ therm_reset_enabled = true;
+
+PROBE_RESET_EXIT:
+ if (ret) {
+ dev_info(&pdev->dev,
+ "%s:Failed reading node=%s, key=%s err=%d. KTM continues\n",
+ __func__, node->full_name, key, ret);
+ therm_reset_enabled = false;
+ }
+ return ret;
+}
+
static int probe_freq_mitigation(struct device_node *node,
struct msm_thermal_data *data,
struct platform_device *pdev)
@@ -3132,6 +3241,8 @@
ret = probe_cc(node, &data, pdev);
ret = probe_freq_mitigation(node, &data, pdev);
+ ret = probe_therm_reset(node, &data, pdev);
+
/*
* Probe optional properties below. Call probe_psm before
* probe_vdd_rstr because rpm_regulator_get has to be called
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index f7d02b2..e6c17aa 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -711,12 +711,11 @@
right_plist, (right_plist ? MDSS_MDP_MAX_STAGE : 0));
if (ctl->is_video_mode) {
- if (perf->bw_overlap > perf->bw_prefill)
- perf->bw_ctl = apply_fudge_factor(perf->bw_ctl,
- &mdss_res->ib_factor_overlap);
- else
- perf->bw_ctl = apply_fudge_factor(perf->bw_ctl,
- &mdss_res->ib_factor);
+ perf->bw_ctl =
+ max(apply_fudge_factor(perf->bw_overlap,
+ &mdss_res->ib_factor_overlap),
+ apply_fudge_factor(perf->bw_prefill,
+ &mdss_res->ib_factor));
}
pr_debug("ctl=%d clk_rate=%u\n", ctl->num, perf->mdp_clk_rate);
pr_debug("bw_overlap=%llu bw_prefill=%llu prefill_bytes=%d\n",
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index cff668d..e5965e6 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -1747,11 +1747,6 @@
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
- ret = mdss_iommu_ctrl(1);
- if (IS_ERR_VALUE(ret)) {
- pr_err("IOMMU attach failed\n");
- goto pan_display_error;
- }
bpp = fbi->var.bits_per_pixel / 8;
offset = fbi->var.xoffset * bpp +
@@ -1769,6 +1764,12 @@
goto pan_display_error;
}
+ ret = mdss_iommu_ctrl(1);
+ if (IS_ERR_VALUE(ret)) {
+ pr_err("IOMMU attach failed\n");
+ goto pan_display_error;
+ }
+
ret = mdss_mdp_overlay_get_fb_pipe(mfd, &pipe,
MDSS_MDP_MIXER_MUX_LEFT);
if (ret) {
diff --git a/include/linux/msm_thermal.h b/include/linux/msm_thermal.h
index 25b5363..2e3270d 100644
--- a/include/linux/msm_thermal.h
+++ b/include/linux/msm_thermal.h
@@ -36,6 +36,7 @@
int32_t psm_temp_hyst_degC;
int32_t ocr_temp_degC;
int32_t ocr_temp_hyst_degC;
+ int32_t therm_reset_temp_degC;
};
#ifdef CONFIG_THERMAL_MONITOR
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 1addd9f..efb0138 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -1348,7 +1348,7 @@
int err;
if (level != SOL_PPPOL2TP)
- return udp_prot.setsockopt(sk, level, optname, optval, optlen);
+ return -EINVAL;
if (optlen < sizeof(int))
return -EINVAL;
@@ -1474,7 +1474,7 @@
struct pppol2tp_session *ps;
if (level != SOL_PPPOL2TP)
- return udp_prot.getsockopt(sk, level, optname, optval, optlen);
+ return -EINVAL;
if (get_user(len, (int __user *) optlen))
return -EFAULT;
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index eb535cc..a3a7134 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -758,9 +758,10 @@
struct net *net = nf_ct_net(ct);
nf_ct_ext_destroy(ct);
- atomic_dec(&net->ct.count);
nf_ct_ext_free(ct);
kmem_cache_free(net->ct.nf_conntrack_cachep, ct);
+ smp_mb__before_atomic_dec();
+ atomic_dec(&net->ct.count);
}
EXPORT_SYMBOL_GPL(nf_conntrack_free);
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index a7a5d1e..a664b75 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -1488,6 +1488,7 @@
case SLIMBUS_2_RX: return IDX_SLIMBUS_2_RX;
case SLIMBUS_2_TX: return IDX_SLIMBUS_2_TX;
case SLIMBUS_3_RX: return IDX_SLIMBUS_3_RX;
+ case SLIMBUS_3_TX: return IDX_SLIMBUS_3_TX;
case INT_BT_SCO_RX: return IDX_INT_BT_SCO_RX;
case INT_BT_SCO_TX: return IDX_INT_BT_SCO_TX;
case INT_BT_A2DP_RX: return IDX_INT_BT_A2DP_RX;