Merge "ASoC: msm: qdsp6v2: fix slow_talk not disabled issue"
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
index f8c4879..c2b963f 100644
--- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
@@ -243,6 +243,12 @@
applied in scenarios where panel interface can
be more tolerant to memory latency such as
command mode panels.
+- qcom,mdss-rotator-ot-limit: This integer value indicates maximum number of pending
+ writes that can be allowed from rotator client. Default
+ value is 16 which is the maximum. This value can be
+ used to reduce the pending writes limit dynamically
+ and can be tuned to match performance requirements
+ depending upon system state.
Fudge Factors: Fudge factors are used to boost demand for
resources like bus bandswidth, clk rate etc. to
@@ -351,6 +357,7 @@
qcom,mdss-smp-data = <22 4096>;
qcom,mdss-rot-block-size = <64>;
+ qcom,mdss-rotator-ot-limit = <2>;
qcom,mdss-smp-mb-per-pipe = <2>;
qcom,mdss-pref-prim-intf = "dsi";
qcom,mdss-has-bwc;
diff --git a/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt b/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
index f2ca95b..d0c2b7d 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
@@ -29,7 +29,7 @@
It is a four tuple consisting of min x,
min y, max x and max y values.
- goodix,i2c-pull-up : To specify pull up is required.
- - goodix,no-force-update : To specify force update is allowed.
+ - goodix,force-update : To specify force update is allowed.
- goodix,enable-power-off : Power off touchscreen during suspend.
- goodix,button-map : Button map of key codes. The number of key codes
depend on panel.
diff --git a/Documentation/devicetree/bindings/nfc/nfc-nci.txt b/Documentation/devicetree/bindings/nfc/nfc-nci.txt
index dca7d5c..2c06599 100644
--- a/Documentation/devicetree/bindings/nfc/nfc-nci.txt
+++ b/Documentation/devicetree/bindings/nfc/nfc-nci.txt
@@ -8,13 +8,15 @@
- reg: NCI i2c slave address.
- qcom,dis-gpio: specific gpio for hardware reset.
- qcom,irq-gpio: specific gpio for read interrupt.
-- qcom,clk-src: nfc clock source ("BBCLK2", "RFCLK3", "GPCLK","GPCLK2" ...)
-- qcom,clk-en-gpio: msm gpio clock,used ony if clock source is msm gpio
+- qcom,clk-src: nfc clock source ("BBCLK2", "RFCLK3", "GPCLK", "GPCLK2", ...)
+- qcom,clk-src-gpio: msm gpio clock,used ony if clock source is msm gpio
+- qcom,clk-req-gpio: clk-req input gpio for MSM based clocks.
+ not used for pmic implementation
- vlogic-supply: LDO for power supply
- interrupt-parent: Should be phandle for the interrupt controller
that services interrupts for this device.
-- interrupts: should contain the NFC interrupt. NFC has one read interrupt.
-- qcom,clk-gpio: pmic gpio on which bbclk2 signal is coming.
+- interrupts: Nfc read interrupt,gpio-clk-req interrupt
+- qcom,clk-gpio: pmic or msm gpio on which bbclk2 signal is coming.
LDO example:
@@ -24,8 +26,8 @@
reg = <0x0e>;
qcom,irq-gpio = <&msmgpio 77 0x00>;
qcom,dis-gpio = <&msmgpio 93 0x00>;
- qcom,clk-en-gpio = <&msmgpio 78 0x00>;
- qcom,clk-src = "GPCLK";
+ qcom,clk-src-gpio = <&msmgpio 78 0x00>;
+ qcom,clk-src = "GPCLK2";
interrupt-parent = <&msmgpio>;
interrupts = <77 0>;
qcom,clk-gpio = <&msmgpio 75 0x00>;
diff --git a/arch/arm/boot/dts/msm8226-mdss.dtsi b/arch/arm/boot/dts/msm8226-mdss.dtsi
index 40576c9..8a98d5c 100644
--- a/arch/arm/boot/dts/msm8226-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8226-mdss.dtsi
@@ -58,6 +58,7 @@
qcom,mdss-wb-off = <0x00011100 0x00013100>;
qcom,mdss-intf-off = <0x00000000 0x00021300>;
qcom,mdss-rot-block-size = <64>;
+ qcom,mdss-rotator-ot-limit = <2>;
qcom,mdss-smp-mb-per-pipe = <4>;
vdd-cx-supply = <&pm8226_s1_corner>;
diff --git a/arch/arm/boot/dts/msm8610-mtp.dtsi b/arch/arm/boot/dts/msm8610-mtp.dtsi
index 7f48db0..aad838e 100644
--- a/arch/arm/boot/dts/msm8610-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8610-mtp.dtsi
@@ -151,10 +151,11 @@
reg = <0x0e>;
qcom,irq-gpio = <&msmgpio 77 0x00>;
qcom,dis-gpio = <&msmgpio 93 0x00>;
- qcom,clk-en-gpio = <&msmgpio 78 0x00>;
+ qcom,clk-req-gpio = <&msmgpio 75 0x00>;
+ qcom,clk-src-gpio = <&msmgpio 78 0x00>;
qcom,clk-src = "GPCLK";
interrupt-parent = <&msmgpio>;
- interrupts = <77 0>;
+ interrupts = <77 75 0>;
qcom,clk-gpio = <&pm8110_gpios 1 0>;
};
};
diff --git a/arch/arm/boot/dts/msm8610-qrd-skuaa.dtsi b/arch/arm/boot/dts/msm8610-qrd-skuaa.dtsi
index 719830e..53abb95 100644
--- a/arch/arm/boot/dts/msm8610-qrd-skuaa.dtsi
+++ b/arch/arm/boot/dts/msm8610-qrd-skuaa.dtsi
@@ -38,11 +38,12 @@
compatible = "qcom,nfc-nci";
reg = <0x0e>;
qcom,irq-gpio = <&msmgpio 77 0x00>;
+ qcom,clk-req-gpio = <&msmgpio 75 0x00>;
qcom,dis-gpio = <&msmgpio 93 0x00>;
- qcom,clk-en-gpio = <&msmgpio 78 0x00>;
+ qcom,clk-src-gpio = <&msmgpio 78 0x00>;
qcom,clk-src = "GPCLK2";
interrupt-parent = <&msmgpio>;
- interrupts = <77 0>;
+ interrupts = <77 75 0>;
qcom,clk-gpio = <&msmgpio 75 0x00>;
};
};
diff --git a/arch/arm/boot/dts/msm8926-v2.dtsi b/arch/arm/boot/dts/msm8926-v2.dtsi
index 55f4608..db8e02f 100644
--- a/arch/arm/boot/dts/msm8926-v2.dtsi
+++ b/arch/arm/boot/dts/msm8926-v2.dtsi
@@ -65,3 +65,7 @@
};
};
};
+
+&apc_vreg_corner {
+ /delete-property/ qcom,cpr-enable;
+};
diff --git a/arch/arm/boot/dts/msm8926.dtsi b/arch/arm/boot/dts/msm8926.dtsi
index a05d232..2bb202f 100644
--- a/arch/arm/boot/dts/msm8926.dtsi
+++ b/arch/arm/boot/dts/msm8926.dtsi
@@ -180,9 +180,9 @@
qcom,pvs-corner-ceiling-fast = <1050000 1050000 1100000>;
qcom,cpr-step-quotient = <30>;
qcom,cpr-up-threshold = <0>;
- qcom,cpr-down-threshold = <1>;
+ qcom,cpr-down-threshold = <2>;
qcom,cpr-apc-volt-step = <10000>;
- qcom,cpr-quotient-adjustment = <0 96 96>;
+ qcom,cpr-quotient-adjustment = <0 72 72>;
vdd-apc-optional-prim-supply = <&ncp6335d>;
vdd-apc-optional-sec-supply = <&fan53555>;
};
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index d0ca01d..f4b4d4a 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -133,6 +133,20 @@
};
};
+ i2c@f9928000 { /* BLSP1 QUP6 */
+ nfc-nci@e {
+ compatible = "qcom,nfc-nci";
+ reg = <0x0e>;
+ qcom,irq-gpio = <&msmgpio 59 0x00>;
+ qcom,dis-gpio = <&msmgpio 13 0x00>;
+ qcom,clk-src = "BBCLK2";
+ qcom,clk-en-gpio = <&msmgpio 0 0x00>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <59 0>;
+ qcom,clk-gpio = <&pm8941_gpios 32 0>;
+ };
+ };
+
i2c@f9967000 {
sii8334@72 {
compatible = "qcom,mhl-sii8334";
@@ -606,6 +620,11 @@
};
gpio@df00 { /* GPIO 32 */
+ qcom,mode = <0>; /* QPNP_PIN_MODE_DIG_IN */
+ qcom,pull = <5>; /* QPNP_PIN_PULL_NO */
+ qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */
+ qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */
+ qcom,master-en = <1>;
};
gpio@e000 { /* GPIO 33 */
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index f4aa25b..030a1f3 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -2347,6 +2347,22 @@
compatible = "qcom,bcl";
};
+ i2c@f9928000 { /* BLSP-1 QUP-6 */
+ cell-index = <3>;
+ compatible = "qcom,i2c-qup";
+ reg = <0xf9928000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "qup_phys_addr";
+ interrupts = <0 100 0>;
+ interrupt-names = "qup_err_intr";
+ qcom,i2c-bus-freq = <400000>;
+ qcom,i2c-src-freq = <19200000>;
+ qcom,scl-gpio = <&msmgpio 30 0>;
+ qcom,sda-gpio = <&msmgpio 29 0>;
+ qcom,master-id = <86>;
+ };
+
qcom,ssm {
compatible = "qcom,ssm";
qcom,channel-name = "SSM_RTR";
diff --git a/arch/arm/mach-msm/board-8610-gpiomux.c b/arch/arm/mach-msm/board-8610-gpiomux.c
index 20bb0e4..2e12fc2 100644
--- a/arch/arm/mach-msm/board-8610-gpiomux.c
+++ b/arch/arm/mach-msm/board-8610-gpiomux.c
@@ -615,6 +615,13 @@
static struct msm_gpiomux_config msm_interrupt_configs[] __initdata = {
{
+ .gpio = 75, /* NFC_CLK_REQ_IRQ*/
+ .settings = {
+ [GPIOMUX_ACTIVE] = &interrupt_gpio_active,
+ [GPIOMUX_SUSPENDED] = &interrupt_gpio_suspend_pullup,
+ },
+ },
+ {
.gpio = 77, /* NFC_IRQ */
.settings = {
[GPIOMUX_ACTIVE] = &interrupt_gpio_active,
diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c
index 7553f82..a3a2f56 100644
--- a/arch/arm/mach-msm/lpm_levels.c
+++ b/arch/arm/mach-msm/lpm_levels.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -341,7 +341,8 @@
const struct cpumask *nextcpu;
spin_lock(&system_state->sync_lock);
- if (num_powered_cores != system_state->num_cores_in_sync) {
+ if (index < 0 ||
+ num_powered_cores != system_state->num_cores_in_sync) {
spin_unlock(&system_state->sync_lock);
return;
}
@@ -418,7 +419,7 @@
system_lvl->num_cpu_votes--;
}
- if (!first_core_up)
+ if (!first_core_up || index < 0)
goto unlock_and_return;
if (default_l2_mode != system_state->system_level[index].l2_mode)
@@ -429,6 +430,7 @@
msm_mpm_exit_sleep(from_idle);
}
unlock_and_return:
+ system_state->last_entered_cluster_index = -1;
spin_unlock(&system_state->sync_lock);
}
@@ -724,8 +726,7 @@
idx = lpm_system_select(system_state, cpu_index, from_idle);
- if (idx >= 0)
- lpm_system_prepare(system_state, idx, from_idle);
+ lpm_system_prepare(system_state, idx, from_idle);
msm_cpu_pm_enter_sleep(cpu_level->mode, from_idle);
@@ -1011,6 +1012,7 @@
}
sys_state.system_level = level;
sys_state.num_system_levels = num_levels;
+ sys_state.last_entered_cluster_index = -1;
return ret;
fail:
kfree(level);
diff --git a/arch/arm/mach-msm/pil-pronto.c b/arch/arm/mach-msm/pil-pronto.c
index 69df3ae..a7fc204 100644
--- a/arch/arm/mach-msm/pil-pronto.c
+++ b/arch/arm/mach-msm/pil-pronto.c
@@ -85,6 +85,7 @@
bool crash;
struct delayed_work cancel_vote_work;
struct ramdump_device *ramdump_dev;
+ struct work_struct wcnss_wdog_bite_work;
};
static int pil_pronto_make_proxy_vote(struct pil_desc *pil)
@@ -322,6 +323,16 @@
return IRQ_HANDLED;
}
+static void wcnss_wdog_bite_work_hdlr(struct work_struct *wcnss_work)
+{
+ struct pronto_data *drv = container_of(wcnss_work, struct pronto_data,
+ wcnss_wdog_bite_work);
+
+ wcnss_log_debug_regs_on_bite();
+
+ restart_wcnss(drv);
+}
+
static irqreturn_t wcnss_wdog_bite_irq_hdlr(int irq, void *dev_id)
{
struct pronto_data *drv = subsys_to_drv(dev_id);
@@ -334,10 +345,9 @@
pr_err("Ignoring wcnss bite irq, restart in progress\n");
return IRQ_HANDLED;
}
- wcnss_log_debug_regs_on_bite();
drv->restart_inprogress = true;
- restart_wcnss(drv);
+ schedule_work(&drv->wcnss_wdog_bite_work);
return IRQ_HANDLED;
}
@@ -490,6 +500,7 @@
drv->subsys_desc.wdog_bite_handler = wcnss_wdog_bite_irq_hdlr;
INIT_DELAYED_WORK(&drv->cancel_vote_work, wcnss_post_bootup);
+ INIT_WORK(&drv->wcnss_wdog_bite_work, wcnss_wdog_bite_work_hdlr);
drv->subsys = subsys_register(&drv->subsys_desc);
if (IS_ERR(drv->subsys)) {
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index 37c236d..0edfdad 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -847,6 +847,22 @@
return ret;
}
+int diag_dci_find_client_index_health(int client_id)
+{
+ int i, ret = DCI_CLIENT_INDEX_INVALID;
+
+ for (i = 0; i < MAX_DCI_CLIENTS; i++) {
+ if (driver->dci_client_tbl[i].client != NULL) {
+ if (driver->dci_client_tbl[i].client_id ==
+ client_id) {
+ ret = i;
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
int diag_dci_find_client_index(int client_id)
{
int i, ret = DCI_CLIENT_INDEX_INVALID;
diff --git a/drivers/char/diag/diag_dci.h b/drivers/char/diag/diag_dci.h
index 2ab8a36..870b0f3 100644
--- a/drivers/char/diag/diag_dci.h
+++ b/drivers/char/diag/diag_dci.h
@@ -56,6 +56,7 @@
} __packed;
struct diag_dci_client_tbl {
+ uint32_t client_id;
struct task_struct *client;
uint16_t list; /* bit mask */
int signal_type;
@@ -74,6 +75,7 @@
/* This is used for DCI health stats */
struct diag_dci_health_stats {
+ int client_id;
int dropped_logs;
int dropped_events;
int received_logs;
@@ -119,6 +121,8 @@
int recd_bytes);
int diag_process_dci_transaction(unsigned char *buf, int len);
void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf);
+
+int diag_dci_find_client_index_health(int client_id);
int diag_dci_find_client_index(int client_id);
/* DCI Log streaming functions */
void create_dci_log_mask_tbl(unsigned char *tbl_buf);
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
index eb7a2a5..3a1c96b 100644
--- a/drivers/char/diag/diag_debugfs.c
+++ b/drivers/char/diag/diag_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 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
@@ -33,14 +33,14 @@
{
char *buf;
int ret;
-
+ unsigned int buf_size;
buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
if (!buf) {
pr_err("diag: %s, Error allocating memory\n", __func__);
return -ENOMEM;
}
-
- ret = scnprintf(buf, DEBUG_BUF_SIZE,
+ buf_size = ksize(buf);
+ ret = scnprintf(buf, buf_size,
"modem ch: 0x%x\n"
"lpass ch: 0x%x\n"
"riva ch: 0x%x\n"
@@ -181,7 +181,7 @@
driver->real_time_mode);
#ifdef CONFIG_DIAG_OVER_USB
- ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
+ ret += scnprintf(buf+ret, buf_size-ret,
"usb_connected: %d\n",
driver->usb_connected);
#endif
@@ -198,7 +198,8 @@
unsigned int bytes_remaining, bytes_written = 0;
unsigned int bytes_in_buf = 0, i = 0;
struct diag_dci_data_info *temp_data = dci_data_smd;
- int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
+ unsigned int buf_size;
+ buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
if (diag_dbgfs_dci_finished) {
diag_dbgfs_dci_finished = 0;
@@ -211,6 +212,7 @@
return -ENOMEM;
}
+ buf_size = ksize(buf);
bytes_remaining = buf_size;
if (diag_dbgfs_dci_data_index == 0) {
@@ -287,6 +289,7 @@
{
char *buf;
int ret;
+ unsigned int buf_size;
buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
if (!buf) {
@@ -294,7 +297,8 @@
return -ENOMEM;
}
- ret = scnprintf(buf, DEBUG_BUF_SIZE,
+ buf_size = ksize(buf);
+ ret = scnprintf(buf, buf_size,
"Pending status for work_stucts:\n"
"diag_drain_work: %d\n"
"Modem data diag_read_smd_work: %d\n"
@@ -342,7 +346,7 @@
diag_notify_update_smd_work)));
#ifdef CONFIG_DIAG_OVER_USB
- ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
+ ret += scnprintf(buf+ret, buf_size-ret,
"diag_proc_hdlc_work: %d\n"
"diag_read_work: %d\n",
work_pending(&(driver->diag_proc_hdlc_work)),
@@ -363,7 +367,8 @@
unsigned int bytes_remaining;
unsigned int bytes_in_buffer = 0;
unsigned int bytes_written;
- int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
+ unsigned int buf_size;
+ buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
if (diag_dbgfs_table_index >= diag_max_reg) {
/* Done. Reset to prepare for future requests */
@@ -376,7 +381,7 @@
pr_err("diag: %s, Error allocating memory\n", __func__);
return -ENOMEM;
}
-
+ buf_size = ksize(buf);
bytes_remaining = buf_size;
if (diag_dbgfs_table_index == 0) {
@@ -385,6 +390,7 @@
"WCNSS: %d, APPS: %d\n",
MODEM_DATA, LPASS_DATA, WCNSS_DATA, APPS_DATA);
bytes_in_buffer += bytes_written;
+ bytes_remaining -= bytes_written;
}
for (i = diag_dbgfs_table_index; i < diag_max_reg; i++) {
@@ -428,14 +434,15 @@
{
char *buf = NULL;
int ret = 0, i = 0;
-
+ unsigned int buf_size;
buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
if (ZERO_OR_NULL_PTR(buf)) {
pr_err("diag: %s, Error allocating memory\n", __func__);
return -ENOMEM;
}
+ buf_size = ksize(buf);
- ret = scnprintf(buf, DEBUG_BUF_SIZE,
+ ret = scnprintf(buf, buf_size,
"POOL_TYPE_COPY: [0x%p : 0x%p] count = %d\n"
"POOL_TYPE_HDLC: [0x%p : 0x%p] count = %d\n"
"POOL_TYPE_USER: [0x%p : 0x%p] count = %d\n"
@@ -456,7 +463,7 @@
for (i = 0; i < MAX_HSIC_CH; i++) {
if (!diag_hsic[i].hsic_inited)
continue;
- ret += scnprintf(buf+ret, DEBUG_BUF_SIZE-ret,
+ ret += scnprintf(buf+ret, buf_size-ret,
"POOL_TYPE_HSIC_%d: [0x%p : 0x%p] count = %d\n",
i+1,
diag_hsic[i].diag_hsic_pool,
@@ -467,7 +474,7 @@
for (i = 0; i < MAX_HSIC_CH; i++) {
if (!diag_hsic[i].hsic_inited)
continue;
- ret += scnprintf(buf+ret, DEBUG_BUF_SIZE-ret,
+ ret += scnprintf(buf+ret, buf_size-ret,
"POOL_TYPE_HSIC_%d_WRITE: [0x%p : 0x%p] count = %d\n",
i+1,
diag_hsic[i].diag_hsic_write_pool,
@@ -486,6 +493,7 @@
{
char *buf = NULL;
int ret = 0;
+ unsigned int buf_size;
buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
if (ZERO_OR_NULL_PTR(buf)) {
@@ -493,7 +501,8 @@
return -ENOMEM;
}
- ret = scnprintf(buf, DEBUG_BUF_SIZE,
+ buf_size = ksize(buf);
+ ret = scnprintf(buf, buf_size,
"POOL_TYPE_COPY: [0x%p : 0x%p] count = %d\n"
"POOL_TYPE_HDLC: [0x%p : 0x%p] count = %d\n"
"POOL_TYPE_USER: [0x%p : 0x%p] count = %d\n"
@@ -528,10 +537,12 @@
unsigned int bytes_remaining;
unsigned int bytes_in_buffer = 0;
unsigned int bytes_written;
- int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
+ unsigned int buf_size;
int bytes_hsic_inited = 45;
int bytes_hsic_not_inited = 410;
+ buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
+
if (diag_dbgfs_finished) {
diag_dbgfs_finished = 0;
return 0;
@@ -543,6 +554,7 @@
return -ENOMEM;
}
+ buf_size = ksize(buf);
bytes_remaining = buf_size;
/* Only one smux for now */
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 9a4e108..0e475c9 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -943,6 +943,8 @@
for (i = 0; i < MAX_DCI_CLIENTS; i++) {
if (driver->dci_client_tbl[i].client == NULL) {
driver->dci_client_tbl[i].client = current;
+ driver->dci_client_tbl[i].client_id =
+ driver->dci_client_id;
driver->dci_client_tbl[i].list =
dci_params->list;
driver->dci_client_tbl[i].signal_type =
@@ -1043,7 +1045,7 @@
sizeof(struct diag_dci_health_stats)))
return -EFAULT;
mutex_lock(&dci_health_mutex);
- i = diag_dci_find_client_index(current->tgid);
+ i = diag_dci_find_client_index_health(stats.client_id);
if (i != DCI_CLIENT_INDEX_INVALID) {
dci_params = &(driver->dci_client_tbl[i]);
stats.dropped_logs = dci_params->dropped_logs;
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.c b/drivers/input/touchscreen/gt9xx/gt9xx.c
index 912d87c..91d787f 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.c
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.c
@@ -1542,15 +1542,14 @@
const char *buf, size_t size)
{
struct goodix_ts_data *ts = dev_get_drvdata(dev);
- unsigned long val;
+ unsigned int val;
int ret;
if (size > 2)
return -EINVAL;
- ret = kstrtoul(buf, 10, &val);
- if (ret != 0)
- return ret;
+ if (sscanf(buf, "%u", &val) != 1);
+ return -EINVAL;
if (ts->gtp_is_suspend) {
dev_err(&ts->client->dev,
@@ -1576,16 +1575,60 @@
return size;
}
+static ssize_t gtp_force_fw_upgrade_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct goodix_ts_data *ts = dev_get_drvdata(dev);
+ unsigned int val;
+ int ret;
+
+ if (size > 2)
+ return -EINVAL;
+
+ if (sscanf(buf, "%u", &val) != 1);
+ return -EINVAL;
+
+ if (ts->gtp_is_suspend) {
+ dev_err(&ts->client->dev,
+ "Can't start fw upgrade. Device is in suspend state.");
+ return -EBUSY;
+ }
+
+ mutex_lock(&ts->input_dev->mutex);
+ if (!ts->fw_loading && val) {
+ disable_irq(ts->client->irq);
+ ts->fw_loading = true;
+ ts->force_update = true;
+ if (config_enabled(CONFIG_GT9XX_TOUCHPANEL_UPDATE)) {
+ ret = gup_update_proc(NULL);
+ if (ret == FAIL)
+ dev_err(&ts->client->dev,
+ "Fail to force update GTP firmware.\n");
+ }
+ ts->force_update = false;
+ ts->fw_loading = false;
+ enable_irq(ts->client->irq);
+ }
+ mutex_unlock(&ts->input_dev->mutex);
+
+ return size;
+}
+
static DEVICE_ATTR(fw_name, (S_IRUGO | S_IWUSR | S_IWGRP),
gtp_fw_name_show,
gtp_fw_name_store);
static DEVICE_ATTR(fw_upgrade, (S_IRUGO | S_IWUSR | S_IWGRP),
gtp_fw_upgrade_show,
gtp_fw_upgrade_store);
+static DEVICE_ATTR(force_fw_upgrade, (S_IRUGO | S_IWUSR | S_IWGRP),
+ gtp_fw_upgrade_show,
+ gtp_force_fw_upgrade_store);
static struct attribute *gtp_attrs[] = {
&dev_attr_fw_name.attr,
&dev_attr_fw_upgrade.attr,
+ &dev_attr_force_fw_upgrade.attr,
NULL
};
@@ -1802,8 +1845,8 @@
pdata->i2c_pull_up = of_property_read_bool(np,
"goodix,i2c-pull-up");
- pdata->no_force_update = of_property_read_bool(np,
- "goodix,no-force-update");
+ pdata->force_update = of_property_read_bool(np,
+ "goodix,force-update");
pdata->enable_power_off = of_property_read_bool(np,
"goodix,enable-power-off");
@@ -1971,6 +2014,9 @@
goto exit_power_off;
}
+ if (pdata->force_update)
+ ts->force_update = true;
+
if (pdata->fw_name)
strlcpy(ts->fw_name, pdata->fw_name,
strlen(pdata->fw_name) + 1);
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.h b/drivers/input/touchscreen/gt9xx/gt9xx.h
index 7a1af23..0ba6895 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.h
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.h
@@ -56,7 +56,7 @@
u32 panel_miny;
u32 panel_maxx;
u32 panel_maxy;
- bool no_force_update;
+ bool force_update;
bool i2c_pull_up;
bool enable_power_off;
size_t config_data_len[GOODIX_MAX_CFG_GROUP];
@@ -94,6 +94,7 @@
bool power_on;
struct mutex lock;
bool fw_loading;
+ bool force_update;
struct regulator *avdd;
struct regulator *vdd;
struct regulator *vcc_i2c;
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx_update.c b/drivers/input/touchscreen/gt9xx/gt9xx_update.c
index 71e8a55..af80eef 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx_update.c
+++ b/drivers/input/touchscreen/gt9xx/gt9xx_update.c
@@ -1,7 +1,7 @@
/* drivers/input/touchscreen/gt9xx_update.c
*
* 2010 - 2012 Goodix Technology.
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 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 as published by
@@ -1432,10 +1432,15 @@
goto file_fail;
}
- ret = gup_enter_update_judge(ts->client, &fw_head);
- if (ret == FAIL) {
- pr_err("Check *.bin file fail.");
- goto file_fail;
+ if (ts->force_update) {
+ dev_dbg(&ts->client->dev, "Enter force update.");
+ } else {
+ ret = gup_enter_update_judge(ts->client, &fw_head);
+ if (ret == FAIL) {
+ dev_err(&ts->client->dev,
+ "Check *.bin file fail.");
+ goto file_fail;
+ }
}
ts->enter_update = 1;
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index 4da0f6f..4b7a3be 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -360,6 +360,18 @@
case HAL_EXTRADATA_MPEG2_SEQDISP:
ret = HFI_PROPERTY_PARAM_VDEC_MPEG2_SEQDISP_EXTRADATA;
break;
+ case HAL_EXTRADATA_FRAME_QP:
+ ret = HFI_PROPERTY_PARAM_VDEC_FRAME_QP_EXTRADATA;
+ break;
+ case HAL_EXTRADATA_FRAME_BITS_INFO:
+ ret = HFI_PROPERTY_PARAM_VDEC_FRAME_BITS_INFO_EXTRADATA;
+ break;
+ case HAL_EXTRADATA_LTR_INFO:
+ ret = HFI_PROPERTY_PARAM_VENC_LTR_INFO;
+ break;
+ case HAL_EXTRADATA_METADATA_MBI:
+ ret = HFI_PROPERTY_PARAM_VENC_MBI_DUMPING;
+ break;
default:
dprintk(VIDC_WARN, "Extradata index not found: %d\n", index);
break;
@@ -389,6 +401,28 @@
return buf_mode;
}
+static u32 get_hfi_ltr_mode(enum ltr_mode ltr_mode_type)
+{
+ u32 ltrmode;
+ switch (ltr_mode_type) {
+ case HAL_LTR_MODE_DISABLE:
+ ltrmode = HFI_LTR_MODE_DISABLE;
+ break;
+ case HAL_LTR_MODE_MANUAL:
+ ltrmode = HFI_LTR_MODE_MANUAL;
+ break;
+ case HAL_LTR_MODE_PERIODIC:
+ ltrmode = HFI_LTR_MODE_PERIODIC;
+ break;
+ default:
+ dprintk(VIDC_ERR, "Invalid ltr mode :0x%x\n",
+ ltr_mode_type);
+ ltrmode = HFI_LTR_MODE_DISABLE;
+ break;
+ }
+ return ltrmode;
+}
+
int create_pkt_cmd_session_set_buffers(
struct hfi_cmd_session_set_buffers_packet *pkt,
u32 session_id,
@@ -1405,6 +1439,54 @@
pkt->size += sizeof(u32) + sizeof(struct hfi_enable);
break;
}
+ case HAL_PARAM_VENC_LTRMODE:
+ {
+ struct hfi_ltrmode *hfi;
+ struct hal_ltrmode *hal = pdata;
+ pkt->rg_property_data[0] =
+ HFI_PROPERTY_PARAM_VENC_LTRMODE;
+ hfi = (struct hfi_ltrmode *) &pkt->rg_property_data[1];
+ hfi->ltrmode = get_hfi_ltr_mode(hal->ltrmode);
+ hfi->ltrcount = hal->ltrcount;
+ hfi->trustmode = hal->trustmode;
+ pkt->size += sizeof(u32) + sizeof(struct hfi_ltrmode);
+ pr_err("SET LTR\n");
+ break;
+ }
+ case HAL_CONFIG_VENC_USELTRFRAME:
+ {
+ struct hfi_ltruse *hfi;
+ struct hal_ltruse *hal = pdata;
+ pkt->rg_property_data[0] =
+ HFI_PROPERTY_CONFIG_VENC_USELTRFRAME;
+ hfi = (struct hfi_ltruse *) &pkt->rg_property_data[1];
+ hfi->frames = hal->frames;
+ hfi->refltr = hal->refltr;
+ hfi->useconstrnt = hal->useconstrnt;
+ pkt->size += sizeof(u32) + sizeof(struct hfi_ltruse);
+ pr_err("USE LTR\n");
+ break;
+ }
+ case HAL_CONFIG_VENC_MARKLTRFRAME:
+ {
+ struct hfi_ltrmark *hfi;
+ struct hal_ltrmark *hal = pdata;
+ pkt->rg_property_data[0] =
+ HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME;
+ hfi = (struct hfi_ltrmark *) &pkt->rg_property_data[1];
+ hfi->markframe = hal->markframe;
+ pkt->size += sizeof(u32) + sizeof(struct hfi_ltrmark);
+ pr_err("MARK LTR\n");
+ break;
+ }
+ case HAL_PARAM_VENC_HIER_P_NUM_FRAMES:
+ {
+ pkt->rg_property_data[0] =
+ HFI_PROPERTY_PARAM_VENC_HIER_P_NUM_ENH_LAYER;
+ pkt->rg_property_data[1] = *(u32 *)pdata;
+ pkt->size += sizeof(u32) * 2;
+ break;
+ }
/* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */
case HAL_CONFIG_BUFFER_REQUIREMENTS:
case HAL_CONFIG_PRIORITY:
@@ -1432,7 +1514,7 @@
case HAL_CONFIG_VENC_TIMESTAMP_SCALE:
case HAL_PARAM_VENC_LOW_LATENCY:
default:
- dprintk(VIDC_ERR, "DEFAULT: Calling 0x%x", ptype);
+ dprintk(VIDC_ERR, "DEFAULT: Calling 0x%x\n", ptype);
rc = -ENOTSUPP;
break;
}
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index 189fca0..f4ad985 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -388,6 +388,10 @@
struct vidc_hal_session_init_done *sess_init_done)
{
struct hal_capability_supported *out = NULL;
+ if (!in) {
+ dprintk(VIDC_ERR, "Invalid input for supported capabilties\n");
+ return;
+ }
switch (in->capability_type) {
case HFI_CAPABILITY_FRAME_WIDTH:
out = &sess_init_done->width;
@@ -420,9 +424,17 @@
case HFI_CAPABILITY_BITRATE:
out = &sess_init_done->bitrate;
break;
+
+ case HFI_CAPABILITY_ENC_LTR_COUNT:
+ out = &sess_init_done->ltr_count;
+ break;
+
+ case HFI_CAPABILITY_HIER_P_NUM_ENH_LAYERS:
+ out = &sess_init_done->hier_p;
+ break;
}
- if (in && out) {
+ if (out) {
out->capability_type =
(enum hal_capability)in->capability_type;
out->min = in->min;
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index 5e3699d..176c612 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -120,6 +120,13 @@
return msm_vidc_g_ctrl((void *)vidc_inst, a);
}
+int msm_v4l2_s_ext_ctrl(struct file *file, void *fh,
+ struct v4l2_ext_controls *a)
+{
+ struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+ return msm_vidc_s_ext_ctrl((void *)vidc_inst, a);
+}
+
int msm_v4l2_reqbufs(struct file *file, void *fh,
struct v4l2_requestbuffers *b)
{
@@ -242,6 +249,7 @@
.vidioc_streamoff = msm_v4l2_streamoff,
.vidioc_s_ctrl = msm_v4l2_s_ctrl,
.vidioc_g_ctrl = msm_v4l2_g_ctrl,
+ .vidioc_s_ext_ctrls = msm_v4l2_s_ext_ctrl,
.vidioc_subscribe_event = msm_v4l2_subscribe_event,
.vidioc_unsubscribe_event = msm_v4l2_unsubscribe_event,
.vidioc_decoder_cmd = msm_v4l2_decoder_cmd,
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index de16c17..71ad080 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -220,7 +220,7 @@
.name = "Extradata Type",
.type = V4L2_CTRL_TYPE_MENU,
.minimum = V4L2_MPEG_VIDC_EXTRADATA_NONE,
- .maximum = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP,
+ .maximum = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO,
.default_value = V4L2_MPEG_VIDC_EXTRADATA_NONE,
.menu_skip_mask = ~(
(1 << V4L2_MPEG_VIDC_EXTRADATA_NONE) |
@@ -241,7 +241,9 @@
(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_INPUT_CROP) |
(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_DIGITAL_ZOOM) |
(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO) |
- (1 << V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP)
+ (1 << V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP) |
+ (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP) |
+ (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO)
),
.qmenu = mpeg_video_vidc_extradata,
.step = 0,
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index de59e81..b01a507 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -37,6 +37,8 @@
#define B_FRAME_QP 30
#define MAX_INTRA_REFRESH_MBS 300
#define MAX_NUM_B_FRAMES 4
+#define MAX_LTR_FRAME_COUNT 10
+
#define L_MODE V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
#define CODING V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY
@@ -114,6 +116,7 @@
"Extradata input crop",
"Extradata digital zoom",
"Extradata aspect ratio",
+ "Extradata macroblock metadata",
};
static const char *const perf_level[] = {
@@ -135,7 +138,8 @@
MSM_VENC_CTRL_CLUSTER_TIMING = 1 << 9,
MSM_VENC_CTRL_CLUSTER_VP8_PROFILE_LEVEL = 1 << 10,
MSM_VENC_CTRL_CLUSTER_DEINTERLACE = 1 << 11,
- MSM_VENC_CTRL_CLUSTER_MAX = 1 << 12,
+ MSM_VENC_CTRL_CLUSTER_USE_LTRFRAME = 1 << 12,
+ MSM_VENC_CTRL_CLUSTER_MAX = 1 << 13,
};
static struct msm_vidc_ctrl msm_venc_ctrls[] = {
@@ -651,7 +655,7 @@
.name = "Extradata Type",
.type = V4L2_CTRL_TYPE_MENU,
.minimum = V4L2_MPEG_VIDC_EXTRADATA_NONE,
- .maximum = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO,
+ .maximum = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI,
.default_value = V4L2_MPEG_VIDC_EXTRADATA_NONE,
.menu_skip_mask = ~(
(1 << V4L2_MPEG_VIDC_EXTRADATA_NONE) |
@@ -671,7 +675,9 @@
(1 << V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER) |
(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_INPUT_CROP) |
(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_DIGITAL_ZOOM) |
- (1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO)
+ (1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO) |
+ (1 << V4L2_MPEG_VIDC_EXTRADATA_LTR) |
+ (1 << V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI)
),
.qmenu = mpeg_video_vidc_extradata,
.step = 0,
@@ -729,6 +735,61 @@
.default_value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_DISABLED,
.step = 1,
.cluster = MSM_VENC_CTRL_CLUSTER_DEINTERLACE,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME,
+ .name = "H264 Use LTR",
+ .type = V4L2_CTRL_TYPE_BUTTON,
+ .minimum = 0,
+ .maximum = (MAX_LTR_FRAME_COUNT - 1),
+ .default_value = 0,
+ .step = 1,
+ .qmenu = NULL,
+ .cluster = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT,
+ .name = "Ltr Count",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = MAX_LTR_FRAME_COUNT,
+ .default_value = 0,
+ .step = 1,
+ .qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_USE_LTRFRAME,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE,
+ .name = "Ltr Mode",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE,
+ .maximum = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_PERIODIC,
+ .default_value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE,
+ .step = 1,
+ .qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_USE_LTRFRAME,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME,
+ .name = "H264 Mark LTR",
+ .type = V4L2_CTRL_TYPE_BUTTON,
+ .minimum = 0,
+ .maximum = (MAX_LTR_FRAME_COUNT - 1),
+ .default_value = 0,
+ .step = 1,
+ .qmenu = NULL,
+ .cluster = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS,
+ .name = "Set Hier P num layers",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 3,
+ .default_value = 0,
+ .step = 1,
+ .qmenu = NULL,
+ .cluster = 0,
}
};
@@ -836,28 +897,33 @@
*num_buffers = buff_req->buffer_count_actual =
max(*num_buffers, buff_req->buffer_count_actual);
}
- if (*num_buffers < MIN_NUM_CAPTURE_BUFFERS)
- *num_buffers = MIN_NUM_CAPTURE_BUFFERS;
- if (*num_buffers > VIDEO_MAX_FRAME) {
- dprintk(VIDC_ERR,
- "Changing buffers requested, from %d to max"\
- " supported (%d) best effort encoding\n",
- *num_buffers, VIDEO_MAX_FRAME);
- *num_buffers = VIDEO_MAX_FRAME;
+ if (*num_buffers < MIN_NUM_CAPTURE_BUFFERS ||
+ *num_buffers > VIDEO_MAX_FRAME) {
+ int temp = *num_buffers;
+
+ *num_buffers = clamp_val(*num_buffers,
+ MIN_NUM_CAPTURE_BUFFERS,
+ VIDEO_MAX_FRAME);
+ dprintk(VIDC_INFO,
+ "Changing buffer count on CAPTURE_MPLANE from %d to %d for best effort encoding\n",
+ temp, *num_buffers);
}
+
ctrl = v4l2_ctrl_find(&inst->ctrl_handler,
V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA);
if (ctrl)
extradata = v4l2_ctrl_g_ctrl(ctrl);
- if (extradata)
+ if (extradata != V4L2_MPEG_VIDC_EXTRADATA_NONE)
*num_planes = *num_planes + 1;
inst->fmts[CAPTURE_PORT]->num_planes = *num_planes;
+
for (i = 0; i < *num_planes; i++) {
sizes[i] = inst->fmts[CAPTURE_PORT]->get_frame_size(
i, inst->prop.height[CAPTURE_PORT],
inst->prop.width[CAPTURE_PORT]);
}
+
property_id = HAL_PARAM_BUFFER_COUNT_ACTUAL;
new_buf_count.buffer_type = HAL_BUFFER_OUTPUT;
new_buf_count.buffer_count_actual = *num_buffers;
@@ -1273,6 +1339,9 @@
struct v4l2_ctrl *temp_ctrl = NULL;
struct hfi_device *hdev;
struct hal_extradata_enable extra;
+ struct hal_ltruse useltr;
+ struct hal_ltrmark markltr;
+ u32 hier_p_layers;
if (!inst || !inst->core || !inst->core->device) {
dprintk(VIDC_ERR, "%s invalid parameters", __func__);
@@ -1970,7 +2039,33 @@
pdata = &enable;
break;
}
+ case V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME:
+ property_id = HAL_CONFIG_VENC_USELTRFRAME;
+ useltr.refltr = ctrl->val;
+ useltr.useconstrnt = false;
+ useltr.frames = 0;
+ pdata = &useltr;
+ break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME:
+ property_id = HAL_CONFIG_VENC_MARKLTRFRAME;
+ markltr.markframe = ctrl->val;
+ pdata = &markltr;
+ break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS:
+ property_id = HAL_PARAM_VENC_HIER_P_NUM_FRAMES;
+ hier_p_layers = ctrl->val;
+ if (hier_p_layers > (inst->capability.hier_p.max - 1)) {
+ dprintk(VIDC_ERR,
+ "Error setting hier p num layers = %d max supported by f/w = %d\n",
+ hier_p_layers,
+ inst->capability.hier_p.max - 1);
+ rc = -ENOTSUPP;
+ break;
+ }
+ pdata = &hier_p_layers;
+ break;
default:
+ dprintk(VIDC_ERR, "Unsupported index: %x\n", ctrl->id);
rc = -ENOTSUPP;
break;
}
@@ -1987,6 +2082,89 @@
return rc;
}
+static struct v4l2_ctrl *get_cluster_from_id(int id)
+{
+ int c;
+ for (c = 0; c < ARRAY_SIZE(msm_venc_ctrls); ++c)
+ if (msm_venc_ctrls[c].id == id)
+ return (struct v4l2_ctrl *)msm_venc_ctrls[c].priv;
+ return NULL;
+}
+
+static int try_set_ext_ctrl(struct msm_vidc_inst *inst,
+ struct v4l2_ext_controls *ctrl)
+{
+ int rc = 0, i;
+ struct v4l2_ext_control *control;
+ struct hfi_device *hdev;
+ struct hal_ltrmode ltrmode;
+ struct v4l2_ctrl *cluster;
+ u32 property_id = 0;
+ void *pdata = NULL;
+ struct msm_vidc_core_capability *cap = NULL;
+
+ if (!inst || !inst->core || !inst->core->device || !ctrl) {
+ dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
+ return -EINVAL;
+ }
+
+ cluster = get_cluster_from_id(ctrl->controls[0].id);
+
+ if (!cluster) {
+ dprintk(VIDC_ERR, "Invalid Ctrl returned for id: %x\n",
+ ctrl->controls[0].id);
+ return -EINVAL;
+ }
+
+ hdev = inst->core->device;
+ cap = &inst->capability;
+
+ control = ctrl->controls;
+ for (i = 0; i < ctrl->count; i++) {
+ switch (control[i].id) {
+ case V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE:
+ ltrmode.ltrmode = control[i].value;
+ ltrmode.trustmode = 1;
+ property_id = HAL_PARAM_VENC_LTRMODE;
+ pdata = <rmode;
+ break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT:
+ ltrmode.ltrcount = control[i].value;
+ if (ltrmode.ltrcount > cap->ltr_count.max) {
+ dprintk(VIDC_ERR,
+ "Invalid LTR count %d. Supported max: %d\n",
+ ltrmode.ltrcount,
+ cap->ltr_count.max);
+ /*
+ * FIXME: Return an error (-EINVALID)
+ * here once VP8 supports LTR count
+ * capability
+ */
+ ltrmode.ltrcount = 1;
+ }
+ ltrmode.trustmode = 1;
+ property_id = HAL_PARAM_VENC_LTRMODE;
+ pdata = <rmode;
+ break;
+ default:
+ dprintk(VIDC_ERR, "Invalid id set: %d\n",
+ control[i].id);
+ rc = -ENOTSUPP;
+ break;
+ }
+ if (rc)
+ break;
+ }
+
+ if (!rc && property_id) {
+ dprintk(VIDC_DBG, "Control: HAL property=%x\n", property_id);
+ rc = call_hfi_op(hdev, session_set_property,
+ (void *)inst->session, property_id, pdata);
+ }
+ pr_err("Returning from %s\n", __func__);
+ return rc;
+}
+
static int msm_venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
{
@@ -2072,6 +2250,22 @@
return v4l2_g_ctrl(&inst->ctrl_handler, ctrl);
}
+int msm_venc_s_ext_ctrl(struct msm_vidc_inst *inst,
+ struct v4l2_ext_controls *ctrl)
+{
+ int rc = 0;
+ if (ctrl->ctrl_class != V4L2_CTRL_CLASS_MPEG) {
+ dprintk(VIDC_ERR, "Invalid Class set for extended control\n");
+ return -EINVAL;
+ }
+ rc = try_set_ext_ctrl(inst, ctrl);
+ if (rc) {
+ dprintk(VIDC_ERR, "Error setting extended control\n");
+ return rc;
+ }
+ return rc;
+}
+
int msm_venc_cmd(struct msm_vidc_inst *inst, struct v4l2_encoder_cmd *enc)
{
int rc = 0;
diff --git a/drivers/media/platform/msm/vidc/msm_venc.h b/drivers/media/platform/msm/vidc/msm_venc.h
index 9020167..5965d39 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.h
+++ b/drivers/media/platform/msm/vidc/msm_venc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012, 2014, 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
@@ -25,6 +25,7 @@
int msm_venc_g_fmt(void *instance, struct v4l2_format *f);
int msm_venc_s_ctrl(void *instance, struct v4l2_control *a);
int msm_venc_g_ctrl(void *instance, struct v4l2_control *a);
+int msm_venc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *a);
int msm_venc_reqbufs(void *instance, struct v4l2_requestbuffers *b);
int msm_venc_prepare_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
int msm_venc_release_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 7a8b2ca..59a1ec0 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -185,6 +185,15 @@
return msm_venc_g_ctrl(instance, control);
return -EINVAL;
}
+int msm_vidc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *control)
+{
+ struct msm_vidc_inst *inst = instance;
+ if (!inst || !control)
+ return -EINVAL;
+ if (inst->session_type == MSM_VIDC_ENCODER)
+ return msm_venc_s_ext_ctrl(instance, control);
+ return -EINVAL;
+}
int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
{
struct msm_vidc_inst *inst = instance;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 7ae2cb5..95afa2a 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -463,6 +463,9 @@
session_init_done->frame_rate;
inst->capability.scale_x = session_init_done->scale_x;
inst->capability.scale_y = session_init_done->scale_y;
+ inst->capability.ltr_count =
+ session_init_done->ltr_count;
+ inst->capability.hier_p = session_init_done->hier_p;
inst->capability.pixelprocess_capabilities =
call_hfi_op(hdev, get_core_capabilities);
inst->capability.capability_set = true;
@@ -1117,6 +1120,7 @@
struct vidc_hal_fbd *fill_buf_done;
enum hal_buffer buffer_type;
int64_t time_usec = 0;
+ int extra_idx = 0;
if (!response) {
dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
@@ -1163,6 +1167,15 @@
ns_to_timeval(time_usec * NSEC_PER_USEC);
}
vb->v4l2_buf.flags = 0;
+ extra_idx =
+ EXTRADATA_IDX(inst->fmts[CAPTURE_PORT]->num_planes);
+ if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+ vb->v4l2_planes[extra_idx].m.userptr =
+ (unsigned long)fill_buf_done->extra_data_buffer;
+ vb->v4l2_planes[extra_idx].bytesused =
+ vb->v4l2_planes[extra_idx].length;
+ vb->v4l2_planes[extra_idx].data_offset = 0;
+ }
handle_dynamic_buffer(inst, (u32)fill_buf_done->packet_buffer1,
fill_buf_done->flags1);
@@ -1217,6 +1230,13 @@
fill_buf_done->start_y_coord, fill_buf_done->frame_width,
fill_buf_done->frame_height, fill_buf_done->picture_type);
+ if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+ dprintk(VIDC_DBG,
+ "extradata: userptr = %p; bytesused = %d; length = %d\n",
+ (u8 *)vb->v4l2_planes[extra_idx].m.userptr,
+ vb->v4l2_planes[extra_idx].bytesused,
+ vb->v4l2_planes[extra_idx].length);
+ }
mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
@@ -3121,6 +3141,18 @@
case V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP:
ret = HAL_EXTRADATA_MPEG2_SEQDISP;
break;
+ case V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP:
+ ret = HAL_EXTRADATA_FRAME_QP;
+ break;
+ case V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO:
+ ret = HAL_EXTRADATA_FRAME_BITS_INFO;
+ break;
+ case V4L2_MPEG_VIDC_EXTRADATA_LTR:
+ ret = HAL_EXTRADATA_LTR_INFO;
+ break;
+ case V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI:
+ ret = HAL_EXTRADATA_METADATA_MBI;
+ break;
default:
dprintk(VIDC_WARN, "Extradata not found: %d\n", index);
break;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index e4f920f..06181dd 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -190,6 +190,8 @@
u32 pixelprocess_capabilities;
struct hal_capability_supported scale_x;
struct hal_capability_supported scale_y;
+ struct hal_capability_supported ltr_count;
+ struct hal_capability_supported hier_p;
u32 capability_set;
enum buffer_mode_type buffer_mode[MAX_PORT_NUM];
};
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.h b/drivers/media/platform/msm/vidc/vidc_hfi.h
index 70b93ff0..75f583f 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -19,6 +19,7 @@
#define HFI_EVENT_SESSION_SEQUENCE_CHANGED (HFI_OX_BASE + 0x3)
#define HFI_EVENT_SESSION_PROPERTY_CHANGED (HFI_OX_BASE + 0x4)
+#define HFI_EVENT_SESSION_LTRUSE_FAILED (HFI_OX_BASE + 0x5)
#define HFI_EVENT_RELEASE_BUFFER_REFERENCE (HFI_OX_BASE + 0x6)
#define HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUFFER_RESOURCES \
@@ -81,9 +82,12 @@
#define HFI_EXTRADATA_CLOSED_CAPTION_UD 0x0000000A
#define HFI_EXTRADATA_AFD_UD 0x0000000B
#define HFI_EXTRADATA_MPEG2_SEQDISP 0x0000000D
+#define HFI_EXTRADATA_FRAME_QP 0x0000000F
+#define HFI_EXTRADATA_FRAME_BITS_INFO 0x00000010
#define HFI_EXTRADATA_MULTISLICE_INFO 0x7F100000
#define HFI_EXTRADATA_NUM_CONCEALED_MB 0x7F100001
#define HFI_EXTRADATA_INDEX 0x7F100002
+#define HFI_EXTRADATA_METADATA_LTR 0x7F100004
#define HFI_EXTRADATA_METADATA_FILLER 0x7FE00002
#define HFI_INDEX_EXTRADATA_INPUT_CROP 0x0700000E
@@ -202,6 +206,10 @@
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x015)
#define HFI_PROPERTY_PARAM_VDEC_MPEG2_SEQDISP_EXTRADATA \
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x016)
+#define HFI_PROPERTY_PARAM_VDEC_FRAME_QP_EXTRADATA \
+ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x018)
+#define HFI_PROPERTY_PARAM_VDEC_FRAME_BITS_INFO_EXTRADATA \
+ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x019)
#define HFI_PROPERTY_CONFIG_VDEC_OX_START \
(HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x0000)
@@ -218,6 +226,10 @@
(HFI_PROPERTY_PARAM_VENC_OX_START + 0x001)
#define HFI_PROPERTY_PARAM_VENC_H264_IDR_S3D_FRAME_PACKING_NAL \
(HFI_PROPERTY_PARAM_VENC_OX_START + 0x002)
+#define HFI_PROPERTY_PARAM_VENC_LTR_INFO \
+ (HFI_PROPERTY_PARAM_VENC_OX_START + 0x003)
+#define HFI_PROPERTY_PARAM_VENC_MBI_DUMPING \
+ (HFI_PROPERTY_PARAM_VENC_OX_START + 0x005)
#define HFI_PROPERTY_CONFIG_VENC_OX_START \
(HFI_DOMAIN_BASE_VENC + HFI_ARCH_OX_OFFSET + 0x6000)
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index 846171e..c764758 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -97,7 +97,11 @@
HAL_EXTRADATA_NUM_CONCEALED_MB,
HAL_EXTRADATA_METADATA_FILLER,
HAL_EXTRADATA_ASPECT_RATIO,
- HAL_EXTRADATA_MPEG2_SEQDISP
+ HAL_EXTRADATA_MPEG2_SEQDISP,
+ HAL_EXTRADATA_FRAME_QP,
+ HAL_EXTRADATA_FRAME_BITS_INFO,
+ HAL_EXTRADATA_LTR_INFO,
+ HAL_EXTRADATA_METADATA_MBI,
};
enum hal_property {
@@ -177,6 +181,11 @@
HAL_PARAM_BUFFER_ALLOC_MODE,
HAL_PARAM_VDEC_FRAME_ASSEMBLY,
HAL_PARAM_VDEC_CONCEAL_COLOR,
+ HAL_PARAM_VENC_LTRMODE,
+ HAL_CONFIG_VENC_MARKLTRFRAME,
+ HAL_CONFIG_VENC_USELTRFRAME,
+ HAL_CONFIG_VENC_LTRPERIOD,
+ HAL_PARAM_VENC_HIER_P_NUM_FRAMES,
};
enum hal_domain {
@@ -896,6 +905,27 @@
enum buffer_mode_type buffer_mode;
};
+enum ltr_mode {
+ HAL_LTR_MODE_DISABLE,
+ HAL_LTR_MODE_MANUAL,
+ HAL_LTR_MODE_PERIODIC,
+};
+
+struct hal_ltrmode {
+ enum ltr_mode ltrmode;
+ u32 ltrcount;
+ u32 trustmode;
+};
+
+struct hal_ltruse {
+ u32 refltr;
+ u32 useconstrnt;
+ u32 frames;
+};
+
+struct hal_ltrmark {
+ u32 markframe;
+};
/* HAL Response */
enum command_response {
@@ -1032,6 +1062,8 @@
struct hal_capability_supported scale_x;
struct hal_capability_supported scale_y;
struct hal_capability_supported bitrate;
+ struct hal_capability_supported ltr_count;
+ struct hal_capability_supported hier_p;
struct hal_uncompressed_format_supported uncomp_format;
struct hal_interlace_format_supported HAL_format;
struct hal_nal_stream_format_supported nal_stream_format;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index 1916e9f..5117266 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -309,7 +309,7 @@
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01A)
#define HFI_PROPERTY_PARAM_VENC_H264_NAL_SVC_EXT \
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01B)
-#define HFI_PROPERTY_PARAM_VENC_H264_LTRMODE \
+#define HFI_PROPERTY_PARAM_VENC_LTRMODE \
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01C)
#define HFI_PROPERTY_PARAM_VENC_VIDEO_FULL_RANGE \
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01D)
@@ -338,7 +338,12 @@
(HFI_DOMAIN_BASE_VPE + HFI_ARCH_COMMON_OFFSET + 0x7000)
#define HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER \
(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x008)
-
+#define HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME \
+ (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x009)
+#define HFI_PROPERTY_CONFIG_VENC_USELTRFRAME \
+ (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x00A)
+#define HFI_PROPERTY_CONFIG_VENC_LTRPERIOD \
+ (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x00C)
#define HFI_PROPERTY_CONFIG_VPE_COMMON_START \
(HFI_DOMAIN_BASE_VPE + HFI_ARCH_COMMON_OFFSET + 0x8000)
#define HFI_PROPERTY_CONFIG_VPE_DEINTERLACE \
@@ -361,6 +366,7 @@
#define HFI_CAPABILITY_BITRATE (HFI_COMMON_BASE + 0x8)
#define HFI_CAPABILITY_BFRAME (HFI_COMMON_BASE + 0x9)
#define HFI_CAPABILITY_HIER_P_NUM_ENH_LAYERS (HFI_COMMON_BASE + 0x10)
+#define HFI_CAPABILITY_ENC_LTR_COUNT (HFI_COMMON_BASE + 0x11)
struct hfi_capability_supported {
u32 capability_type;
@@ -531,6 +537,26 @@
u32 layer_id;
};
+#define HFI_LTR_MODE_DISABLE 0x0
+#define HFI_LTR_MODE_MANUAL 0x1
+#define HFI_LTR_MODE_PERIODIC 0x2
+
+struct hfi_ltrmode {
+ u32 ltrmode;
+ u32 ltrcount;
+ u32 trustmode;
+};
+
+struct hfi_ltruse {
+ u32 refltr;
+ u32 useconstrnt;
+ u32 frames;
+};
+
+struct hfi_ltrmark {
+ u32 markframe;
+};
+
struct hfi_frame_size {
u32 buffer_type;
u32 width;
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index 1c42431..5eb359e 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -555,7 +555,6 @@
{WCD9XXX_IRQ_EAR_PA_OCPL_FAULT, false},
{WCD9XXX_IRQ_HPH_L_PA_STARTUP, false},
{WCD9XXX_IRQ_HPH_R_PA_STARTUP, false},
- {WCD9320_IRQ_EAR_PA_STARTUP, false},
{WCD9XXX_IRQ_RESERVED_0, false},
{WCD9XXX_IRQ_RESERVED_1, false},
{WCD9XXX_IRQ_MAD_AUDIO, false},
diff --git a/drivers/nfc/nfc-nci.c b/drivers/nfc/nfc-nci.c
index b808f97..c6192ed 100644
--- a/drivers/nfc/nfc-nci.c
+++ b/drivers/nfc/nfc-nci.c
@@ -30,8 +30,10 @@
struct qca199x_platform_data {
unsigned int irq_gpio;
+ unsigned int irq_gpio_clk_req;
+ unsigned int clk_req_irq_num;
unsigned int dis_gpio;
- unsigned int ven_gpio;
+ unsigned int clkreq_gpio;
unsigned int reg;
const char *clk_src_name;
unsigned int clk_src_gpio;
@@ -52,32 +54,48 @@
#define MAX_PACKET_SIZE (PACKET_HEADER_SIZE_NCI + 255)
#define MAX_QCA_REG (116)
/* will timeout in approx. 100ms as 10us steps */
+#define NFC_RF_CLK_FREQ (19200000)
#define NTF_TIMEOUT (10000)
#define CORE_RESET_RSP_GID (0x60)
#define CORE_RESET_OID (0x00)
#define CORE_RST_NTF_LENGTH (0x02)
+static void clk_req_update(struct work_struct *work);
struct qca199x_dev {
wait_queue_head_t read_wq;
- struct mutex read_mutex;
- struct i2c_client *client;
- struct miscdevice qca199x_device;
- unsigned int irq_gpio;
- unsigned int dis_gpio;
- unsigned int ven_gpio;
- bool irq_enabled;
- bool sent_first_nci_write;
- spinlock_t irq_enabled_lock;
- unsigned int count_irq;
+ struct mutex read_mutex;
+ struct i2c_client *client;
+ struct miscdevice qca199x_device;
+ /* NFC_IRQ new NCI data available */
+ unsigned int irq_gpio;
+ /* CLK_REQ IRQ to signal the state has changed */
+ unsigned int irq_gpio_clk_req;
+ /* Actual IRQ no. assigned to CLK_REQ */
+ unsigned int clk_req_irq_num;
+ unsigned int dis_gpio;
+ unsigned int clkreq_gpio;
+ /* NFC_IRQ state */
+ bool irq_enabled;
+ bool sent_first_nci_write;
+ spinlock_t irq_enabled_lock;
+ unsigned int count_irq;
+ /* CLK_REQ IRQ state */
+ bool irq_enabled_clk_req;
+ spinlock_t irq_enabled_lock_clk_req;
+ unsigned int count_irq_clk_req;
enum nfcc_state state;
- unsigned int clk_src_gpio;
- const char *clk_src_name;
- struct clk *s_clk;
- bool clk_run;
+ /* CLK control */
+ unsigned int clk_src_gpio;
+ const char *clk_src_name;
+ struct clk *s_clk;
+ bool clk_run;
+ struct work_struct msm_clock_controll_work;
+ struct workqueue_struct *my_wq;
};
static int nfc_i2c_write(struct i2c_client *client, u8 *buf, int len);
+static int nfcc_hw_check(struct i2c_client *client, unsigned short curr_addr);
static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr);
static int qca199x_clock_select(struct qca199x_dev *qca199x_dev);
static int qca199x_clock_deselect(struct qca199x_dev *qca199x_dev);
@@ -92,9 +110,10 @@
/*
* FTM-RAW-I2C RD/WR MODE
*/
-static struct devicemode device_mode;
-static int ftm_raw_write_mode;
-static int ftm_werr_code;
+static struct devicemode device_mode;
+static int ftm_raw_write_mode;
+static int ftm_werr_code;
+
static void qca199x_init_stat(struct qca199x_dev *qca199x_dev)
{
@@ -156,6 +175,95 @@
return mask;
}
+/* Handlers for CLK_REQ */
+static void qca199x_disable_irq_clk_req(struct qca199x_dev *qca199x_dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&qca199x_dev->irq_enabled_lock_clk_req, flags);
+ if (qca199x_dev->irq_enabled_clk_req) {
+ disable_irq_nosync(qca199x_dev->clk_req_irq_num);
+ qca199x_dev->irq_enabled_clk_req = false;
+ }
+ spin_unlock_irqrestore(&qca199x_dev->irq_enabled_lock_clk_req, flags);
+}
+
+
+static void qca199x_enable_irq_clk_req(struct qca199x_dev *qca199x_dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&qca199x_dev->irq_enabled_lock_clk_req, flags);
+ if (!qca199x_dev->irq_enabled_clk_req) {
+ qca199x_dev->irq_enabled_clk_req = true;
+ enable_irq(qca199x_dev->clk_req_irq_num);
+ }
+ spin_unlock_irqrestore(&qca199x_dev->irq_enabled_lock_clk_req, flags);
+}
+
+
+static irqreturn_t qca199x_dev_irq_handler_clk_req(int irq, void *dev_id)
+{
+ struct qca199x_dev *qca199x_dev = dev_id;
+ unsigned long flags;
+
+ spin_lock_irqsave(&qca199x_dev->irq_enabled_lock_clk_req, flags);
+ qca199x_dev->count_irq_clk_req++;
+ spin_unlock_irqrestore(&qca199x_dev->irq_enabled_lock_clk_req, flags);
+
+ queue_work(qca199x_dev->my_wq, &qca199x_dev->msm_clock_controll_work);
+
+ return IRQ_HANDLED;
+}
+
+
+static struct gpiomux_setting nfc_clk_on = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+static struct gpiomux_setting nfc_clk_on_suspend = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+static struct gpiomux_setting nfc_clk_off = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static void clk_req_update(struct work_struct *work)
+{
+ struct i2c_client *client;
+ struct qca199x_dev *qca199x_dev;
+ int gpio_clk_req_level = 0;
+
+ qca199x_dev = container_of(work, struct qca199x_dev,
+ msm_clock_controll_work);
+ client = qca199x_dev->client;
+
+ /* Read status level of CLK_REQ from NFC Controller, QCA199_x */
+ gpio_clk_req_level = gpio_get_value(qca199x_dev->irq_gpio_clk_req);
+ if (gpio_clk_req_level == 1) {
+ if (qca199x_dev->clk_run == false) {
+ msm_gpiomux_write(qca199x_dev->clk_src_gpio,
+ GPIOMUX_ACTIVE, &nfc_clk_on, NULL);
+ msm_gpiomux_write(qca199x_dev->clk_src_gpio,
+ GPIOMUX_SUSPENDED, &nfc_clk_on_suspend, NULL);
+ qca199x_dev->clk_run = true;
+ }
+ } else{
+ if (qca199x_dev->clk_run == true) {
+ msm_gpiomux_write(qca199x_dev->clk_src_gpio,
+ GPIOMUX_ACTIVE, &nfc_clk_off, NULL);
+ msm_gpiomux_write(qca199x_dev->clk_src_gpio,
+ GPIOMUX_SUSPENDED, &nfc_clk_off, NULL);
+ qca199x_dev->clk_run = false;
+ }
+ }
+}
+
/*
* ONLY for FTM-RAW-I2C Mode
* Required to instigate a read, which comes from DT layer. This means we need
@@ -396,7 +504,14 @@
filp->private_data = qca199x_dev;
qca199x_init_stat(qca199x_dev);
+ /* Enable interrupts from NFCC NFC_INT new NCI data available */
qca199x_enable_irq(qca199x_dev);
+
+ if ((!strcmp(qca199x_dev->clk_src_name, "GPCLK")) ||
+ (!strcmp(qca199x_dev->clk_src_name, "GPCLK2"))) {
+ /* Enable interrupts from NFCC CLK_REQ */
+ qca199x_enable_irq_clk_req(qca199x_dev);
+ }
dev_dbg(&qca199x_dev->client->dev,
"%d,%d\n", imajor(inode), iminor(inode));
return ret;
@@ -759,6 +874,33 @@
return r;
}
+/* Check for availability of qca199x_ NFC controller hardware */
+static int nfcc_hw_check(struct i2c_client *client, unsigned short curr_addr)
+{
+ int r = 0;
+ unsigned char buf = 0;
+
+ client->addr = curr_addr;
+ /* Set-up Addr 0. No data written */
+ r = i2c_master_send(client, &buf, 1);
+ if (r < 0)
+ goto err_presence_check;
+ buf = 0;
+ /* Read back from Addr 0 */
+ r = i2c_master_recv(client, &buf, 1);
+ if (r < 0)
+ goto err_presence_check;
+
+ r = 0;
+ return r;
+
+err_presence_check:
+ r = -ENXIO;
+ dev_err(&client->dev,
+ "nfc-nci nfcc_presence check - no NFCC available\n");
+ return r;
+}
+/* Initialise qca199x_ NFC controller hardware */
static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr)
{
int r = 0;
@@ -949,6 +1091,14 @@
goto err_invalid_dis_gpio;
}
if (qca199x_dev->clk_run == false) {
+ /* Set clock rate */
+ if ((!strcmp(qca199x_dev->clk_src_name, "GPCLK")) ||
+ (!strcmp(qca199x_dev->clk_src_name, "GPCLK2"))) {
+ r = clk_set_rate(qca199x_dev->s_clk, NFC_RF_CLK_FREQ);
+ if (r)
+ goto err_invalid_clk;
+ }
+
r = clk_prepare_enable(qca199x_dev->s_clk);
if (r)
goto err_invalid_clk;
@@ -990,10 +1140,6 @@
if (r)
return -EINVAL;
- r = of_property_read_u32(np, "qcom,clk-gpio", &pdata->ven_gpio);
- if (r)
- return -EINVAL;
-
pdata->dis_gpio = of_get_named_gpio(np, "qcom,dis-gpio", 0);
if ((!gpio_is_valid(pdata->dis_gpio)))
return -EINVAL;
@@ -1004,11 +1150,24 @@
r = of_property_read_string(np, "qcom,clk-src", &pdata->clk_src_name);
- if ((!strcmp(pdata->clk_src_name, "GPCLK")) ||
- (!strcmp(pdata->clk_src_name, "GPCLK2")))
- pdata->clk_src_gpio = of_get_named_gpio(np,
- "qcom,clk-en-gpio", 0);
+ if (strcmp(pdata->clk_src_name, "GPCLK2")) {
+ r = of_property_read_u32(np, "qcom,clk-gpio",
+ &pdata->clkreq_gpio);
+ if (r)
+ return -EINVAL;
+ }
+ if ((!strcmp(pdata->clk_src_name, "GPCLK")) ||
+ (!strcmp(pdata->clk_src_name, "GPCLK2"))) {
+ pdata->clk_src_gpio = of_get_named_gpio(np,
+ "qcom,clk-src-gpio", 0);
+ if ((!gpio_is_valid(pdata->clk_src_gpio)))
+ return -EINVAL;
+ pdata->irq_gpio_clk_req = of_get_named_gpio(np,
+ "qcom,clk-req-gpio", 0);
+ if ((!gpio_is_valid(pdata->irq_gpio_clk_req)))
+ return -EINVAL;
+ }
if (r)
return -EINVAL;
return r;
@@ -1057,40 +1216,23 @@
return -ENOMEM;
}
qca199x_dev->client = client;
- if (gpio_is_valid(platform_data->irq_gpio)) {
- r = gpio_request(platform_data->irq_gpio, "nfc_irq_gpio");
- if (r) {
- dev_err(&client->dev, "unable to request gpio [%d]\n",
- platform_data->irq_gpio);
- goto err_free_dev;
- }
- r = gpio_direction_input(platform_data->irq_gpio);
- if (r) {
- dev_err(&client->dev,
- "unable to set direction for gpio [%d]\n",
- platform_data->irq_gpio);
- goto err_irq;
- }
- gpio_to_irq(0);
- irqn = gpio_to_irq(platform_data->irq_gpio);
- if (irqn < 0) {
- r = irqn;
- goto err_irq;
- }
- client->irq = irqn;
+ /*
+ * To be efficient we need to test whether nfcc hardware is physically
+ * present before attempting further hardware initialisation.
+ * For this we need to be sure the device is in ULPM state by
+ * setting disable line low early on.
+ *
+ */
- } else {
- dev_err(&client->dev, "irq gpio not provided\n");
- goto err_free_dev;
- }
+
if (gpio_is_valid(platform_data->dis_gpio)) {
r = gpio_request(platform_data->dis_gpio, "nfc_reset_gpio");
if (r) {
dev_err(&client->dev,
"NFC: unable to request gpio [%d]\n",
platform_data->dis_gpio);
- goto err_irq;
+ goto err_free_dev;
}
r = gpio_direction_output(platform_data->dis_gpio, 1);
if (r) {
@@ -1101,7 +1243,75 @@
}
} else {
dev_err(&client->dev, "dis gpio not provided\n");
- goto err_irq;
+ goto err_free_dev;
+ }
+
+ /* Put device in ULPM */
+ gpio_set_value(platform_data->dis_gpio, 0);
+ r = nfcc_hw_check(client, platform_data->reg);
+ if (r) {
+ /* We don't think there is hardware but just in case HPD */
+ gpio_set_value(platform_data->dis_gpio, 1);
+ goto err_dis_gpio;
+ }
+
+ if (gpio_is_valid(platform_data->irq_gpio)) {
+ r = gpio_request(platform_data->irq_gpio, "nfc_irq_gpio");
+ if (r) {
+ dev_err(&client->dev, "unable to request gpio [%d]\n",
+ platform_data->irq_gpio);
+ goto err_dis_gpio;
+ }
+ r = gpio_direction_input(platform_data->irq_gpio);
+ if (r) {
+
+ dev_err(&client->dev,
+ "unable to set direction for gpio [%d]\n",
+ platform_data->irq_gpio);
+ goto err_irq;
+ }
+ irqn = gpio_to_irq(platform_data->irq_gpio);
+ if (irqn < 0) {
+ r = irqn;
+ goto err_irq;
+ }
+ client->irq = irqn;
+
+ } else {
+ dev_err(&client->dev, "irq gpio not provided\n");
+ goto err_dis_gpio;
+ }
+ /* Interrupt from NFCC CLK_REQ to handle REF_CLK
+ o/p gating/selection */
+ if ((!strcmp(platform_data->clk_src_name, "GPCLK")) ||
+ (!strcmp(platform_data->clk_src_name, "GPCLK2"))) {
+ if (gpio_is_valid(platform_data->irq_gpio_clk_req)) {
+ r = gpio_request(platform_data->irq_gpio_clk_req,
+ "nfc_irq_gpio_clk_en");
+ if (r) {
+ dev_err(&client->dev, "unable to request CLK_EN gpio [%d]\n",
+ platform_data->irq_gpio_clk_req);
+ goto err_irq;
+ }
+ r = gpio_direction_input(
+ platform_data->irq_gpio_clk_req);
+ if (r) {
+ dev_err(&client->dev,
+ "unable to set direction for CLK_EN gpio [%d]\n",
+ platform_data->irq_gpio_clk_req);
+ goto err_irq_clk;
+ }
+ gpio_to_irq(0);
+ irqn = gpio_to_irq(platform_data->irq_gpio_clk_req);
+ if (irqn < 0) {
+ r = irqn;
+ goto err_irq_clk;
+ }
+ platform_data->clk_req_irq_num = irqn;
+ } else {
+ dev_err(&client->dev, "irq CLK_EN gpio not provided\n");
+ goto err_irq;
+ }
}
/* Get the clock source name and gpio from from Device Tree */
qca199x_dev->clk_src_name = platform_data->clk_src_name;
@@ -1112,37 +1322,49 @@
if (r == -1)
goto err_clk;
else
- goto err_dis_gpio;
+ goto err_irq_clk;
}
- platform_data->ven_gpio = of_get_named_gpio(node,
- "qcom,clk-gpio", 0);
- if (gpio_is_valid(platform_data->ven_gpio)) {
- r = gpio_request(platform_data->ven_gpio, "nfc_ven_gpio");
- if (r) {
- dev_err(&client->dev, "unable to request gpio [%d]\n",
- platform_data->ven_gpio);
- goto err_ven_gpio;
+ if (strcmp(platform_data->clk_src_name, "GPCLK2")) {
+ platform_data->clkreq_gpio =
+ of_get_named_gpio(node, "qcom,clk-gpio", 0);
+
+ if (gpio_is_valid(platform_data->clkreq_gpio)) {
+ r = gpio_request(platform_data->clkreq_gpio,
+ "nfc_clkreq_gpio");
+ if (r) {
+ dev_err(&client->dev, "unable to request gpio [%d]\n",
+ platform_data->clkreq_gpio);
+ goto err_clkreq_gpio;
+ }
+ r = gpio_direction_input(platform_data->clkreq_gpio);
+ if (r) {
+ dev_err(&client->dev,
+ "unable to set direction for gpio [%d]\n",
+ platform_data->clkreq_gpio);
+ goto err_clkreq_gpio;
+ }
+ } else {
+ dev_err(&client->dev, "clkreq gpio not provided\n");
+ goto err_clk;
}
- r = gpio_direction_input(platform_data->ven_gpio);
- if (r) {
- dev_err(&client->dev,
- "unable to set direction for gpio [%d]\n",
- platform_data->ven_gpio);
- goto err_ven_gpio;
- }
- } else {
- dev_err(&client->dev, "ven gpio not provided\n");
- goto err_clk;
+ qca199x_dev->clkreq_gpio = platform_data->clkreq_gpio;
}
qca199x_dev->dis_gpio = platform_data->dis_gpio;
qca199x_dev->irq_gpio = platform_data->irq_gpio;
- qca199x_dev->ven_gpio = platform_data->ven_gpio;
+ if ((!strcmp(platform_data->clk_src_name, "GPCLK")) ||
+ (!strcmp(platform_data->clk_src_name, "GPCLK2"))) {
+ qca199x_dev->irq_gpio_clk_req =
+ platform_data->irq_gpio_clk_req;
+ qca199x_dev->clk_req_irq_num =
+ platform_data->clk_req_irq_num;
+ }
/* init mutex and queues */
init_waitqueue_head(&qca199x_dev->read_wq);
mutex_init(&qca199x_dev->read_mutex);
spin_lock_init(&qca199x_dev->irq_enabled_lock);
+ spin_lock_init(&qca199x_dev->irq_enabled_lock_clk_req);
qca199x_dev->qca199x_device.minor = MISC_DYNAMIC_MINOR;
qca199x_dev->qca199x_device.name = "nfc-nci";
@@ -1154,6 +1376,27 @@
goto err_misc_register;
}
+
+ /*
+ * Reboot the NFCC now that all resources are ready
+ *
+ * The NFCC takes time to transition between power states.
+ * We wait 20uS for the NFCC to shutdown. (HPD)
+ * We wait 100uS for the NFCC to boot into ULPM.
+ */
+ gpio_set_value(platform_data->dis_gpio, 1);/* HPD */
+ msleep(20);
+ gpio_set_value(platform_data->dis_gpio, 0);/* ULPM */
+ msleep(100);
+
+
+ /* Here we perform a second presence check. */
+ r = nfcc_hw_check(client, platform_data->reg);
+ if (r) {
+ /* We don't think there is hardware but just in case HPD */
+ gpio_set_value(platform_data->dis_gpio, 1);
+ goto err_nfcc_not_present;
+ }
regulators.regulator = regulator_get(&client->dev, regulators.name);
if (IS_ERR(regulators.regulator)) {
r = PTR_ERR(regulators.regulator);
@@ -1172,6 +1415,7 @@
* for reading. It is cleared when all data has been read.
*/
device_mode.handle_flavour = UNSOLICITED_MODE;
+ /* NFC_INT IRQ */
qca199x_dev->irq_enabled = true;
r = request_irq(client->irq, qca199x_dev_irq_handler,
IRQF_TRIGGER_RISING, client->name, qca199x_dev);
@@ -1180,6 +1424,31 @@
goto err_request_irq_failed;
}
qca199x_disable_irq(qca199x_dev);
+ /* CLK_REQ IRQ */
+ if ((!strcmp(platform_data->clk_src_name, "GPCLK")) ||
+ (!strcmp(platform_data->clk_src_name, "GPCLK2"))) {
+ r = request_irq(qca199x_dev->clk_req_irq_num,
+ qca199x_dev_irq_handler_clk_req,
+ (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING),
+ client->name, qca199x_dev);
+ if (r) {
+ dev_err(&client->dev,
+ "nfc-nci probe: request_irq failed. irq no = %d\n, main irq = %d",
+ qca199x_dev->clk_req_irq_num, client->irq);
+ goto err_request_irq_failed;
+ }
+ qca199x_dev->irq_enabled_clk_req = true;
+ qca199x_disable_irq_clk_req(qca199x_dev);
+
+
+ qca199x_dev->my_wq =
+ create_singlethread_workqueue("qca1990x_CLK_REQ_queue");
+ if (!qca199x_dev->my_wq)
+ goto err_create_workq;
+
+ INIT_WORK(&qca199x_dev->msm_clock_controll_work,
+ clk_req_update);
+ }
i2c_set_clientdata(client, qca199x_dev);
gpio_set_value(platform_data->dis_gpio, 1);
dev_dbg(&client->dev,
@@ -1187,28 +1456,33 @@
__func__);
return 0;
+err_create_workq:
+ dev_err(&client->dev,
+ "nfc-nci probe: %s, work_queue creation failure\n",
+ __func__);
+ free_irq(client->irq, qca199x_dev);
+err_nfcc_not_present:
err_request_irq_failed:
misc_deregister(&qca199x_dev->qca199x_device);
err_misc_register:
mutex_destroy(&qca199x_dev->read_mutex);
-err_ven_gpio:
- gpio_free(platform_data->ven_gpio);
+err_clkreq_gpio:
+ if (strcmp(platform_data->clk_src_name, "GPCLK2"))
+ gpio_free(platform_data->clkreq_gpio);
err_clk:
qca199x_clock_deselect(qca199x_dev);
-err_dis_gpio:
- r = gpio_direction_input(platform_data->dis_gpio);
- if (r)
- dev_err(&client->dev, "nfc-nci probe: Unable to set direction\n");
+err_irq_clk:
if ((!strcmp(platform_data->clk_src_name, "GPCLK")) ||
- (!strcmp(platform_data->clk_src_name, "GPCLK2"))) {
- r = gpio_direction_input(platform_data->clk_src_gpio);
+ (!strcmp(platform_data->clk_src_name, "GPCLK2"))) {
+ r = gpio_direction_input(platform_data->irq_gpio_clk_req);
if (r)
dev_err(&client->dev, "nfc-nci probe: Unable to set direction\n");
- gpio_free(platform_data->clk_src_gpio);
+ gpio_free(platform_data->irq_gpio_clk_req);
}
- gpio_free(platform_data->dis_gpio);
err_irq:
gpio_free(platform_data->irq_gpio);
+err_dis_gpio:
+ gpio_free(platform_data->dis_gpio);
err_free_dev:
kfree(qca199x_dev);
return r;
@@ -1223,8 +1497,13 @@
misc_deregister(&qca199x_dev->qca199x_device);
mutex_destroy(&qca199x_dev->read_mutex);
gpio_free(qca199x_dev->irq_gpio);
+ if ((!strcmp(qca199x_dev->clk_src_name, "GPCLK")) ||
+ (!strcmp(qca199x_dev->clk_src_name, "GPCLK2"))) {
+ gpio_free(qca199x_dev->irq_gpio_clk_req);
+ }
gpio_free(qca199x_dev->dis_gpio);
- gpio_free(qca199x_dev->ven_gpio);
+ if (strcmp(qca199x_dev->clk_src_name, "GPCLK2"))
+ gpio_free(qca199x_dev->clkreq_gpio);
kfree(qca199x_dev);
return 0;
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 6cac572..2559ff9 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -407,6 +407,14 @@
}
}
+static void disable_bms_irq_nosync(struct bms_irq *irq)
+{
+ if (!__test_and_set_bit(0, &irq->disabled)) {
+ disable_irq_nosync(irq->irq);
+ pr_debug("disabled irq %d\n", irq->irq);
+ }
+}
+
#define HOLD_OREG_DATA BIT(0)
static int lock_output_data(struct qpnp_bms_chip *chip)
{
@@ -3562,7 +3570,7 @@
struct qpnp_bms_chip *chip = _chip;
pr_debug("sw_cc_thr irq triggered\n");
- disable_bms_irq(&chip->sw_cc_thr_irq);
+ disable_bms_irq_nosync(&chip->sw_cc_thr_irq);
bms_stay_awake(&chip->soc_wake_source);
schedule_work(&chip->recalc_work);
return IRQ_HANDLED;
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 1223fe0..40c5568 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -113,6 +113,7 @@
#define USB_OCP_THR 0x52
#define USB_OCP_CLR 0x53
#define BAT_IF_TEMP_STATUS 0x09
+#define BOOST_ILIM 0x78
#define REG_OFFSET_PERP_SUBTYPE 0x05
@@ -217,6 +218,7 @@
struct qpnp_chg_irq {
int irq;
unsigned long disabled;
+ unsigned long wake_enable;
};
struct qpnp_chg_regulator {
@@ -364,6 +366,7 @@
struct work_struct soc_check_work;
struct delayed_work aicl_check_work;
struct work_struct insertion_ocv_work;
+ struct work_struct ocp_clear_work;
struct qpnp_chg_regulator otg_vreg;
struct qpnp_chg_regulator boost_vreg;
struct qpnp_chg_regulator batfet_vreg;
@@ -531,6 +534,24 @@
}
}
+static void
+qpnp_chg_irq_wake_enable(struct qpnp_chg_irq *irq)
+{
+ if (!__test_and_set_bit(0, &irq->wake_enable)) {
+ pr_debug("number = %d\n", irq->irq);
+ enable_irq_wake(irq->irq);
+ }
+}
+
+static void
+qpnp_chg_irq_wake_disable(struct qpnp_chg_irq *irq)
+{
+ if (__test_and_clear_bit(0, &irq->wake_enable)) {
+ pr_debug("number = %d\n", irq->irq);
+ disable_irq_wake(irq->irq);
+ }
+}
+
#define USB_OTG_EN_BIT BIT(0)
static int
qpnp_chg_is_otg_en_set(struct qpnp_chg_chip *chip)
@@ -1215,10 +1236,36 @@
qpnp_chg_usb_usb_ocp_irq_handler(int irq, void *_chip)
{
struct qpnp_chg_chip *chip = _chip;
- int rc;
pr_debug("usb-ocp triggered\n");
+ schedule_work(&chip->ocp_clear_work);
+
+ return IRQ_HANDLED;
+}
+
+#define BOOST_ILIMIT_MIN 0x07
+#define BOOST_ILIMIT_DEF 0x02
+#define BOOST_ILIMT_MASK 0xFF
+static void
+qpnp_chg_ocp_clear_work(struct work_struct *work)
+{
+ int rc;
+ u8 usb_sts;
+ struct qpnp_chg_chip *chip = container_of(work,
+ struct qpnp_chg_chip, ocp_clear_work);
+
+ if (chip->type == SMBBP) {
+ rc = qpnp_chg_masked_write(chip,
+ chip->boost_base + BOOST_ILIM,
+ BOOST_ILIMT_MASK,
+ BOOST_ILIMIT_MIN, 1);
+ if (rc) {
+ pr_err("Failed to turn configure ilim rc = %d\n", rc);
+ return;
+ }
+ }
+
rc = qpnp_chg_masked_write(chip,
chip->usb_chgpth_base + USB_OCP_CLR,
OCP_CLR_BIT,
@@ -1234,7 +1281,29 @@
if (rc)
pr_err("Failed to turn off usb ovp rc = %d\n", rc);
- return IRQ_HANDLED;
+ if (chip->type == SMBBP) {
+ /* Wait for OCP circuitry to be powered up */
+ msleep(100);
+ rc = qpnp_chg_read(chip, &usb_sts,
+ INT_RT_STS(chip->usb_chgpth_base), 1);
+ if (rc) {
+ pr_err("failed to read interrupt sts %d\n", rc);
+ return;
+ }
+
+ if (usb_sts & COARSE_DET_USB_IRQ) {
+ rc = qpnp_chg_masked_write(chip,
+ chip->boost_base + BOOST_ILIM,
+ BOOST_ILIMT_MASK,
+ BOOST_ILIMIT_DEF, 1);
+ if (rc) {
+ pr_err("Failed to set ilim rc = %d\n", rc);
+ return;
+ }
+ } else {
+ pr_warn_ratelimited("USB short to GND detected!\n");
+ }
+ }
}
#define QPNP_CHG_VDDMAX_MIN 3400
@@ -1678,6 +1747,8 @@
u8 chgr_sts;
int rc;
+ qpnp_chg_irq_wake_disable(&chip->chg_fastchg);
+
rc = qpnp_chg_read(chip, &chgr_sts, INT_RT_STS(chip->chgr_base), 1);
if (rc)
pr_err("failed to read interrupt sts %d\n", rc);
@@ -1781,6 +1852,17 @@
if (!qpnp_chg_is_otg_en_set(chip))
return 0;
+ if (chip->type == SMBBP) {
+ rc = qpnp_chg_masked_write(chip,
+ chip->boost_base + BOOST_ILIM,
+ BOOST_ILIMT_MASK,
+ BOOST_ILIMIT_DEF, 1);
+ if (rc) {
+ pr_err("Failed to set ilim rc = %d\n", rc);
+ return rc;
+ }
+ }
+
/* enable usb ovp fet */
rc = qpnp_chg_masked_write(chip,
chip->usb_chgpth_base + CHGR_USB_USB_OTG_CTL,
@@ -1804,11 +1886,23 @@
switch_usb_to_host_mode(struct qpnp_chg_chip *chip)
{
int rc;
+ u8 usb_sts;
pr_debug("switch to host mode\n");
if (qpnp_chg_is_otg_en_set(chip))
return 0;
+ if (chip->type == SMBBP) {
+ rc = qpnp_chg_masked_write(chip,
+ chip->boost_base + BOOST_ILIM,
+ BOOST_ILIMT_MASK,
+ BOOST_ILIMIT_MIN, 1);
+ if (rc) {
+ pr_err("Failed to turn configure ilim rc = %d\n", rc);
+ return rc;
+ }
+ }
+
if (!qpnp_chg_is_dc_chg_plugged_in(chip)) {
rc = qpnp_chg_force_run_on_batt(chip, 1);
if (rc) {
@@ -1827,6 +1921,30 @@
return rc;
}
+ if (chip->type == SMBBP) {
+ /* Wait for OCP circuitry to be powered up */
+ msleep(100);
+ rc = qpnp_chg_read(chip, &usb_sts,
+ INT_RT_STS(chip->usb_chgpth_base), 1);
+ if (rc) {
+ pr_err("failed to read interrupt sts %d\n", rc);
+ return rc;
+ }
+
+ if (usb_sts & COARSE_DET_USB_IRQ) {
+ rc = qpnp_chg_masked_write(chip,
+ chip->boost_base + BOOST_ILIM,
+ BOOST_ILIMT_MASK,
+ BOOST_ILIMIT_DEF, 1);
+ if (rc) {
+ pr_err("Failed to set ilim rc = %d\n", rc);
+ return rc;
+ }
+ } else {
+ pr_warn_ratelimited("USB short to GND detected!\n");
+ }
+ }
+
return 0;
}
@@ -2148,6 +2266,7 @@
&& soc <= chip->soc_resume_limit) {
pr_debug("resuming charging at %d%% soc\n", soc);
chip->resuming_charging = true;
+ qpnp_chg_irq_wake_enable(&chip->chg_fastchg);
qpnp_chg_set_appropriate_vbatdet(chip);
qpnp_chg_charge_en(chip, !chip->charging_disabled);
}
@@ -3848,10 +3967,10 @@
return rc;
}
- enable_irq_wake(chip->chg_trklchg.irq);
- enable_irq_wake(chip->chg_failed.irq);
+ qpnp_chg_irq_wake_enable(&chip->chg_trklchg);
+ qpnp_chg_irq_wake_enable(&chip->chg_failed);
qpnp_chg_disable_irq(&chip->chg_vbatdet_lo);
- enable_irq_wake(chip->chg_vbatdet_lo.irq);
+ qpnp_chg_irq_wake_enable(&chip->chg_vbatdet_lo);
break;
case SMBB_BAT_IF_SUBTYPE:
@@ -3874,7 +3993,7 @@
return rc;
}
- enable_irq_wake(chip->batt_pres.irq);
+ qpnp_chg_irq_wake_enable(&chip->batt_pres);
chip->batt_temp_ok.irq = spmi_get_irq_byname(spmi,
spmi_resource, "bat-temp-ok");
@@ -3893,7 +4012,7 @@
}
qpnp_chg_bat_if_batt_temp_irq_handler(0, chip);
- enable_irq_wake(chip->batt_temp_ok.irq);
+ qpnp_chg_irq_wake_enable(&chip->batt_temp_ok);
break;
case SMBB_BUCK_SUBTYPE:
@@ -3975,11 +4094,11 @@
return rc;
}
- enable_irq_wake(chip->usb_ocp.irq);
+ qpnp_chg_irq_wake_enable(&chip->usb_ocp);
}
- enable_irq_wake(chip->usbin_valid.irq);
- enable_irq_wake(chip->chg_gone.irq);
+ qpnp_chg_irq_wake_enable(&chip->usbin_valid);
+ qpnp_chg_irq_wake_enable(&chip->chg_gone);
break;
case SMBB_DC_CHGPTH_SUBTYPE:
chip->dcin_valid.irq = spmi_get_irq_byname(spmi,
@@ -3998,7 +4117,7 @@
return rc;
}
- enable_irq_wake(chip->dcin_valid.irq);
+ qpnp_chg_irq_wake_enable(&chip->dcin_valid);
break;
}
}
@@ -4527,6 +4646,8 @@
INIT_WORK(&chip->reduce_power_stage_work,
qpnp_chg_reduce_power_stage_work);
mutex_init(&chip->batfet_vreg_lock);
+ INIT_WORK(&chip->ocp_clear_work,
+ qpnp_chg_ocp_clear_work);
INIT_WORK(&chip->batfet_lcl_work,
qpnp_chg_batfet_lcl_work);
INIT_WORK(&chip->insertion_ocv_work,
diff --git a/drivers/usb/gadget/f_mbim.c b/drivers/usb/gadget/f_mbim.c
index 15f20ca..88a7bde 100644
--- a/drivers/usb/gadget/f_mbim.c
+++ b/drivers/usb/gadget/f_mbim.c
@@ -1710,8 +1710,10 @@
return -EIO;
}
+ spin_lock(&dev->lock);
while (list_empty(&dev->cpkt_req_q)) {
pr_debug("Requests list is empty. Wait.\n");
+ spin_unlock(&dev->lock);
ret = wait_event_interruptible(dev->read_wq,
!list_empty(&dev->cpkt_req_q));
if (ret < 0) {
@@ -1720,11 +1722,13 @@
return -ERESTARTSYS;
}
pr_debug("Received request packet\n");
+ spin_lock(&dev->lock);
}
cpkt = list_first_entry(&dev->cpkt_req_q, struct ctrl_pkt,
list);
if (cpkt->len > count) {
+ spin_unlock(&dev->lock);
mbim_unlock(&dev->read_excl);
pr_err("cpkt size too big:%d > buf size:%d\n",
cpkt->len, count);
@@ -1734,6 +1738,7 @@
pr_debug("cpkt size:%d\n", cpkt->len);
list_del(&cpkt->list);
+ spin_unlock(&dev->lock);
mbim_unlock(&dev->read_excl);
ret = copy_to_user(buf, cpkt->buf, cpkt->len);
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 8c2ac09..ada1281 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -119,6 +119,7 @@
u8 has_wfd_blk;
u8 has_wb_ad;
+ u32 rotator_ot_limit;
u32 mdp_irq_mask;
u32 mdp_hist_irq_mask;
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index bc9a2a9..088472f 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -2109,6 +2109,10 @@
&data);
mdata->rot_block_size = (!rc ? data : 128);
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "qcom,mdss-rotator-ot-limit", &data);
+ mdata->rotator_ot_limit = (!rc ? data : 0);
+
mdata->has_bwc = of_property_read_bool(pdev->dev.of_node,
"qcom,mdss-has-bwc");
mdata->has_decimation = of_property_read_bool(pdev->dev.of_node,
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
index ff55c57..27a7707 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
@@ -17,6 +17,9 @@
#include "mdss_mdp_rotator.h"
#include "mdss_panel.h"
+#define VBIF_WR_LIM_CONF 0xC0
+#define MDSS_DEFAULT_OT_SETTING 0x10
+
enum mdss_mdp_writeback_type {
MDSS_MDP_WRITEBACK_TYPE_ROTATOR,
MDSS_MDP_WRITEBACK_TYPE_LINE,
@@ -34,6 +37,9 @@
u32 intr_type;
u32 intf_num;
+ u32 xin_id;
+ u32 wr_lim;
+
u32 opmode;
struct mdss_mdp_format_params *dst_fmt;
u16 width;
@@ -55,26 +61,31 @@
.type = MDSS_MDP_WRITEBACK_TYPE_ROTATOR,
.intr_type = MDSS_MDP_IRQ_WB_ROT_COMP,
.intf_num = 0,
+ .xin_id = 3,
},
{
.type = MDSS_MDP_WRITEBACK_TYPE_ROTATOR,
.intr_type = MDSS_MDP_IRQ_WB_ROT_COMP,
.intf_num = 1,
+ .xin_id = 11,
},
{
.type = MDSS_MDP_WRITEBACK_TYPE_LINE,
.intr_type = MDSS_MDP_IRQ_WB_ROT_COMP,
.intf_num = 0,
+ .xin_id = 3,
},
{
.type = MDSS_MDP_WRITEBACK_TYPE_LINE,
.intr_type = MDSS_MDP_IRQ_WB_ROT_COMP,
.intf_num = 1,
+ .xin_id = 11,
},
{
.type = MDSS_MDP_WRITEBACK_TYPE_WFD,
.intr_type = MDSS_MDP_IRQ_WB_WFD,
.intf_num = 0,
+ .xin_id = 6,
},
};
@@ -438,9 +449,12 @@
{
struct mdss_mdp_writeback_ctx *ctx;
struct mdss_mdp_writeback_arg *wb_args;
- u32 flush_bits;
+ u32 flush_bits, val, off;
int ret;
+ if (!ctl || !ctl->mdata)
+ return -ENODEV;
+
ctx = (struct mdss_mdp_writeback_ctx *) ctl->priv_data;
if (!ctx)
return -ENODEV;
@@ -451,6 +465,18 @@
return -EPERM;
}
+ if (ctl->mdata->rotator_ot_limit) {
+ if (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR)
+ ctx->wr_lim = ctl->mdata->rotator_ot_limit;
+ else
+ ctx->wr_lim = MDSS_DEFAULT_OT_SETTING;
+ off = (ctx->xin_id % 4) * 8;
+ val = readl_relaxed(ctl->mdata->vbif_base + VBIF_WR_LIM_CONF);
+ val &= ~(0xFF << off);
+ val |= (ctx->wr_lim) << off;
+ writel_relaxed(val, ctl->mdata->vbif_base + VBIF_WR_LIM_CONF);
+ }
+
wb_args = (struct mdss_mdp_writeback_arg *) arg;
if (!wb_args)
return -ENOENT;
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index d525e84..f78d418 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -119,10 +119,10 @@
/* This needs to be modified manually now, when we add
a new RANGE of SSIDs to the msg_mask_tbl */
#define MSG_MASK_TBL_CNT 24
-#define EVENT_LAST_ID 0x09CB
+#define EVENT_LAST_ID 0x09F6
#define MSG_SSID_0 0
-#define MSG_SSID_0_LAST 97
+#define MSG_SSID_0_LAST 101
#define MSG_SSID_1 500
#define MSG_SSID_1_LAST 506
#define MSG_SSID_2 1000
@@ -138,7 +138,7 @@
#define MSG_SSID_7 4600
#define MSG_SSID_7_LAST 4614
#define MSG_SSID_8 5000
-#define MSG_SSID_8_LAST 5030
+#define MSG_SSID_8_LAST 5031
#define MSG_SSID_9 5500
#define MSG_SSID_9_LAST 5516
#define MSG_SSID_10 6000
@@ -154,7 +154,7 @@
#define MSG_SSID_15 8000
#define MSG_SSID_15_LAST 8000
#define MSG_SSID_16 8500
-#define MSG_SSID_16_LAST 8523
+#define MSG_SSID_16_LAST 8524
#define MSG_SSID_17 9000
#define MSG_SSID_17_LAST 9008
#define MSG_SSID_18 9500
@@ -166,7 +166,7 @@
#define MSG_SSID_21 10300
#define MSG_SSID_21_LAST 10300
#define MSG_SSID_22 10350
-#define MSG_SSID_22_LAST 10374
+#define MSG_SSID_22_LAST 10377
#define MSG_SSID_23 0xC000
#define MSG_SSID_23_LAST 0xC063
@@ -182,6 +182,7 @@
MSG_LVL_LOW,
MSG_LVL_ERROR,
MSG_LVL_LOW,
+ MSG_LVL_LOW,
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_HIGH,
@@ -280,7 +281,7 @@
MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
- MSG_LVL_MED,
+ MSG_LVL_LOW,
MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
MSG_LVL_LOW,
MSG_LVL_MED,
@@ -292,6 +293,10 @@
MSG_LVL_LOW,
MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
MSG_LVL_MED,
+ MSG_LVL_HIGH,
+ MSG_LVL_LOW,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH
};
static const uint32_t msg_bld_masks_1[] = {
@@ -321,7 +326,8 @@
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
- MSG_LVL_MED,
+ MSG_LVL_MED|MSG_MASK_5|MSG_MASK_6|MSG_MASK_7|
+ MSG_MASK_8|MSG_MASK_9|MSG_MASK_10,
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED
@@ -439,6 +445,7 @@
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
+ MSG_LVL_MED,
MSG_LVL_MED
};
@@ -632,6 +639,7 @@
MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_LOW,
+ MSG_LVL_LOW,
};
static const uint32_t msg_bld_masks_17[] = {
@@ -722,13 +730,16 @@
MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
MSG_LVL_LOW
};
/* LOG CODES */
static const uint32_t log_code_last_tbl[] = {
0x0, /* EQUIP ID 0 */
- 0x182F, /* EQUIP ID 1 */
+ 0x184A, /* EQUIP ID 1 */
0x0, /* EQUIP ID 2 */
0x0, /* EQUIP ID 3 */
0x4910, /* EQUIP ID 4 */
diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h
index dcc2353..4ce3db1 100644
--- a/include/linux/msm_vidc_enc.h
+++ b/include/linux/msm_vidc_enc.h
@@ -59,6 +59,7 @@
#define VEN_EXTRADATA_QCOMFILLER 0x002
#define VEN_EXTRADATA_SLICEINFO 0x100
#define VEN_EXTRADATA_LTRINFO 0x200
+#define VEN_EXTRADATA_MBINFO 0x400
/*ENCODER CONFIGURATION CONSTANTS*/
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 51ca67d..81d5b9c 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1841,7 +1841,11 @@
V4L2_MPEG_VIDC_INDEX_EXTRADATA_INPUT_CROP,
V4L2_MPEG_VIDC_INDEX_EXTRADATA_DIGITAL_ZOOM,
V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO,
- V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP
+ V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP,
+ V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP,
+ V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO,
+ V4L2_MPEG_VIDC_EXTRADATA_LTR,
+ V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI,
};
#define V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL (V4L2_CID_MPEG_MSM_VIDC_BASE + 26)
@@ -1909,6 +1913,27 @@
#define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR \
(V4L2_CID_MPEG_MSM_VIDC_BASE + 38)
+#define V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 39)
+
+enum v4l2_mpeg_vidc_video_ltrmode {
+ V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE = 0,
+ V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL = 1,
+ V4L2_MPEG_VIDC_VIDEO_LTR_MODE_PERIODIC = 2
+};
+
+#define V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 40)
+
+#define V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 41)
+
+#define V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 42)
+
+#define V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 43)
+
/* Camera class control IDs */
#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900)
#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1)
diff --git a/include/media/msm_vidc.h b/include/media/msm_vidc.h
index 81db11a..9028b1a 100644
--- a/include/media/msm_vidc.h
+++ b/include/media/msm_vidc.h
@@ -60,6 +60,7 @@
int msm_vidc_s_fmt(void *instance, struct v4l2_format *f);
int msm_vidc_g_fmt(void *instance, struct v4l2_format *f);
int msm_vidc_s_ctrl(void *instance, struct v4l2_control *a);
+int msm_vidc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *a);
int msm_vidc_g_ctrl(void *instance, struct v4l2_control *a);
int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b);
int msm_vidc_prepare_buf(void *instance, struct v4l2_buffer *b);
@@ -95,6 +96,16 @@
int *domain_num, int *partition_num);
void *msm_vidc_smem_get_client(void *instance);
#endif
+
+struct msm_vidc_extradata_header {
+ unsigned int size;
+ unsigned int:32; /** Keeping binary compatibility */
+ unsigned int:32; /* with firmware and OpenMAX IL **/
+ unsigned int type; /* msm_vidc_extradata_type */
+ unsigned int data_size;
+ unsigned char data[1];
+};
+
struct msm_vidc_interlace_payload {
unsigned int format;
};
@@ -160,6 +171,13 @@
unsigned int fpa_repetition_period;
unsigned int fpa_extension_flag;
};
+struct msm_vidc_frame_qp_payload {
+ unsigned int frame_qp;
+};
+struct msm_vidc_frame_bits_info_payload {
+ unsigned int frame_bits;
+ unsigned int header_bits;
+};
enum msm_vidc_extradata_type {
EXTRADATA_NONE = 0x00000000,
@@ -173,11 +191,15 @@
EXTRADATA_PANSCAN_WINDOW = 0x00000008,
EXTRADATA_RECOVERY_POINT_SEI = 0x00000009,
EXTRADATA_MPEG2_SEQDISP = 0x0000000D,
+ EXTRADATA_FRAME_QP = 0x0000000F,
+ EXTRADATA_FRAME_BITS_INFO = 0x00000010,
EXTRADATA_MULTISLICE_INFO = 0x7F100000,
EXTRADATA_NUM_CONCEALED_MB = 0x7F100001,
EXTRADATA_INDEX = 0x7F100002,
EXTRADATA_ASPECT_RATIO = 0x7F100003,
EXTRADATA_METADATA_FILLER = 0x7FE00002,
+ MSM_VIDC_EXTRADATA_METADATA_LTR = 0x7F100004,
+ EXTRADATA_METADATA_MBI = 0x7F100005,
};
enum msm_vidc_interlace_type {
INTERLACE_FRAME_PROGRESSIVE = 0x01,
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index a5e8dc2..d012c75 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -190,6 +190,18 @@
zone_reclaimable_pages(z) - z->dirty_balance_reserve;
}
/*
+ * Unreclaimable memory (kernel memory or anonymous memory
+ * without swap) can bring down the dirtyable pages below
+ * the zone's dirty balance reserve and the above calculation
+ * will underflow. However we still want to add in nodes
+ * which are below threshold (negative values) to get a more
+ * accurate calculation but make sure that the total never
+ * underflows.
+ */
+ if ((long)x < 0)
+ x = 0;
+
+ /*
* Make sure that the number of highmem pages is never larger
* than the number of the total dirtyable memory. This can only
* occur in very strange VM situations but we want to make sure
@@ -211,8 +223,8 @@
{
unsigned long x;
- x = global_page_state(NR_FREE_PAGES) + global_reclaimable_pages() -
- dirty_balance_reserve;
+ x = global_page_state(NR_FREE_PAGES) + global_reclaimable_pages();
+ x -= min(x, dirty_balance_reserve);
if (!vm_highmem_is_dirtyable)
x -= highmem_dirtyable_memory(x);
@@ -279,9 +291,12 @@
* highmem zone can hold its share of dirty pages, so we don't
* care about vm_highmem_is_dirtyable here.
*/
- return zone_page_state(zone, NR_FREE_PAGES) +
- zone_reclaimable_pages(zone) -
- zone->dirty_balance_reserve;
+ unsigned long nr_pages = zone_page_state(zone, NR_FREE_PAGES) +
+ zone_reclaimable_pages(zone);
+
+ /* don't allow this to underflow */
+ nr_pages -= min(nr_pages, zone->dirty_balance_reserve);
+ return nr_pages;
}
/**
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index 32ca0c6..f37b86c 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -2906,16 +2906,15 @@
if (wcd9xxx_cancel_btn_work(mbhc))
pr_debug("%s: button press is canceled\n", __func__);
- /* cancel detect plug */
- wcd9xxx_cancel_hs_detect_plug(mbhc,
- &mbhc->correct_plug_swch);
-
insert = !wcd9xxx_swch_level_remove(mbhc);
pr_debug("%s: Current plug type %d, insert %d\n", __func__,
mbhc->current_plug, insert);
if ((mbhc->current_plug == PLUG_TYPE_NONE) && insert) {
mbhc->lpi_enabled = false;
wmb();
+ /* cancel detect plug */
+ wcd9xxx_cancel_hs_detect_plug(mbhc,
+ &mbhc->correct_plug_swch);
if ((mbhc->current_plug != PLUG_TYPE_NONE) &&
!(snd_soc_read(codec, WCD9XXX_A_MBHC_INSERT_DETECT) &
@@ -2930,6 +2929,9 @@
} else if ((mbhc->current_plug != PLUG_TYPE_NONE) && !insert) {
mbhc->lpi_enabled = false;
wmb();
+ /* cancel detect plug */
+ wcd9xxx_cancel_hs_detect_plug(mbhc,
+ &mbhc->correct_plug_swch);
if (mbhc->current_plug == PLUG_TYPE_HEADPHONE) {
wcd9xxx_report_plug(mbhc, 0, SND_JACK_HEADPHONE);
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 54b1263..3e30290 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -93,6 +93,11 @@
sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
sizeof(struct srs_trumedia_params_GLOBAL);
adm_params = kzalloc(sz, GFP_KERNEL);
+ if (!adm_params) {
+ pr_err("%s, adm params memory alloc failed\n",
+ __func__);
+ return -ENOMEM;
+ }
adm_params->payload_size =
sizeof(struct srs_trumedia_params_GLOBAL) +
sizeof(struct adm_param_data_v5);
@@ -117,6 +122,11 @@
sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
sizeof(struct srs_trumedia_params_WOWHD);
adm_params = kzalloc(sz, GFP_KERNEL);
+ if (!adm_params) {
+ pr_err("%s, adm params memory alloc failed\n",
+ __func__);
+ return -ENOMEM;
+ }
adm_params->payload_size =
sizeof(struct srs_trumedia_params_WOWHD) +
sizeof(struct adm_param_data_v5);
@@ -142,6 +152,11 @@
sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
sizeof(struct srs_trumedia_params_CSHP);
adm_params = kzalloc(sz, GFP_KERNEL);
+ if (!adm_params) {
+ pr_err("%s, adm params memory alloc failed\n",
+ __func__);
+ return -ENOMEM;
+ }
adm_params->payload_size =
sizeof(struct srs_trumedia_params_CSHP) +
sizeof(struct adm_param_data_v5);
@@ -166,6 +181,11 @@
sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
sizeof(struct srs_trumedia_params_HPF);
adm_params = kzalloc(sz, GFP_KERNEL);
+ if (!adm_params) {
+ pr_err("%s, adm params memory alloc failed\n",
+ __func__);
+ return -ENOMEM;
+ }
adm_params->payload_size =
sizeof(struct srs_trumedia_params_HPF) +
sizeof(struct adm_param_data_v5);
@@ -186,6 +206,11 @@
sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
sizeof(struct srs_trumedia_params_PEQ);
adm_params = kzalloc(sz, GFP_KERNEL);
+ if (!adm_params) {
+ pr_err("%s, adm params memory alloc failed\n",
+ __func__);
+ return -ENOMEM;
+ }
adm_params->payload_size =
sizeof(struct srs_trumedia_params_PEQ) +
sizeof(struct adm_param_data_v5);
@@ -208,6 +233,11 @@
sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
sizeof(struct srs_trumedia_params_HL);
adm_params = kzalloc(sz, GFP_KERNEL);
+ if (!adm_params) {
+ pr_err("%s, adm params memory alloc failed\n",
+ __func__);
+ return -ENOMEM;
+ }
adm_params->payload_size =
sizeof(struct srs_trumedia_params_HL) +
sizeof(struct adm_param_data_v5);
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 0970a83..4792719 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -475,7 +475,6 @@
struct snd_soc_pcm_runtime *fe = cstream->private_data;
struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream;
struct snd_soc_platform *platform = fe->platform;
- struct snd_pcm_hw_params *hw_params;
int ret = 0, stream;
if (cstream->direction == SND_COMPRESS_PLAYBACK)
@@ -483,10 +482,6 @@
else
stream = SNDRV_PCM_STREAM_CAPTURE;
- hw_params = kzalloc(sizeof(*hw_params), GFP_KERNEL);
- if (hw_params == NULL)
- return -ENOMEM;
-
mutex_lock(&fe->card->dpcm_mutex);
/* first we call set_params for the platform driver
* this should configure the soc side