summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/pinctrl/qcom,msm8998-pinctrl.txt201
-rw-r--r--drivers/clk/msm/clock-local2.c4
-rw-r--r--drivers/clk/msm/mdss/mdss-dsi-pll-8998.c399
-rw-r--r--drivers/esoc/esoc-mdm-4x.c6
-rw-r--r--drivers/gpu/msm/kgsl_pwrscale.c10
-rw-r--r--drivers/media/platform/msm/ais/pproc/cpp/msm_cpp.c21
-rw-r--r--drivers/media/platform/msm/ais/sensor/flash/msm_flash.c7
-rw-r--r--drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c40
-rw-r--r--drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c4
-rw-r--r--drivers/net/wireless/ath/wil6210/sysfs.c3
-rw-r--r--drivers/net/wireless/cnss2/pci.c4
-rw-r--r--drivers/power/supply/qcom/smb138x-charger.c7
-rw-r--r--drivers/soc/qcom/watchdog_v2.c11
-rw-r--r--drivers/usb/dwc3/core.h3
-rw-r--r--drivers/usb/dwc3/gadget.c50
-rw-r--r--drivers/usb/gadget/composite.c3
-rw-r--r--drivers/usb/pd/policy_engine.c2
-rw-r--r--drivers/video/fbdev/msm/mdss_dba_utils.c3
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c16
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c12
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_edid.c33
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_edid.h6
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_tx.c14
-rw-r--r--fs/Kconfig5
-rw-r--r--fs/file_table.c137
-rw-r--r--fs/internal.h26
-rw-r--r--fs/namei.c2
-rw-r--r--fs/namespace.c2
-rw-r--r--include/dt-bindings/clock/msm-clocks-8998.h10
-rw-r--r--include/linux/fs.h4
-rw-r--r--sound/soc/msm/apq8096-auto.c17
-rw-r--r--sound/soc/msm/msm-dai-fe.c14
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c175
-rw-r--r--sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c14
34 files changed, 1058 insertions, 207 deletions
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8998-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8998-pinctrl.txt
new file mode 100644
index 000000000000..8a9514153172
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8998-pinctrl.txt
@@ -0,0 +1,201 @@
+Qualcomm Technologies, Inc. MSM8998 TLMM block
+
+This binding describes the Top Level Mode Multiplexer block found in the
+MSM8998 platform. With new GPIOs tiling, GPIO pins are
+grouped into various cores - NORTH, WEST, EAST. TLMM_GPIO_ID_STATUSn
+register's value for a GPIO pin decides the core location for it.
+
+- compatible:
+ Usage: required
+ Value type: <string>
+ Definition: must be "qcom,msm8998-pinctrl"
+
+- reg:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: the base address and size of the TLMM register space.
+
+- interrupts:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: should specify the TLMM summary IRQ.
+
+- interrupt-controller:
+ Usage: required
+ Value type: <none>
+ Definition: identifies this node as an interrupt controller
+
+- #interrupt-cells:
+ Usage: required
+ Value type: <u32>
+ Definition: must be 2. Specifying the pin number and flags, as defined
+ in <dt-bindings/interrupt-controller/irq.h>
+
+- gpio-controller:
+ Usage: required
+ Value type: <none>
+ Definition: identifies this node as a gpio controller
+
+- #gpio-cells:
+ Usage: required
+ Value type: <u32>
+ Definition: must be 2. Specifying the pin number and flags, as defined
+ in <dt-bindings/gpio/gpio.h>
+
+Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
+a general description of GPIO and interrupt bindings.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+The pin configuration nodes act as a container for an arbitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those pin(s)/group(s), and various pin configuration
+parameters, such as pull-up, drive strength, etc.
+
+
+PIN CONFIGURATION NODES:
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+
+The following generic properties as defined in pinctrl-bindings.txt are valid
+to specify in a pin configuration subnode:
+
+- pins:
+ Usage: required
+ Value type: <string-array>
+ Definition: List of gpio pins affected by the properties specified in
+ this subnode. Valid pins are:
+ gpio0-gpio149,
+ sdc1_clk,
+ sdc1_cmd,
+ sdc1_data
+ sdc2_clk,
+ sdc2_cmd,
+ sdc2_data
+ sdc1_rclk,
+
+- function:
+ Usage: required
+ Value type: <string>
+ Definition: Specify the alternative function to be configured for the
+ specified pins. Functions are only valid for gpio pins.
+ Valid values are:
+
+ blsp_uart1, blsp_spi1, blsp_i2c1, blsp_uim1, atest_tsens,
+ bimc_dte1, dac_calib0, blsp_spi8, blsp_uart8, blsp_uim8,
+ qdss_cti_trig_out_b, bimc_dte0, dac_calib1, qdss_cti_trig_in_b,
+ dac_calib2, atest_tsens2, atest_usb1, blsp_spi10, blsp_uart10,
+ blsp_uim10, atest_bbrx1, atest_usb13, atest_bbrx0, atest_usb12,
+ mdp_vsync, edp_lcd, blsp_i2c10, atest_gpsadc1, atest_usb11,
+ atest_gpsadc0, edp_hot, atest_usb10, m_voc, dac_gpio, atest_char,
+ cam_mclk, pll_bypassnl, qdss_stm7, blsp_i2c8, qdss_tracedata_b,
+ pll_reset, qdss_stm6, qdss_stm5, qdss_stm4, atest_usb2, cci_i2c,
+ qdss_stm3, dac_calib3, atest_usb23, atest_char3, dac_calib4,
+ qdss_stm2, atest_usb22, atest_char2, qdss_stm1, dac_calib5,
+ atest_usb21, atest_char1, dbg_out, qdss_stm0, dac_calib6,
+ atest_usb20, atest_char0, dac_calib10, qdss_stm10,
+ qdss_cti_trig_in_a, cci_timer4, blsp_spi6, blsp_uart6, blsp_uim6,
+ blsp2_spi, qdss_stm9, qdss_cti_trig_out_a, dac_calib11,
+ qdss_stm8, cci_timer0, qdss_stm13, dac_calib7, cci_timer1,
+ qdss_stm12, dac_calib8, cci_timer2, blsp1_spi, qdss_stm11,
+ dac_calib9, cci_timer3, cci_async, dac_calib12, blsp_i2c6,
+ qdss_tracectl_a, dac_calib13, qdss_traceclk_a, dac_calib14,
+ dac_calib15, hdmi_rcv, dac_calib16, hdmi_cec, pwr_modem,
+ dac_calib17, hdmi_ddc, pwr_nav, dac_calib18, pwr_crypto,
+ dac_calib19, hdmi_hot, dac_calib20, dac_calib21, pci_e0,
+ dac_calib22, dac_calib23, dac_calib24, tsif1_sync, dac_calib25,
+ sd_write, tsif1_error, blsp_spi2, blsp_uart2, blsp_uim2,
+ qdss_cti, blsp_i2c2, blsp_spi3, blsp_uart3, blsp_uim3, blsp_i2c3,
+ uim3, blsp_spi9, blsp_uart9, blsp_uim9, blsp10_spi, blsp_i2c9,
+ blsp_spi7, blsp_uart7, blsp_uim7, qdss_tracedata_a, blsp_i2c7,
+ qua_mi2s, gcc_gp1_clk_a, ssc_irq, uim4, blsp_spi11, blsp_uart11,
+ blsp_uim11, gcc_gp2_clk_a, gcc_gp3_clk_a, blsp_i2c11, cri_trng0,
+ cri_trng1, cri_trng, qdss_stm18, pri_mi2s, qdss_stm17, blsp_spi4,
+ blsp_uart4, blsp_uim4, qdss_stm16, qdss_stm15, blsp_i2c4,
+ qdss_stm14, dac_calib26, spkr_i2s, audio_ref, lpass_slimbus,
+ isense_dbg, tsense_pwm1, tsense_pwm2, btfm_slimbus, ter_mi2s,
+ qdss_stm22, qdss_stm21, qdss_stm20, qdss_stm19, gcc_gp1_clk_b,
+ sec_mi2s, blsp_spi5, blsp_uart5, blsp_uim5, gcc_gp2_clk_b,
+ gcc_gp3_clk_b, blsp_i2c5, blsp_spi12, blsp_uart12, blsp_uim12,
+ qdss_stm25, qdss_stm31, blsp_i2c12, qdss_stm30, qdss_stm29,
+ tsif1_clk, qdss_stm28, tsif1_en, tsif1_data, sdc4_cmd, qdss_stm27,
+ qdss_traceclk_b, tsif2_error, sdc43, vfr_1, qdss_stm26, tsif2_clk,
+ sdc4_clk, qdss_stm24, tsif2_en, sdc42, qdss_stm23, qdss_tracectl_b,
+ sd_card, tsif2_data, sdc41, tsif2_sync, sdc40, mdp_vsync_p_b,
+ ldo_en, mdp_vsync_s_b, ldo_update, blsp11_uart_tx_b, blsp11_uart_rx_b,
+ blsp11_i2c_sda_b, prng_rosc, blsp11_i2c_scl_b, uim2, uim1, uim_batt,
+ pci_e2, pa_indicator, adsp_ext, ddr_bist, qdss_tracedata_11,
+ qdss_tracedata_12, modem_tsync, nav_dr, nav_pps, pci_e1, gsm_tx,
+ qspi_cs, ssbi2, ssbi1, mss_lte, qspi_clk, qspi0, qspi1, qspi2, qspi3,
+ gpio
+
+- bias-disable:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins should be configued as no pull.
+
+- bias-pull-down:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins should be configued as pull down.
+
+- bias-pull-up:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins should be configued as pull up.
+
+- output-high:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins are configured in output mode, driven
+ high.
+ Not valid for sdc pins.
+
+- output-low:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins are configured in output mode, driven
+ low.
+ Not valid for sdc pins.
+
+- drive-strength:
+ Usage: optional
+ Value type: <u32>
+ Definition: Selects the drive strength for the specified pins, in mA.
+ Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16
+
+Example:
+
+ tlmm: pinctrl@01010000 {
+ compatible = "qcom,msm8998-pinctrl";
+ reg = <0x01010000 0x300000>;
+ interrupts = <0 208 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ uart_console_active: uart_console_active {
+ mux {
+ pins = "gpio4", "gpio5";
+ function = "blsp_uart8";
+ };
+
+ config {
+ pins = "gpio4", "gpio5";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+ };
diff --git a/drivers/clk/msm/clock-local2.c b/drivers/clk/msm/clock-local2.c
index 076ead6aaf34..40d8d12cda82 100644
--- a/drivers/clk/msm/clock-local2.c
+++ b/drivers/clk/msm/clock-local2.c
@@ -1517,8 +1517,8 @@ static int set_rate_pixel(struct clk *clk, unsigned long rate)
{
struct rcg_clk *rcg = to_rcg_clk(clk);
struct clk_freq_tbl *pixel_freq = rcg->current_freq;
- int frac_num[] = {3, 2, 4, 1};
- int frac_den[] = {8, 9, 9, 1};
+ int frac_num[] = {1, 2, 4, 3, 2};
+ int frac_den[] = {1, 3, 9, 8, 9};
int delta = 100000;
int i, rc;
diff --git a/drivers/clk/msm/mdss/mdss-dsi-pll-8998.c b/drivers/clk/msm/mdss/mdss-dsi-pll-8998.c
index eb69ed35f46d..040707e58e25 100644
--- a/drivers/clk/msm/mdss/mdss-dsi-pll-8998.c
+++ b/drivers/clk/msm/mdss/mdss-dsi-pll-8998.c
@@ -152,8 +152,6 @@ struct dsi_pll_regs {
struct dsi_pll_config {
u32 ref_freq;
- bool div_override;
- u32 output_div;
bool ignore_frac;
bool disable_prescaler;
bool enable_ssc;
@@ -212,7 +210,6 @@ static void dsi_pll_setup_config(struct dsi_pll_8998 *pll,
struct dsi_pll_config *config = &pll->pll_configuration;
config->ref_freq = 19200000;
- config->output_div = 1;
config->dec_bits = 8;
config->frac_bits = 18;
config->lock_timer = 64;
@@ -222,7 +219,6 @@ static void dsi_pll_setup_config(struct dsi_pll_8998 *pll,
config->thresh_cycles = 32;
config->refclk_cycles = 256;
- config->div_override = false;
config->ignore_frac = false;
config->disable_prescaler = false;
config->enable_ssc = rsc->ssc_en;
@@ -243,54 +239,14 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_8998 *pll,
{
struct dsi_pll_config *config = &pll->pll_configuration;
struct dsi_pll_regs *regs = &pll->reg_setup;
- u64 target_freq;
u64 fref = rsc->vco_ref_clk_rate;
- u32 computed_output_div, div_log = 0;
u64 pll_freq;
u64 divider;
u64 dec, dec_multiple;
u32 frac;
u64 multiplier;
- u32 i;
-
- target_freq = rsc->vco_current_rate;
- pr_debug("target_freq = %llu\n", target_freq);
-
- if (config->div_override) {
- computed_output_div = config->output_div;
-
- /*
- * Computed_output_div = 2 ^ div_log
- * To get div_log from output div just get the index of the
- * 1 bit in the value.
- * div_log ranges from 0-3. so check the 4 lsbs
- */
-
- for (i = 0; i < 4; i++) {
- if (computed_output_div & (1 << i)) {
- div_log = i;
- break;
- }
- }
-
- } else {
- if (target_freq < MHZ_250) {
- computed_output_div = 8;
- div_log = 3;
- } else if (target_freq < MHZ_500) {
- computed_output_div = 4;
- div_log = 2;
- } else if (target_freq < MHZ_1000) {
- computed_output_div = 2;
- div_log = 1;
- } else {
- computed_output_div = 1;
- div_log = 0;
- }
- }
- pr_debug("computed_output_div = %d\n", computed_output_div);
- pll_freq = target_freq * computed_output_div;
+ pll_freq = rsc->vco_current_rate;
if (config->disable_prescaler)
divider = fref;
@@ -315,7 +271,6 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_8998 *pll,
else
regs->pll_clock_inverters = 0;
- regs->pll_outdiv_rate = div_log;
regs->pll_lockdet_rate = config->lock_timer;
regs->decimal_div_start = dec;
regs->frac_div_start_low = (frac & 0xff);
@@ -478,7 +433,6 @@ static void dsi_pll_commit(struct dsi_pll_8998 *pll,
MDSS_PLL_REG_W(pll_base, PLL_FRAC_DIV_START_HIGH_1,
reg->frac_div_start_high);
MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCKDET_RATE_1, 0x40);
- MDSS_PLL_REG_W(pll_base, PLL_PLL_OUTDIV_RATE, reg->pll_outdiv_rate);
MDSS_PLL_REG_W(pll_base, PLL_PLL_LOCK_DELAY, 0x06);
MDSS_PLL_REG_W(pll_base, PLL_CMODE, 0x10);
MDSS_PLL_REG_W(pll_base, PLL_CLOCK_INVERTERS, reg->pll_clock_inverters);
@@ -597,11 +551,23 @@ static int dsi_pll_enable(struct dsi_pll_vco_clk *vco)
{
int rc;
struct mdss_pll_resources *rsc = vco->priv;
+ struct dsi_pll_8998 *pll = rsc->priv;
+ struct dsi_pll_regs *regs = &pll->reg_setup;
dsi_pll_enable_pll_bias(rsc);
if (rsc->slave)
dsi_pll_enable_pll_bias(rsc->slave);
+ /*
+ * The PLL out dividers are fixed divider clocks and hence the
+ * set_div is not called during set_rate cycle of the tree.
+ * The outdiv rate is therefore set in the pll out mux's set_sel
+ * callback. But that will be called only after vco's set rate.
+ * Hence PLL out div value is set here before locking the PLL.
+ */
+ MDSS_PLL_REG_W(rsc->pll_base, PLL_PLL_OUTDIV_RATE,
+ regs->pll_outdiv_rate);
+
/* Start PLL */
MDSS_PLL_REG_W(rsc->phy_base, PHY_CMN_PLL_CNTRL, 0x01);
@@ -728,7 +694,9 @@ static int vco_8998_prepare(struct clk *c)
static unsigned long dsi_pll_get_vco_rate(struct clk *c)
{
struct dsi_pll_vco_clk *vco = to_vco_clk(c);
- struct mdss_pll_resources *pll = vco->priv;
+ struct mdss_pll_resources *rsc = vco->priv;
+ struct dsi_pll_8998 *pll = rsc->priv;
+ struct dsi_pll_regs *regs = &pll->reg_setup;
int rc;
u64 ref_clk = vco->ref_clk_rate;
u64 vco_rate;
@@ -738,27 +706,30 @@ static unsigned long dsi_pll_get_vco_rate(struct clk *c)
u32 outdiv;
u64 pll_freq, tmp64;
- rc = mdss_pll_resource_enable(pll, true);
+ rc = mdss_pll_resource_enable(rsc, true);
if (rc) {
pr_err("failed to enable pll(%d) resource, rc=%d\n",
- pll->index, rc);
+ rsc->index, rc);
return 0;
}
- dec = MDSS_PLL_REG_R(pll->pll_base, PLL_DECIMAL_DIV_START_1);
+ dec = MDSS_PLL_REG_R(rsc->pll_base, PLL_DECIMAL_DIV_START_1);
dec &= 0xFF;
- frac = MDSS_PLL_REG_R(pll->pll_base, PLL_FRAC_DIV_START_LOW_1);
- frac |= ((MDSS_PLL_REG_R(pll->pll_base, PLL_FRAC_DIV_START_MID_1) &
+ frac = MDSS_PLL_REG_R(rsc->pll_base, PLL_FRAC_DIV_START_LOW_1);
+ frac |= ((MDSS_PLL_REG_R(rsc->pll_base, PLL_FRAC_DIV_START_MID_1) &
0xFF) <<
8);
- frac |= ((MDSS_PLL_REG_R(pll->pll_base, PLL_FRAC_DIV_START_HIGH_1) &
+ frac |= ((MDSS_PLL_REG_R(rsc->pll_base, PLL_FRAC_DIV_START_HIGH_1) &
0x3) <<
16);
/* OUTDIV_1:0 field is (log(outdiv, 2)) */
- outdiv = MDSS_PLL_REG_R(pll->pll_base, PLL_PLL_OUTDIV_RATE);
+ outdiv = MDSS_PLL_REG_R(rsc->pll_base, PLL_PLL_OUTDIV_RATE);
outdiv &= 0x3;
+
+ regs->pll_outdiv_rate = outdiv;
+
outdiv = 1 << outdiv;
/*
@@ -776,7 +747,7 @@ static unsigned long dsi_pll_get_vco_rate(struct clk *c)
pr_debug("dec=0x%x, frac=0x%x, outdiv=%d, vco=%llu\n",
dec, frac, outdiv, vco_rate);
- (void)mdss_pll_resource_enable(pll, false);
+ (void)mdss_pll_resource_enable(rsc, false);
return (unsigned long)vco_rate;
}
@@ -930,6 +901,26 @@ static int bit_clk_set_div(struct div_clk *clk, int div)
return rc;
}
+static int dsi_pll_out_set_mux_sel(struct mux_clk *clk, int sel)
+{
+ struct mdss_pll_resources *rsc = clk->priv;
+ struct dsi_pll_8998 *pll = rsc->priv;
+ struct dsi_pll_regs *regs = &pll->reg_setup;
+
+ regs->pll_outdiv_rate = sel;
+
+ return 0;
+}
+
+static int dsi_pll_out_get_mux_sel(struct mux_clk *clk)
+{
+ struct mdss_pll_resources *rsc = clk->priv;
+ struct dsi_pll_8998 *pll = rsc->priv;
+ struct dsi_pll_regs *regs = &pll->reg_setup;
+
+ return regs->pll_outdiv_rate;
+}
+
static int post_vco_clk_get_div(struct div_clk *clk)
{
int rc;
@@ -1125,52 +1116,75 @@ static struct clk_mux_ops mdss_mux_ops = {
.get_mux_sel = mdss_get_mux_sel,
};
+static struct clk_mux_ops mdss_pll_out_mux_ops = {
+ .set_mux_sel = dsi_pll_out_set_mux_sel,
+ .get_mux_sel = dsi_pll_out_get_mux_sel,
+};
+
/*
* Clock tree for generating DSI byte and pixel clocks.
*
- *
- * +---------------+
- * | vco_clk |
- * +-------+-------+
- * |
- * +----------------------+------------------+
- * | | |
- * +-------v-------+ +-------v-------+ +-------v-------+
- * | bitclk_src | | post_vco_div1 | | post_vco_div4 |
- * | DIV(1..15) | +-------+-------+ +-------+-------+
- * +-------+-------+ | |
- * | +------------+ |
- * +--------------------+ | |
- * Shadow Path | | | |
- * + +-------v-------+ +------v------+ +---v-----v------+
- * | | byteclk_src | |post_bit_div | \ post_vco_mux /
- * | | DIV(8) | |DIV(1,2) | \ /
- * | +-------+-------+ +------+------+ +---+------+
- * | | | |
- * | | +------+ +----+
- * | +--------+ | |
- * | | +----v-----v------+
- * +-v---------v----+ \ pclk_src_mux /
- * \ byteclk_mux / \ /
- * \ / +-----+-----+
- * +----+-----+ | Shadow Path
- * | | +
- * v +-----v------+ |
- * dsi_byte_clk | pclk_src | |
- * | DIV(1..15) | |
- * +-----+------+ |
- * | |
- * | |
- * +--------+ |
- * | |
- * +---v----v----+
- * \ pclk_mux /
- * \ /
- * +---+---+
- * |
- * |
- * v
- * dsi_pclk
+ * +---------------+
+ * | vco_clk |
+ * | |
+ * +-------+-------+
+ * |
+ * |
+ * +-------+--------+------------------+-----------------+
+ * | | | |
+ * +------v-------+ +------v-------+ +-------v------+ +------v-------+
+ * | pll_out_div1 | | pll_out_div2 | | pll_out_div4 | | pll_out_div8 |
+ * | DIV(1) | | DIV(2) | | DIV(4) | | DIV(8) |
+ * +------+-------+ +------+-------+ +-------+------+ +------+-------+
+ * | | | |
+ * +------------+ | +--------------+ |
+ * | | | +---------------------------+
+ * | | | |
+ * +--v---v---v----v--+
+ * \ pll_out_mux /
+ * \ /
+ * +------+-----+
+ * |
+ * +---------------+-----------------+
+ * | | |
+ * +------v-----+ +-------v-------+ +-------v-------+
+ * | bitclk_src | | post_vco_div1 | | post_vco_div4 |
+ * | DIV(1..15) | + DIV(1) | | DIV(4) |
+ * +------+-----+ +-------+-------+ +-------+-------+
+ * | | |
+ * Shadow | | +---------------------+
+ * Path | +-----------------------------+ |
+ * + | | |
+ * | +---------------------------------+ | |
+ * | | | | |
+ * | +------v------=+ +------v-------+ +-v---------v----+
+ * | | byteclk_src | | post_bit_div | \ post_vco_mux /
+ * | | DIV(8) | | DIV(1,2) | \ /
+ * | +------+-------+ +------+-------+ +---+------+
+ * | | | |
+ * | | | +----------+
+ * | | | |
+ * | | +----v-----v------+
+ * +-v--------v---------+ \ pclk_src_mux /
+ * \ byteclk_mux / \ /
+ * \ / +-----+-----+
+ * +------+-------+ | Shadow
+ * | | Path
+ * v +-----v------+ +
+ * dsi_byte_clk | pclk_src | |
+ * | DIV(1..15) | |
+ * +-----+------+ |
+ * | |
+ * +------+ |
+ * | |
+ * +---v----v----+
+ * \ pclk_mux /
+ * \ /
+ * +---+---+
+ * |
+ * |
+ * v
+ * dsi_pclk
*
*/
@@ -1186,6 +1200,83 @@ static struct dsi_pll_vco_clk dsi0pll_vco_clk = {
},
};
+static struct div_clk dsi0pll_pll_out_div1 = {
+ .data = {
+ .div = 1,
+ .min_div = 1,
+ .max_div = 1,
+ },
+ .c = {
+ .parent = &dsi0pll_vco_clk.c,
+ .dbg_name = "dsi0pll_pll_out_div1",
+ .ops = &clk_ops_div,
+ .flags = CLKFLAG_NO_RATE_CACHE,
+ CLK_INIT(dsi0pll_pll_out_div1.c),
+ }
+};
+
+static struct div_clk dsi0pll_pll_out_div2 = {
+ .data = {
+ .div = 2,
+ .min_div = 2,
+ .max_div = 2,
+ },
+ .c = {
+ .parent = &dsi0pll_vco_clk.c,
+ .dbg_name = "dsi0pll_pll_out_div2",
+ .ops = &clk_ops_div,
+ .flags = CLKFLAG_NO_RATE_CACHE,
+ CLK_INIT(dsi0pll_pll_out_div2.c),
+ }
+};
+
+static struct div_clk dsi0pll_pll_out_div4 = {
+ .data = {
+ .div = 4,
+ .min_div = 4,
+ .max_div = 4,
+ },
+ .c = {
+ .parent = &dsi0pll_vco_clk.c,
+ .dbg_name = "dsi0pll_pll_out_div4",
+ .ops = &clk_ops_div,
+ .flags = CLKFLAG_NO_RATE_CACHE,
+ CLK_INIT(dsi0pll_pll_out_div4.c),
+ }
+};
+
+static struct div_clk dsi0pll_pll_out_div8 = {
+ .data = {
+ .div = 8,
+ .min_div = 8,
+ .max_div = 8,
+ },
+ .c = {
+ .parent = &dsi0pll_vco_clk.c,
+ .dbg_name = "dsi0pll_pll_out_div8",
+ .ops = &clk_ops_div,
+ .flags = CLKFLAG_NO_RATE_CACHE,
+ CLK_INIT(dsi0pll_pll_out_div8.c),
+ }
+};
+
+static struct mux_clk dsi0pll_pll_out_mux = {
+ .num_parents = 4,
+ .parents = (struct clk_src[]) {
+ {&dsi0pll_pll_out_div1.c, 0},
+ {&dsi0pll_pll_out_div2.c, 1},
+ {&dsi0pll_pll_out_div4.c, 2},
+ {&dsi0pll_pll_out_div8.c, 3},
+ },
+ .ops = &mdss_pll_out_mux_ops,
+ .c = {
+ .parent = &dsi0pll_pll_out_div1.c,
+ .dbg_name = "dsi0pll_pll_out_mux",
+ .ops = &clk_ops_gen_mux,
+ .flags = CLKFLAG_NO_RATE_CACHE,
+ CLK_INIT(dsi0pll_pll_out_mux.c),
+ }
+};
static struct div_clk dsi0pll_bitclk_src = {
.data = {
.div = 1,
@@ -1194,7 +1285,7 @@ static struct div_clk dsi0pll_bitclk_src = {
},
.ops = &clk_bitclk_src_ops,
.c = {
- .parent = &dsi0pll_vco_clk.c,
+ .parent = &dsi0pll_pll_out_mux.c,
.dbg_name = "dsi0pll_bitclk_src",
.ops = &clk_ops_bitclk_src_c,
.flags = CLKFLAG_NO_RATE_CACHE,
@@ -1210,7 +1301,7 @@ static struct div_clk dsi0pll_post_vco_div1 = {
},
.ops = &clk_post_vco_div_ops,
.c = {
- .parent = &dsi0pll_vco_clk.c,
+ .parent = &dsi0pll_pll_out_mux.c,
.dbg_name = "dsi0pll_post_vco_div1",
.ops = &clk_ops_post_vco_div_c,
.flags = CLKFLAG_NO_RATE_CACHE,
@@ -1226,7 +1317,7 @@ static struct div_clk dsi0pll_post_vco_div4 = {
},
.ops = &clk_post_vco_div_ops,
.c = {
- .parent = &dsi0pll_vco_clk.c,
+ .parent = &dsi0pll_pll_out_mux.c,
.dbg_name = "dsi0pll_post_vco_div4",
.ops = &clk_ops_post_vco_div_c,
.flags = CLKFLAG_NO_RATE_CACHE,
@@ -1355,6 +1446,84 @@ static struct dsi_pll_vco_clk dsi1pll_vco_clk = {
},
};
+static struct div_clk dsi1pll_pll_out_div1 = {
+ .data = {
+ .div = 1,
+ .min_div = 1,
+ .max_div = 1,
+ },
+ .c = {
+ .parent = &dsi1pll_vco_clk.c,
+ .dbg_name = "dsi1pll_pll_out_div1",
+ .ops = &clk_ops_div,
+ .flags = CLKFLAG_NO_RATE_CACHE,
+ CLK_INIT(dsi1pll_pll_out_div1.c),
+ }
+};
+
+static struct div_clk dsi1pll_pll_out_div2 = {
+ .data = {
+ .div = 2,
+ .min_div = 2,
+ .max_div = 2,
+ },
+ .c = {
+ .parent = &dsi1pll_vco_clk.c,
+ .dbg_name = "dsi1pll_pll_out_div2",
+ .ops = &clk_ops_div,
+ .flags = CLKFLAG_NO_RATE_CACHE,
+ CLK_INIT(dsi1pll_pll_out_div2.c),
+ }
+};
+
+static struct div_clk dsi1pll_pll_out_div4 = {
+ .data = {
+ .div = 4,
+ .min_div = 4,
+ .max_div = 4,
+ },
+ .c = {
+ .parent = &dsi1pll_vco_clk.c,
+ .dbg_name = "dsi1pll_pll_out_div4",
+ .ops = &clk_ops_div,
+ .flags = CLKFLAG_NO_RATE_CACHE,
+ CLK_INIT(dsi1pll_pll_out_div4.c),
+ }
+};
+
+static struct div_clk dsi1pll_pll_out_div8 = {
+ .data = {
+ .div = 8,
+ .min_div = 8,
+ .max_div = 8,
+ },
+ .c = {
+ .parent = &dsi1pll_vco_clk.c,
+ .dbg_name = "dsi1pll_pll_out_div8",
+ .ops = &clk_ops_div,
+ .flags = CLKFLAG_NO_RATE_CACHE,
+ CLK_INIT(dsi1pll_pll_out_div8.c),
+ }
+};
+
+static struct mux_clk dsi1pll_pll_out_mux = {
+ .num_parents = 4,
+ .parents = (struct clk_src[]) {
+ {&dsi1pll_pll_out_div1.c, 0},
+ {&dsi1pll_pll_out_div2.c, 1},
+ {&dsi1pll_pll_out_div4.c, 2},
+ {&dsi1pll_pll_out_div8.c, 3},
+ },
+ .ops = &mdss_pll_out_mux_ops,
+ .c = {
+ .parent = &dsi1pll_pll_out_div1.c,
+ .dbg_name = "dsi1pll_pll_out_mux",
+ .ops = &clk_ops_gen_mux,
+ .flags = CLKFLAG_NO_RATE_CACHE,
+ CLK_INIT(dsi1pll_pll_out_mux.c),
+ }
+};
+
static struct div_clk dsi1pll_bitclk_src = {
.data = {
.div = 1,
@@ -1363,7 +1532,7 @@ static struct div_clk dsi1pll_bitclk_src = {
},
.ops = &clk_bitclk_src_ops,
.c = {
- .parent = &dsi1pll_vco_clk.c,
+ .parent = &dsi1pll_pll_out_mux.c,
.dbg_name = "dsi1pll_bitclk_src",
.ops = &clk_ops_bitclk_src_c,
.flags = CLKFLAG_NO_RATE_CACHE,
@@ -1379,7 +1548,7 @@ static struct div_clk dsi1pll_post_vco_div1 = {
},
.ops = &clk_post_vco_div_ops,
.c = {
- .parent = &dsi1pll_vco_clk.c,
+ .parent = &dsi1pll_pll_out_mux.c,
.dbg_name = "dsi1pll_post_vco_div1",
.ops = &clk_ops_post_vco_div_c,
.flags = CLKFLAG_NO_RATE_CACHE,
@@ -1395,7 +1564,7 @@ static struct div_clk dsi1pll_post_vco_div4 = {
},
.ops = &clk_post_vco_div_ops,
.c = {
- .parent = &dsi1pll_vco_clk.c,
+ .parent = &dsi1pll_pll_out_mux.c,
.dbg_name = "dsi1pll_post_vco_div4",
.ops = &clk_ops_post_vco_div_c,
.flags = CLKFLAG_NO_RATE_CACHE,
@@ -1523,6 +1692,11 @@ static struct clk_lookup mdss_dsi_pll0cc_8998[] = {
CLK_LIST(dsi0pll_post_vco_div1),
CLK_LIST(dsi0pll_post_vco_div4),
CLK_LIST(dsi0pll_bitclk_src),
+ CLK_LIST(dsi0pll_pll_out_mux),
+ CLK_LIST(dsi0pll_pll_out_div8),
+ CLK_LIST(dsi0pll_pll_out_div4),
+ CLK_LIST(dsi0pll_pll_out_div2),
+ CLK_LIST(dsi0pll_pll_out_div1),
CLK_LIST(dsi0pll_vco_clk),
};
static struct clk_lookup mdss_dsi_pll1cc_8998[] = {
@@ -1536,6 +1710,11 @@ static struct clk_lookup mdss_dsi_pll1cc_8998[] = {
CLK_LIST(dsi1pll_post_vco_div1),
CLK_LIST(dsi1pll_post_vco_div4),
CLK_LIST(dsi1pll_bitclk_src),
+ CLK_LIST(dsi1pll_pll_out_mux),
+ CLK_LIST(dsi1pll_pll_out_div8),
+ CLK_LIST(dsi1pll_pll_out_div4),
+ CLK_LIST(dsi1pll_pll_out_div2),
+ CLK_LIST(dsi1pll_pll_out_div1),
CLK_LIST(dsi1pll_vco_clk),
};
@@ -1596,6 +1775,11 @@ int dsi_pll_clock_register_8998(struct platform_device *pdev,
dsi0pll_post_vco_div1.priv = pll_res;
dsi0pll_post_vco_div4.priv = pll_res;
dsi0pll_bitclk_src.priv = pll_res;
+ dsi0pll_pll_out_div1.priv = pll_res;
+ dsi0pll_pll_out_div2.priv = pll_res;
+ dsi0pll_pll_out_div4.priv = pll_res;
+ dsi0pll_pll_out_div8.priv = pll_res;
+ dsi0pll_pll_out_mux.priv = pll_res;
dsi0pll_vco_clk.priv = pll_res;
rc = of_msm_clock_register(pdev->dev.of_node,
@@ -1612,6 +1796,11 @@ int dsi_pll_clock_register_8998(struct platform_device *pdev,
dsi1pll_post_vco_div1.priv = pll_res;
dsi1pll_post_vco_div4.priv = pll_res;
dsi1pll_bitclk_src.priv = pll_res;
+ dsi1pll_pll_out_div1.priv = pll_res;
+ dsi1pll_pll_out_div2.priv = pll_res;
+ dsi1pll_pll_out_div4.priv = pll_res;
+ dsi1pll_pll_out_div8.priv = pll_res;
+ dsi1pll_pll_out_mux.priv = pll_res;
dsi1pll_vco_clk.priv = pll_res;
rc = of_msm_clock_register(pdev->dev.of_node,
diff --git a/drivers/esoc/esoc-mdm-4x.c b/drivers/esoc/esoc-mdm-4x.c
index 26f69fa61ba1..6eab3ea187c6 100644
--- a/drivers/esoc/esoc-mdm-4x.c
+++ b/drivers/esoc/esoc-mdm-4x.c
@@ -88,12 +88,10 @@ static void mdm_enable_irqs(struct mdm_ctrl *mdm)
return;
if (mdm->irq_mask & IRQ_ERRFATAL) {
enable_irq(mdm->errfatal_irq);
- irq_set_irq_wake(mdm->errfatal_irq, 1);
mdm->irq_mask &= ~IRQ_ERRFATAL;
}
if (mdm->irq_mask & IRQ_STATUS) {
enable_irq(mdm->status_irq);
- irq_set_irq_wake(mdm->status_irq, 1);
mdm->irq_mask &= ~IRQ_STATUS;
}
if (mdm->irq_mask & IRQ_PBLRDY) {
@@ -107,12 +105,10 @@ static void mdm_disable_irqs(struct mdm_ctrl *mdm)
if (!mdm)
return;
if (!(mdm->irq_mask & IRQ_ERRFATAL)) {
- irq_set_irq_wake(mdm->errfatal_irq, 0);
disable_irq_nosync(mdm->errfatal_irq);
mdm->irq_mask |= IRQ_ERRFATAL;
}
if (!(mdm->irq_mask & IRQ_STATUS)) {
- irq_set_irq_wake(mdm->status_irq, 0);
disable_irq_nosync(mdm->status_irq);
mdm->irq_mask |= IRQ_STATUS;
}
@@ -701,6 +697,7 @@ static int mdm_configure_ipc(struct mdm_ctrl *mdm, struct platform_device *pdev)
goto errfatal_err;
}
mdm->errfatal_irq = irq;
+ irq_set_irq_wake(mdm->errfatal_irq, 1);
errfatal_err:
/* status irq */
@@ -719,6 +716,7 @@ errfatal_err:
goto status_err;
}
mdm->status_irq = irq;
+ irq_set_irq_wake(mdm->status_irq, 1);
status_err:
if (gpio_is_valid(MDM_GPIO(mdm, MDM2AP_PBLRDY))) {
irq = platform_get_irq_byname(pdev, "plbrdy_irq");
diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c
index 3e4cc4490792..2b7a1fcbaa78 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.c
+++ b/drivers/gpu/msm/kgsl_pwrscale.c
@@ -591,7 +591,7 @@ int kgsl_devfreq_get_dev_status(struct device *dev,
struct kgsl_device *device = dev_get_drvdata(dev);
struct kgsl_pwrctrl *pwrctrl;
struct kgsl_pwrscale *pwrscale;
- ktime_t tmp;
+ ktime_t tmp1, tmp2;
if (device == NULL)
return -ENODEV;
@@ -602,6 +602,8 @@ int kgsl_devfreq_get_dev_status(struct device *dev,
pwrctrl = &device->pwrctrl;
mutex_lock(&device->mutex);
+
+ tmp1 = ktime_get();
/*
* If the GPU clock is on grab the latest power counter
* values. Otherwise the most recent ACTIVE values will
@@ -609,9 +611,9 @@ int kgsl_devfreq_get_dev_status(struct device *dev,
*/
kgsl_pwrscale_update_stats(device);
- tmp = ktime_get();
- stat->total_time = ktime_us_delta(tmp, pwrscale->time);
- pwrscale->time = tmp;
+ tmp2 = ktime_get();
+ stat->total_time = ktime_us_delta(tmp2, pwrscale->time);
+ pwrscale->time = tmp1;
stat->busy_time = pwrscale->accum_stats.busy_time;
diff --git a/drivers/media/platform/msm/ais/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/ais/pproc/cpp/msm_cpp.c
index 811ac98beead..6c50070c91ab 100644
--- a/drivers/media/platform/msm/ais/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/ais/pproc/cpp/msm_cpp.c
@@ -2882,7 +2882,7 @@ end:
return rc;
}
-static int msm_cpp_validate_input(unsigned int cmd, void *arg,
+static int msm_cpp_validate_ioctl_input(unsigned int cmd, void *arg,
struct msm_camera_v4l2_ioctl_t **ioctl_ptr)
{
switch (cmd) {
@@ -2922,6 +2922,14 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
pr_err("sd %pK\n", sd);
return -EINVAL;
}
+
+
+ rc = msm_cpp_validate_ioctl_input(cmd, arg, &ioctl_ptr);
+ if (rc != 0) {
+ pr_err("input validation failed\n");
+ return rc;
+ }
+
cpp_dev = v4l2_get_subdevdata(sd);
if (cpp_dev == NULL) {
pr_err("cpp_dev is null\n");
@@ -2933,11 +2941,6 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
return -EINVAL;
}
- rc = msm_cpp_validate_input(cmd, arg, &ioctl_ptr);
- if (rc != 0) {
- pr_err("input validation failed\n");
- return rc;
- }
mutex_lock(&cpp_dev->mutex);
CPP_DBG("E cmd: 0x%x\n", cmd);
@@ -3437,6 +3440,7 @@ STREAM_BUFF_END:
} else {
pr_err("%s:%d IOMMMU attach triggered in invalid state\n",
__func__, __LINE__);
+ rc = -EINVAL;
}
break;
}
@@ -4061,7 +4065,8 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file,
default:
pr_err_ratelimited("%s: unsupported compat type :%x LOAD %lu\n",
__func__, cmd, VIDIOC_MSM_CPP_LOAD_FIRMWARE);
- break;
+ mutex_unlock(&cpp_dev->mutex);
+ return -EINVAL;
}
mutex_unlock(&cpp_dev->mutex);
@@ -4092,7 +4097,7 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file,
default:
pr_err_ratelimited("%s: unsupported compat type :%d\n",
__func__, cmd);
- break;
+ return -EINVAL;
}
if (is_copytouser_req) {
diff --git a/drivers/media/platform/msm/ais/sensor/flash/msm_flash.c b/drivers/media/platform/msm/ais/sensor/flash/msm_flash.c
index a2a89b92c9f1..734b37172421 100644
--- a/drivers/media/platform/msm/ais/sensor/flash/msm_flash.c
+++ b/drivers/media/platform/msm/ais/sensor/flash/msm_flash.c
@@ -152,6 +152,13 @@ static int32_t msm_flash_i2c_write_table(
conf_array.reg_setting = settings->reg_setting_a;
conf_array.size = settings->size;
+ /* Validate the settings size */
+ if ((!conf_array.size) || (conf_array.size > MAX_I2C_REG_SET)) {
+ pr_err("failed: invalid size %d", conf_array.size);
+ return -EINVAL;
+ }
+
+
return flash_ctrl->flash_i2c_client.i2c_func_tbl->i2c_write_table(
&flash_ctrl->flash_i2c_client, &conf_array);
}
diff --git a/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c b/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
index c243d587e308..90edadaed1ef 100644
--- a/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
+++ b/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
@@ -175,35 +175,45 @@ int32_t msm_camera_io_poll_value_wmask(void __iomem *addr, u32 wait_data,
void msm_camera_io_dump(void __iomem *addr, int size, int enable)
{
- char line_str[128], *p_str;
+ char line_str[128];
int i;
- u32 *p = (u32 *) addr;
+ ptrdiff_t p = 0;
+ size_t offset = 0, used = 0;
u32 data;
CDBG("%s: addr=%pK size=%d\n", __func__, addr, size);
- if (!p || (size <= 0) || !enable)
+ if (!addr || (size <= 0) || !enable)
return;
line_str[0] = '\0';
- p_str = line_str;
for (i = 0; i < size/4; i++) {
if (i % 4 == 0) {
-#ifdef CONFIG_COMPAT
- snprintf(p_str, 20, "%016lx: ", (unsigned long) p);
- p_str += 18;
-#else
- snprintf(p_str, 12, "%08lx: ", (unsigned long) p);
- p_str += 10;
-#endif
+ used = snprintf(line_str + offset,
+ sizeof(line_str) - offset, "0x%04tX: ", p);
+ if (offset + used >= sizeof(line_str)) {
+ pr_err("%s\n", line_str);
+ offset = 0;
+ line_str[0] = '\0';
+ } else {
+ offset += used;
+ }
+ }
+ data = readl_relaxed(addr + p);
+ p = p + 4;
+ used = snprintf(line_str + offset,
+ sizeof(line_str) - offset, "%08x ", data);
+ if (offset + used >= sizeof(line_str)) {
+ pr_err("%s\n", line_str);
+ offset = 0;
+ line_str[0] = '\0';
+ } else {
+ offset += used;
}
- data = readl_relaxed(p++);
- snprintf(p_str, 12, "%08x ", data);
- p_str += 9;
if ((i + 1) % 4 == 0) {
pr_err("%s\n", line_str);
line_str[0] = '\0';
- p_str = line_str;
+ offset = 0;
}
}
if (line_str[0] != '\0')
diff --git a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
index 4149122b1c77..10f72a2155db 100644
--- a/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
+++ b/drivers/media/platform/msm/sde/rotator/sde_rotator_r3.c
@@ -668,11 +668,11 @@ static void sde_hw_rotator_setup_fetchengine(struct sde_hw_rotator_context *ctx,
/*
* Determine if traffic shaping is required. Only enable traffic
- * shaping when content is 4k@60fps. The actual traffic shaping
+ * shaping when content is 4k@30fps. The actual traffic shaping
* bandwidth calculation is done in output setup.
*/
if (((cfg->src_rect->w * cfg->src_rect->h) >= RES_UHD) &&
- (cfg->fps <= 60)) {
+ (cfg->fps <= 30)) {
SDEROT_DBG("Enable Traffic Shaper\n");
ctx->is_traffic_shaping = true;
} else {
diff --git a/drivers/net/wireless/ath/wil6210/sysfs.c b/drivers/net/wireless/ath/wil6210/sysfs.c
index b4c4d09011b4..b91bf51be767 100644
--- a/drivers/net/wireless/ath/wil6210/sysfs.c
+++ b/drivers/net/wireless/ath/wil6210/sysfs.c
@@ -291,6 +291,8 @@ int wil6210_sysfs_init(struct wil6210_priv *wil)
return err;
}
+ kobject_uevent(&dev->kobj, KOBJ_CHANGE);
+
return 0;
}
@@ -299,4 +301,5 @@ void wil6210_sysfs_remove(struct wil6210_priv *wil)
struct device *dev = wil_to_dev(wil);
sysfs_remove_group(&dev->kobj, &wil6210_attribute_group);
+ kobject_uevent(&dev->kobj, KOBJ_CHANGE);
}
diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c
index 236654285db7..edc39af2d361 100644
--- a/drivers/net/wireless/cnss2/pci.c
+++ b/drivers/net/wireless/cnss2/pci.c
@@ -1366,12 +1366,10 @@ int cnss_pci_start_mhi(struct cnss_pci_data *pci_priv)
ret = cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_POWER_ON);
if (ret)
- goto deinit_mhi;
+ goto out;
return 0;
-deinit_mhi:
- cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_DEINIT);
out:
return ret;
}
diff --git a/drivers/power/supply/qcom/smb138x-charger.c b/drivers/power/supply/qcom/smb138x-charger.c
index 335b160e24a5..ec74e3825dd5 100644
--- a/drivers/power/supply/qcom/smb138x-charger.c
+++ b/drivers/power/supply/qcom/smb138x-charger.c
@@ -845,6 +845,13 @@ static int smb138x_init_slave_hw(struct smb138x *chip)
}
}
+ /* configure to a fixed 700khz freq to avoid tdie errors */
+ rc = smblib_set_charge_param(chg, &chg->param.freq_buck, 700);
+ if (rc < 0) {
+ pr_err("Couldn't configure 700Khz switch freq rc=%d\n", rc);
+ return rc;
+ }
+
/* enable watchdog bark and bite interrupts, and disable the watchdog */
rc = smblib_masked_write(chg, WD_CFG_REG, WDOG_TIMER_EN_BIT
| WDOG_TIMER_EN_ON_PLUGIN_BIT | BITE_WDOG_INT_EN_BIT
diff --git a/drivers/soc/qcom/watchdog_v2.c b/drivers/soc/qcom/watchdog_v2.c
index 745a069df88a..625030f1f256 100644
--- a/drivers/soc/qcom/watchdog_v2.c
+++ b/drivers/soc/qcom/watchdog_v2.c
@@ -134,6 +134,8 @@ static int msm_watchdog_suspend(struct device *dev)
return 0;
__raw_writel(1, wdog_dd->base + WDT0_RST);
if (wdog_dd->wakeup_irq_enable) {
+ /* Make sure register write is complete before proceeding */
+ mb();
wdog_dd->last_pet = sched_clock();
return 0;
}
@@ -148,8 +150,15 @@ static int msm_watchdog_resume(struct device *dev)
{
struct msm_watchdog_data *wdog_dd =
(struct msm_watchdog_data *)dev_get_drvdata(dev);
- if (!enable || wdog_dd->wakeup_irq_enable)
+ if (!enable)
+ return 0;
+ if (wdog_dd->wakeup_irq_enable) {
+ __raw_writel(1, wdog_dd->base + WDT0_RST);
+ /* Make sure register write is complete before proceeding */
+ mb();
+ wdog_dd->last_pet = sched_clock();
return 0;
+ }
__raw_writel(1, wdog_dd->base + WDT0_EN);
__raw_writel(1, wdog_dd->base + WDT0_RST);
mb();
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 1b4fb562ce4b..927c84ea4921 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -39,6 +39,7 @@
#define DWC3_MSG_MAX 500
/* Global constants */
+#define DWC3_ZLP_BUF_SIZE 1024 /* size of a superspeed bulk */
#define DWC3_EP0_BOUNCE_SIZE 512
#define DWC3_ENDPOINTS_NUM 32
#define DWC3_XHCI_RESOURCES_NUM 2
@@ -748,6 +749,7 @@ struct dwc3_scratchpad_array {
* @ctrl_req: usb control request which is used for ep0
* @ep0_trb: trb which is used for the ctrl_req
* @ep0_bounce: bounce buffer for ep0
+ * @zlp_buf: used when request->zero is set
* @setup_buf: used while precessing STD USB requests
* @ctrl_req_addr: dma address of ctrl_req
* @ep0_trb: dma address of ep0_trb
@@ -853,6 +855,7 @@ struct dwc3 {
struct usb_ctrlrequest *ctrl_req;
struct dwc3_trb *ep0_trb;
void *ep0_bounce;
+ void *zlp_buf;
void *scratchbuf;
u8 *setup_buf;
dma_addr_t ctrl_req_addr;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 658fcca485d8..94709587f238 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1340,6 +1340,32 @@ static bool dwc3_gadget_is_suspended(struct dwc3 *dwc)
return false;
}
+static void __dwc3_gadget_ep_zlp_complete(struct usb_ep *ep,
+ struct usb_request *request)
+{
+ dwc3_gadget_ep_free_request(ep, request);
+}
+
+static int __dwc3_gadget_ep_queue_zlp(struct dwc3 *dwc, struct dwc3_ep *dep)
+{
+ struct dwc3_request *req;
+ struct usb_request *request;
+ struct usb_ep *ep = &dep->endpoint;
+
+ dwc3_trace(trace_dwc3_gadget, "queueing ZLP\n");
+ request = dwc3_gadget_ep_alloc_request(ep, GFP_ATOMIC);
+ if (!request)
+ return -ENOMEM;
+
+ request->length = 0;
+ request->buf = dwc->zlp_buf;
+ request->complete = __dwc3_gadget_ep_zlp_complete;
+
+ req = to_dwc3_request(request);
+
+ return __dwc3_gadget_ep_queue(dep, req);
+}
+
static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
gfp_t gfp_flags)
{
@@ -1387,6 +1413,16 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
ret = __dwc3_gadget_ep_queue(dep, req);
+ /*
+ * Okay, here's the thing, if gadget driver has requested for a ZLP by
+ * setting request->zero, instead of doing magic, we will just queue an
+ * extra usb_request ourselves so that it gets handled the same way as
+ * any other request.
+ */
+ if (ret == 0 && request->zero && request->length &&
+ (request->length % ep->maxpacket == 0))
+ ret = __dwc3_gadget_ep_queue_zlp(dwc, dep);
+
out:
spin_unlock_irqrestore(&dwc->lock, flags);
@@ -3554,6 +3590,12 @@ int dwc3_gadget_init(struct dwc3 *dwc)
goto err3;
}
+ dwc->zlp_buf = kzalloc(DWC3_ZLP_BUF_SIZE, GFP_KERNEL);
+ if (!dwc->zlp_buf) {
+ ret = -ENOMEM;
+ goto err4;
+ }
+
dwc->gadget.ops = &dwc3_gadget_ops;
dwc->gadget.speed = USB_SPEED_UNKNOWN;
dwc->gadget.sg_supported = true;
@@ -3595,12 +3637,12 @@ int dwc3_gadget_init(struct dwc3 *dwc)
ret = dwc3_gadget_init_endpoints(dwc);
if (ret)
- goto err4;
+ goto err5;
ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget);
if (ret) {
dev_err(dwc->dev, "failed to register udc\n");
- goto err4;
+ goto err5;
}
if (!dwc->is_drd) {
@@ -3612,6 +3654,9 @@ int dwc3_gadget_init(struct dwc3 *dwc)
return 0;
+err5:
+ kfree(dwc->zlp_buf);
+
err4:
dwc3_gadget_free_endpoints(dwc);
dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
@@ -3649,6 +3694,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
dwc->ep0_bounce, dwc->ep0_bounce_addr);
kfree(dwc->setup_buf);
+ kfree(dwc->zlp_buf);
dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2,
dwc->ep0_trb, dwc->ep0_trb_addr);
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index eeccae8bfc1b..442d44278f33 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -35,7 +35,8 @@
(speed == USB_SPEED_SUPER ?\
SSUSB_GADGET_VBUS_DRAW : CONFIG_USB_GADGET_VBUS_DRAW)
-static bool disable_l1_for_hs;
+/* disable LPM by default */
+static bool disable_l1_for_hs = true;
module_param(disable_l1_for_hs, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(disable_l1_for_hs,
"Disable support for L1 LPM for HS devices");
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 3f1c2b32abb8..0cbe95304417 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -1702,7 +1702,6 @@ static void usbpd_sm(struct work_struct *w)
if (pd->current_pr == PR_SINK) {
usbpd_set_state(pd, PE_SNK_STARTUP);
} else if (pd->current_pr == PR_SRC) {
- enable_vbus(pd);
if (!pd->vconn_enabled &&
pd->typec_mode ==
POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE) {
@@ -1712,6 +1711,7 @@ static void usbpd_sm(struct work_struct *w)
else
pd->vconn_enabled = true;
}
+ enable_vbus(pd);
usbpd_set_state(pd, PE_SRC_STARTUP);
}
diff --git a/drivers/video/fbdev/msm/mdss_dba_utils.c b/drivers/video/fbdev/msm/mdss_dba_utils.c
index c6ff92ed1686..3330f8f62b78 100644
--- a/drivers/video/fbdev/msm/mdss_dba_utils.c
+++ b/drivers/video/fbdev/msm/mdss_dba_utils.c
@@ -576,6 +576,7 @@ int mdss_dba_utils_video_on(void *data, struct mdss_panel_info *pinfo)
video_cfg.h_pulse_width = pinfo->lcdc.h_pulse_width;
video_cfg.v_pulse_width = pinfo->lcdc.v_pulse_width;
video_cfg.pclk_khz = (unsigned long)pinfo->clk_rate / 1000;
+ video_cfg.hdmi_mode = !hdmi_edid_is_dvi_mode(ud->edid_data);
/* Calculate number of DSI lanes configured */
video_cfg.num_of_input_lanes = 0;
@@ -591,8 +592,6 @@ int mdss_dba_utils_video_on(void *data, struct mdss_panel_info *pinfo)
/* Get scan information from EDID */
video_cfg.vic = mdss_dba_get_vic_panel_info(ud, pinfo);
ud->current_vic = video_cfg.vic;
- video_cfg.hdmi_mode = hdmi_edid_get_sink_mode(ud->edid_data,
- video_cfg.vic);
video_cfg.scaninfo = hdmi_edid_get_sink_scaninfo(ud->edid_data,
video_cfg.vic);
if (ud->ops.video_on)
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index 89ec73c21630..a98e5a9007bd 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -1094,8 +1094,14 @@ static int dp_audio_info_setup(struct platform_device *pdev,
struct mdss_dp_drv_pdata *dp_ctrl = platform_get_drvdata(pdev);
if (!dp_ctrl || !params) {
- DEV_ERR("%s: invalid input\n", __func__);
- return -ENODEV;
+ pr_err("invalid input\n");
+ rc = -ENODEV;
+ goto end;
+ }
+
+ if (!dp_ctrl->power_on) {
+ pr_debug("DP is already power off\n");
+ goto end;
}
mdss_dp_audio_setup_sdps(&dp_ctrl->ctrl_io, params->num_of_channels);
@@ -1103,6 +1109,7 @@ static int dp_audio_info_setup(struct platform_device *pdev,
mdss_dp_set_safe_to_exit_level(&dp_ctrl->ctrl_io, dp_ctrl->lane_cnt);
mdss_dp_audio_enable(&dp_ctrl->ctrl_io, true);
+end:
return rc;
} /* dp_audio_info_setup */
@@ -1134,6 +1141,11 @@ static void dp_audio_teardown_done(struct platform_device *pdev)
return;
}
+ if (!dp->power_on) {
+ pr_err("DP is already power off\n");
+ return;
+ }
+
mdss_dp_audio_enable(&dp->ctrl_io, false);
/* Make sure the DP audio engine is disabled */
wmb();
diff --git a/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c b/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c
index 5a677dfe7484..36a062dc5207 100644
--- a/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c
+++ b/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c
@@ -894,22 +894,24 @@ static bool dp_hdcp2p2_supported(struct dp_hdcp2p2_ctrl *ctrl)
{
struct edp_cmd cmd = {0};
const u32 offset = 0x6921d;
- u8 buf;
+ u8 buf[3];
cmd.read = 1;
cmd.addr = offset;
- cmd.len = sizeof(buf);
- cmd.out_buf = &buf;
+ cmd.len = ARRAY_SIZE(buf);
+ cmd.out_buf = buf;
if (dp_aux_read(ctrl->init_data.cb_data, &cmd)) {
pr_err("RxCaps read failed\n");
goto error;
}
- pr_debug("rxcaps 0x%x\n", buf);
+ pr_debug("HDCP_CAPABLE=%lu\n", (buf[2] & BIT(1)) >> 1);
+ pr_debug("VERSION=%d\n", buf[0]);
- if (buf & BIT(1))
+ if ((buf[2] & BIT(1)) && (buf[0] == 0x2))
return true;
+
error:
return false;
}
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.c b/drivers/video/fbdev/msm/mdss_hdmi_edid.c
index a953dd1a2ac2..abd2192997e5 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_edid.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.c
@@ -62,6 +62,11 @@
#define EDID_VENDOR_ID_SIZE 4
#define EDID_IEEE_REG_ID 0x0c03
+enum edid_sink_mode {
+ SINK_MODE_DVI,
+ SINK_MODE_HDMI
+};
+
enum luminance_value {
NO_LUMINANCE_DATA = 3,
MAXIMUM_LUMINANCE = 4,
@@ -2418,7 +2423,7 @@ end:
return scaninfo;
} /* hdmi_edid_get_sink_scaninfo */
-u32 hdmi_edid_get_sink_mode(void *input, u32 mode)
+static u32 hdmi_edid_get_sink_mode(void *input)
{
struct hdmi_edid_ctrl *edid_ctrl = (struct hdmi_edid_ctrl *)input;
bool sink_mode;
@@ -2431,13 +2436,8 @@ u32 hdmi_edid_get_sink_mode(void *input, u32 mode)
if (edid_ctrl->edid_override &&
(edid_ctrl->override_data.sink_mode != -1))
sink_mode = edid_ctrl->override_data.sink_mode;
- else {
- if (edid_ctrl->sink_mode &&
- (mode > 0 && mode <= HDMI_EVFRMT_END))
- sink_mode = SINK_MODE_HDMI;
- else
- sink_mode = SINK_MODE_DVI;
- }
+ else
+ sink_mode = edid_ctrl->sink_mode;
return sink_mode;
} /* hdmi_edid_get_sink_mode */
@@ -2452,21 +2452,10 @@ u32 hdmi_edid_get_sink_mode(void *input, u32 mode)
*/
bool hdmi_edid_is_dvi_mode(void *input)
{
- struct hdmi_edid_ctrl *edid_ctrl = (struct hdmi_edid_ctrl *)input;
- int sink_mode;
-
- if (!edid_ctrl) {
- DEV_ERR("%s: invalid input\n", __func__);
- return true;
- }
-
- if (edid_ctrl->edid_override &&
- (edid_ctrl->override_data.sink_mode != -1))
- sink_mode = edid_ctrl->override_data.sink_mode;
+ if (hdmi_edid_get_sink_mode(input))
+ return false;
else
- sink_mode = edid_ctrl->sink_mode;
-
- return (sink_mode == SINK_MODE_DVI);
+ return true;
}
/**
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.h b/drivers/video/fbdev/msm/mdss_hdmi_edid.h
index c604d0fbf7b2..af802bb45f89 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_edid.h
+++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.h
@@ -58,16 +58,10 @@ struct hdmi_edid_override_data {
int vic;
};
-enum edid_sink_mode {
- SINK_MODE_DVI,
- SINK_MODE_HDMI
-};
-
int hdmi_edid_parser(void *edid_ctrl);
u32 hdmi_edid_get_raw_data(void *edid_ctrl, u8 *buf, u32 size);
u8 hdmi_edid_get_sink_scaninfo(void *edid_ctrl, u32 resolution);
bool hdmi_edid_is_dvi_mode(void *input);
-u32 hdmi_edid_get_sink_mode(void *edid_ctrl, u32 mode);
bool hdmi_edid_sink_scramble_override(void *input);
bool hdmi_edid_get_sink_scrambler_support(void *input);
bool hdmi_edid_get_scdc_support(void *input);
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
index 2e267f2695d7..9ee0c27b225e 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c
@@ -375,12 +375,11 @@ static void hdmi_tx_audio_setup(struct hdmi_tx_ctrl *hdmi_ctrl)
}
}
-static inline bool hdmi_tx_is_dvi_mode(struct hdmi_tx_ctrl *hdmi_ctrl)
+static inline u32 hdmi_tx_is_dvi_mode(struct hdmi_tx_ctrl *hdmi_ctrl)
{
void *data = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID);
- return (hdmi_edid_get_sink_mode(data,
- hdmi_ctrl->vic) == SINK_MODE_DVI);
+ return hdmi_edid_is_dvi_mode(data);
} /* hdmi_tx_is_dvi_mode */
static inline u32 hdmi_tx_is_in_splash(struct hdmi_tx_ctrl *hdmi_ctrl)
@@ -2482,8 +2481,7 @@ static void hdmi_tx_set_mode(struct hdmi_tx_ctrl *hdmi_ctrl, u32 power_on)
hdmi_ctrl_reg |= BIT(2);
/* Set transmission mode to DVI based in EDID info */
- if (hdmi_edid_get_sink_mode(data,
- hdmi_ctrl->vic) == SINK_MODE_DVI)
+ if (hdmi_edid_is_dvi_mode(data))
hdmi_ctrl_reg &= ~BIT(1); /* DVI mode */
/*
@@ -2942,6 +2940,7 @@ static int hdmi_tx_audio_info_setup(struct platform_device *pdev,
{
int rc = 0;
struct hdmi_tx_ctrl *hdmi_ctrl = platform_get_drvdata(pdev);
+ u32 is_mode_dvi;
if (!hdmi_ctrl || !params) {
DEV_ERR("%s: invalid input\n", __func__);
@@ -2950,8 +2949,9 @@ static int hdmi_tx_audio_info_setup(struct platform_device *pdev,
mutex_lock(&hdmi_ctrl->tx_lock);
- if (!hdmi_tx_is_dvi_mode(hdmi_ctrl) &&
- hdmi_tx_is_panel_on(hdmi_ctrl)) {
+ is_mode_dvi = hdmi_tx_is_dvi_mode(hdmi_ctrl);
+
+ if (!is_mode_dvi && hdmi_tx_is_panel_on(hdmi_ctrl)) {
memcpy(&hdmi_ctrl->audio_params, params,
sizeof(struct msm_ext_disp_audio_setup_params));
diff --git a/fs/Kconfig b/fs/Kconfig
index a5d2dc39ba07..4adb93ec85ea 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -282,4 +282,9 @@ endif # NETWORK_FILESYSTEMS
source "fs/nls/Kconfig"
source "fs/dlm/Kconfig"
+config FILE_TABLE_DEBUG
+ bool "Enable FILE_TABLE_DEBUG"
+ help
+ This option enables debug of the open files using a global filetable
+
endmenu
diff --git a/fs/file_table.c b/fs/file_table.c
index ad17e05ebf95..b4baa0de4988 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -41,6 +41,141 @@ static struct kmem_cache *filp_cachep __read_mostly;
static struct percpu_counter nr_files __cacheline_aligned_in_smp;
+#ifdef CONFIG_FILE_TABLE_DEBUG
+#include <linux/hashtable.h>
+#include <mount.h>
+static DEFINE_MUTEX(global_files_lock);
+static DEFINE_HASHTABLE(global_files_hashtable, 10);
+
+struct global_filetable_lookup_key {
+ struct work_struct work;
+ uintptr_t value;
+};
+
+void global_filetable_print_warning_once(void)
+{
+ pr_err_once("\n**********************************************************\n");
+ pr_err_once("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n");
+ pr_err_once("** **\n");
+ pr_err_once("** VFS FILE TABLE DEBUG is enabled . **\n");
+ pr_err_once("** Allocating extra memory and slowing access to files **\n");
+ pr_err_once("** **\n");
+ pr_err_once("** This means that this is a DEBUG kernel and it is **\n");
+ pr_err_once("** unsafe for production use. **\n");
+ pr_err_once("** **\n");
+ pr_err_once("** If you see this message and you are not debugging **\n");
+ pr_err_once("** the kernel, report this immediately to your vendor! **\n");
+ pr_err_once("** **\n");
+ pr_err_once("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n");
+ pr_err_once("**********************************************************\n");
+}
+
+void global_filetable_add(struct file *filp)
+{
+ struct mount *mnt;
+
+ if (filp->f_path.dentry->d_iname == NULL ||
+ strlen(filp->f_path.dentry->d_iname) == 0)
+ return;
+
+ mnt = real_mount(filp->f_path.mnt);
+
+ mutex_lock(&global_files_lock);
+ hash_add(global_files_hashtable, &filp->f_hash, (uintptr_t)mnt);
+ mutex_unlock(&global_files_lock);
+}
+
+void global_filetable_del(struct file *filp)
+{
+ mutex_lock(&global_files_lock);
+ hash_del(&filp->f_hash);
+ mutex_unlock(&global_files_lock);
+}
+
+static void global_print_file(struct file *filp, char *path_buffer, int *count)
+{
+ char *pathname;
+
+ pathname = d_path(&filp->f_path, path_buffer, PAGE_SIZE);
+ if (IS_ERR(pathname))
+ pr_err("VFS: File %d Address : %pa partial filename: %s ref_count=%ld\n",
+ ++(*count), &filp, filp->f_path.dentry->d_iname,
+ atomic_long_read(&filp->f_count));
+ else
+ pr_err("VFS: File %d Address : %pa full filepath: %s ref_count=%ld\n",
+ ++(*count), &filp, pathname,
+ atomic_long_read(&filp->f_count));
+}
+
+static void global_filetable_print(uintptr_t lookup_mnt)
+{
+ struct hlist_node *tmp;
+ struct file *filp;
+ struct mount *mnt;
+ int index;
+ int count = 0;
+ char *path_buffer = (char *)__get_free_page(GFP_TEMPORARY);
+
+ mutex_lock(&global_files_lock);
+ pr_err("\n**********************************************************\n");
+ pr_err("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n");
+
+ pr_err("\n");
+ pr_err("VFS: The following files hold a reference to the mount\n");
+ pr_err("\n");
+ hash_for_each_possible_safe(global_files_hashtable, filp, tmp, f_hash,
+ lookup_mnt) {
+ mnt = real_mount(filp->f_path.mnt);
+ if ((uintptr_t)mnt == lookup_mnt)
+ global_print_file(filp, path_buffer, &count);
+ }
+ pr_err("\n");
+ pr_err("VFS: Found total of %d open files\n", count);
+ pr_err("\n");
+
+ count = 0;
+ pr_err("\n");
+ pr_err("VFS: The following files need to cleaned up\n");
+ pr_err("\n");
+ hash_for_each_safe(global_files_hashtable, index, tmp, filp, f_hash) {
+ if (atomic_long_read(&filp->f_count) == 0)
+ global_print_file(filp, path_buffer, &count);
+ }
+
+ pr_err("\n");
+ pr_err("VFS: Found total of %d files awaiting clean-up\n", count);
+ pr_err("\n");
+ pr_err("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n");
+ pr_err("\n**********************************************************\n");
+
+ mutex_unlock(&global_files_lock);
+ free_page((unsigned long)path_buffer);
+}
+
+static void global_filetable_print_work_fn(struct work_struct *work)
+{
+ struct global_filetable_lookup_key *key;
+ uintptr_t lookup_mnt;
+
+ key = container_of(work, struct global_filetable_lookup_key, work);
+ lookup_mnt = key->value;
+ kfree(key);
+ global_filetable_print(lookup_mnt);
+}
+
+void global_filetable_delayed_print(struct mount *mnt)
+{
+ struct global_filetable_lookup_key *key;
+
+ key = kzalloc(sizeof(*key), GFP_KERNEL);
+ if (key == NULL)
+ return;
+ key->value = (uintptr_t)mnt;
+ INIT_WORK(&key->work, global_filetable_print_work_fn);
+ schedule_work(&key->work);
+}
+#endif /* CONFIG_FILE_TABLE_DEBUG */
+
static void file_free_rcu(struct rcu_head *head)
{
struct file *f = container_of(head, struct file, f_u.fu_rcuhead);
@@ -219,6 +354,7 @@ static void __fput(struct file *file)
put_write_access(inode);
__mnt_drop_write(mnt);
}
+ global_filetable_del(file);
file->f_path.dentry = NULL;
file->f_path.mnt = NULL;
file->f_inode = NULL;
@@ -314,6 +450,7 @@ void __init files_init(void)
filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0,
SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
percpu_counter_init(&nr_files, 0, GFP_KERNEL);
+ global_filetable_print_warning_once();
}
/*
diff --git a/fs/internal.h b/fs/internal.h
index 6387b35a1c0d..1b93a3929b16 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -153,3 +153,29 @@ extern void mnt_pin_kill(struct mount *m);
* fs/nsfs.c
*/
extern struct dentry_operations ns_dentry_operations;
+
+#ifdef CONFIG_FILE_TABLE_DEBUG
+void global_filetable_print_warning_once(void);
+void global_filetable_add(struct file *filp);
+void global_filetable_del(struct file *filp);
+void global_filetable_delayed_print(struct mount *mnt);
+
+#else /* i.e NOT CONFIG_FILE_TABLE_DEBUG */
+
+static inline void global_filetable_print_warning_once(void)
+{
+}
+
+static inline void global_filetable_add(struct file *filp)
+{
+}
+
+static inline void global_filetable_del(struct file *filp)
+{
+}
+
+static inline void global_filetable_delayed_print(struct mount *mnt)
+{
+}
+
+#endif /* CONFIG_FILE_TABLE_DEBUG */
diff --git a/fs/namei.c b/fs/namei.c
index 816b6e8e934e..b5dfe2c5b51e 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3379,6 +3379,8 @@ out2:
error = -ESTALE;
}
file = ERR_PTR(error);
+ } else {
+ global_filetable_add(file);
}
return file;
}
diff --git a/fs/namespace.c b/fs/namespace.c
index a22959c97384..0f52d90c356f 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1595,6 +1595,8 @@ static int do_umount(struct mount *mnt, int flags)
}
unlock_mount_hash();
namespace_unlock();
+ if (retval == -EBUSY)
+ global_filetable_delayed_print(mnt);
return retval;
}
diff --git a/include/dt-bindings/clock/msm-clocks-8998.h b/include/dt-bindings/clock/msm-clocks-8998.h
index cd36374a04a7..67e47c46e09a 100644
--- a/include/dt-bindings/clock/msm-clocks-8998.h
+++ b/include/dt-bindings/clock/msm-clocks-8998.h
@@ -443,6 +443,11 @@
#define clk_dsi0pll_pclk_src 0x5efd85d4
#define clk_dsi0pll_pclk_src_mux 0x84b14663
#define clk_dsi0pll_post_bit_div 0xf46dcf27
+#define clk_dsi0pll_pll_out_div1 0xeda5b7fe
+#define clk_dsi0pll_pll_out_div2 0x97fa476d
+#define clk_dsi0pll_pll_out_div4 0x90a98ce0
+#define clk_dsi0pll_pll_out_div8 0x9d9d85cf
+#define clk_dsi0pll_pll_out_mux 0x179c27ca
#define clk_dsi0pll_post_vco_mux 0xfaf9bd1f
#define clk_dsi0pll_post_vco_div1 0xabb50b2a
#define clk_dsi0pll_post_vco_div4 0xbe51c091
@@ -455,6 +460,11 @@
#define clk_dsi1pll_pclk_src 0xeddcd80e
#define clk_dsi1pll_pclk_src_mux 0x3651feb3
#define clk_dsi1pll_post_bit_div 0x712f0260
+#define clk_dsi1pll_pll_out_div8 0x87628ddb
+#define clk_dsi1pll_pll_out_div4 0x0d9a384b
+#define clk_dsi1pll_pll_out_div2 0x0c9b5748
+#define clk_dsi1pll_pll_out_div1 0x3193164e
+#define clk_dsi1pll_pll_out_mux 0x171bf8fd
#define clk_dsi1pll_post_vco_mux 0xc6a90d20
#define clk_dsi1pll_post_vco_div1 0x6f47ca7d
#define clk_dsi1pll_post_vco_div4 0x90628974
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 4b27be2038e3..df1171bada01 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -912,6 +912,10 @@ struct file {
struct list_head f_tfile_llink;
#endif /* #ifdef CONFIG_EPOLL */
struct address_space *f_mapping;
+
+#ifdef CONFIG_FILE_TABLE_DEBUG
+ struct hlist_node f_hash;
+#endif /* #ifdef CONFIG_FILE_TABLE_DEBUG */
} __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
struct file_handle {
diff --git a/sound/soc/msm/apq8096-auto.c b/sound/soc/msm/apq8096-auto.c
index b6121d75c148..2ae78f75c340 100644
--- a/sound/soc/msm/apq8096-auto.c
+++ b/sound/soc/msm/apq8096-auto.c
@@ -3044,21 +3044,22 @@ static struct snd_soc_dai_link apq8096_common_dai_links[] = {
.codec_name = "snd-soc-dummy",
},
{
- .name = "SLIMBUS_4 Hostless",
- .stream_name = "SLIMBUS_4 Hostless",
- .cpu_dai_name = "SLIMBUS4_HOSTLESS",
- .platform_name = "msm-pcm-hostless",
+ .name = "MSM8996 HFP RX",
+ .stream_name = "MultiMedia21",
+ .cpu_dai_name = "MultiMedia21",
+ .platform_name = "msm-pcm-loopback",
.dynamic = 1,
.dpcm_playback = 1,
.dpcm_capture = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
- .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
.ignore_suspend = 1,
- /* this dailink has playback support */
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ /* this dainlink has playback support */
.ignore_pmdown_time = 1,
- .codec_dai_name = "snd-soc-dummy-dai",
- .codec_name = "snd-soc-dummy",
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA21,
},
{
.name = "VoLTE",
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index cc89408fcb39..468afdc81424 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -2656,6 +2656,20 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.rate_min = 8000,
.rate_max = 384000,
},
+ .capture = {
+ .stream_name = "MultiMedia21 Capture",
+ .aif_name = "MM_UL21",
+ .rates = (SNDRV_PCM_RATE_8000_48000|
+ SNDRV_PCM_RATE_KNOT),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
+ .channels_min = 1,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
.ops = &msm_fe_Multimedia_dai_ops,
.name = "MultiMedia21",
.probe = fe_dai_probe,
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 2bf61521ad52..b99549d62e8a 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -605,6 +605,21 @@ static struct msm_pcm_routing_fdai_data
/* MULTIMEDIA20 */
{{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* MULTIMEDIA21 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* MULTIMEDIA22 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* MULTIMEDIA23 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* MULTIMEDIA24 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* MULTIMEDIA25 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
/* CS_VOICE */
{{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
@@ -5227,6 +5242,9 @@ static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_AUXPCM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = {
@@ -5287,6 +5305,9 @@ static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new tert_auxpcm_rx_mixer_controls[] = {
@@ -5440,6 +5461,9 @@ static const struct snd_kcontrol_new pri_tdm_rx_0_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_0,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = {
@@ -5491,6 +5515,9 @@ static const struct snd_kcontrol_new pri_tdm_rx_1_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_1,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = {
@@ -5542,6 +5569,9 @@ static const struct snd_kcontrol_new pri_tdm_rx_2_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_2,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = {
@@ -5593,6 +5623,9 @@ static const struct snd_kcontrol_new pri_tdm_rx_3_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_PRI_TDM_RX_3,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new pri_tdm_tx_0_mixer_controls[] = {
@@ -5695,6 +5728,9 @@ static const struct snd_kcontrol_new sec_tdm_rx_0_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_0,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = {
@@ -5746,6 +5782,9 @@ static const struct snd_kcontrol_new sec_tdm_rx_1_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_1,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_SEC_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = {
@@ -5797,6 +5836,9 @@ static const struct snd_kcontrol_new sec_tdm_rx_2_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_2,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_SEC_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = {
@@ -5848,6 +5890,9 @@ static const struct snd_kcontrol_new sec_tdm_rx_3_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SEC_TDM_RX_3,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_SEC_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new sec_tdm_tx_0_mixer_controls[] = {
@@ -5950,6 +5995,9 @@ static const struct snd_kcontrol_new tert_tdm_rx_0_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_RX_0,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_TERT_TDM_RX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new tert_tdm_tx_0_mixer_controls[] = {
@@ -6052,6 +6100,9 @@ static const struct snd_kcontrol_new tert_tdm_rx_1_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_RX_1,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_TERT_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = {
@@ -6103,6 +6154,9 @@ static const struct snd_kcontrol_new tert_tdm_rx_2_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_RX_2,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_TERT_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = {
@@ -6154,6 +6208,9 @@ static const struct snd_kcontrol_new tert_tdm_rx_3_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_RX_3,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_TERT_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = {
@@ -6205,6 +6262,9 @@ static const struct snd_kcontrol_new tert_tdm_rx_4_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERT_TDM_RX_4,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_TERT_TDM_RX_4,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = {
@@ -6259,6 +6319,9 @@ static const struct snd_kcontrol_new quat_tdm_rx_0_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUAT_TDM_RX_0,
MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_QUAT_TDM_RX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new quat_tdm_tx_0_mixer_controls[] = {
@@ -6364,6 +6427,9 @@ static const struct snd_kcontrol_new quat_tdm_rx_1_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUAT_TDM_RX_1,
MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_QUAT_TDM_RX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = {
@@ -6418,6 +6484,9 @@ static const struct snd_kcontrol_new quat_tdm_rx_2_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUAT_TDM_RX_2,
MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_QUAT_TDM_RX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = {
@@ -6472,6 +6541,9 @@ static const struct snd_kcontrol_new quat_tdm_rx_3_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia20", MSM_BACKEND_DAI_QUAT_TDM_RX_3,
MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia21", MSM_BACKEND_DAI_QUAT_TDM_RX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
@@ -7350,6 +7422,63 @@ static const struct snd_kcontrol_new mmul20_mixer_controls[] = {
msm_routing_put_audio_mixer),
};
+static const struct snd_kcontrol_new mmul21_mixer_controls[] = {
+ SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_AUXPCM_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_0", MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_1", MSM_BACKEND_DAI_PRI_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_0", MSM_BACKEND_DAI_SEC_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_1", MSM_BACKEND_DAI_SEC_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_2", MSM_BACKEND_DAI_SEC_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("SEC_TDM_TX_3", MSM_BACKEND_DAI_SEC_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA21, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_I2S_RX,
MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
@@ -11470,6 +11599,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
SND_SOC_DAPM_AIF_OUT("MM_UL18", "MultiMedia18 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL19", "MultiMedia19 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MM_UL20", "MultiMedia20 Capture", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("MM_UL21", "MultiMedia21 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("CS-VOICE_DL1", "CS-VOICE Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("VOICE2_DL", "Voice2 Playback", 0, 0, 0, 0),
@@ -12210,6 +12340,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
mmul19_mixer_controls, ARRAY_SIZE(mmul19_mixer_controls)),
SND_SOC_DAPM_MIXER("MultiMedia20 Mixer", SND_SOC_NOPM, 0, 0,
mmul20_mixer_controls, ARRAY_SIZE(mmul20_mixer_controls)),
+ SND_SOC_DAPM_MIXER("MultiMedia21 Mixer", SND_SOC_NOPM, 0, 0,
+ mmul21_mixer_controls, ARRAY_SIZE(mmul21_mixer_controls)),
SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
@@ -12964,6 +13096,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"PRI_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"},
{"PRI_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"PRI_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Audio Mixer"},
{"PRI_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -12982,6 +13115,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"PRI_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"},
{"PRI_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"PRI_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"PRI_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"PRI_TDM_RX_1", NULL, "PRI_TDM_RX_1 Audio Mixer"},
{"PRI_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13000,6 +13134,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"PRI_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"},
{"PRI_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"PRI_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"PRI_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"PRI_TDM_RX_2", NULL, "PRI_TDM_RX_2 Audio Mixer"},
{"PRI_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13018,6 +13153,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"PRI_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"},
{"PRI_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"PRI_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"PRI_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Audio Mixer"},
{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13054,6 +13190,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SEC_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"},
{"SEC_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"SEC_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Audio Mixer"},
{"SEC_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13072,6 +13209,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SEC_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"},
{"SEC_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"SEC_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SEC_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"SEC_TDM_RX_1", NULL, "SEC_TDM_RX_1 Audio Mixer"},
{"SEC_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13090,6 +13228,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SEC_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"},
{"SEC_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"SEC_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SEC_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"SEC_TDM_RX_2", NULL, "SEC_TDM_RX_2 Audio Mixer"},
{"SEC_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13108,6 +13247,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SEC_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"},
{"SEC_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"SEC_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SEC_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Audio Mixer"},
{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13144,6 +13284,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"TERT_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"},
{"TERT_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"TERT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"TERT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Audio Mixer"},
{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13180,6 +13321,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"TERT_TDM_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"},
{"TERT_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"TERT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"TERT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"TERT_TDM_RX_1", NULL, "TERT_TDM_RX_1 Audio Mixer"},
{"TERT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13198,6 +13340,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"TERT_TDM_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"},
{"TERT_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"TERT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"TERT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"TERT_TDM_RX_2", NULL, "TERT_TDM_RX_2 Audio Mixer"},
{"TERT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13216,6 +13359,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"TERT_TDM_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"},
{"TERT_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"TERT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"TERT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"TERT_TDM_RX_3", NULL, "TERT_TDM_RX_3 Audio Mixer"},
{"TERT_TDM_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13234,6 +13378,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"TERT_TDM_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"},
{"TERT_TDM_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"TERT_TDM_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"TERT_TDM_RX_4 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"TERT_TDM_RX_4", NULL, "TERT_TDM_RX_4 Audio Mixer"},
{"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13253,6 +13398,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"},
{"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia20", "MM_DL20"},
+ {"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Audio Mixer"},
{"PRI_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13326,6 +13472,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"},
{"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia20", "MM_DL20"},
+ {"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"QUAT_TDM_RX_1", NULL, "QUAT_TDM_RX_1 Audio Mixer"},
{"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13345,6 +13492,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"},
{"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia20", "MM_DL20"},
+ {"QUAT_TDM_RX_2 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2 Audio Mixer"},
{"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13364,6 +13512,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"},
{"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"},
{"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia20", "MM_DL20"},
+ {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia21", "MM_DL21"},
{"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Audio Mixer"},
{"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
@@ -13566,6 +13715,25 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MultiMedia20 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
{"MultiMedia20 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"MultiMedia21 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
+ {"MultiMedia21 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
+ {"MultiMedia21 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"MultiMedia21 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
+ {"MultiMedia21 Mixer", "SEC_TDM_TX_0", "SEC_TDM_TX_0"},
+ {"MultiMedia21 Mixer", "SEC_TDM_TX_1", "SEC_TDM_TX_1"},
+ {"MultiMedia21 Mixer", "SEC_TDM_TX_2", "SEC_TDM_TX_2"},
+ {"MultiMedia21 Mixer", "SEC_TDM_TX_3", "SEC_TDM_TX_3"},
+ {"MultiMedia21 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
+ {"MultiMedia21 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
+ {"MultiMedia21 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"},
+ {"MultiMedia21 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"},
+ {"MultiMedia21 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"},
+ {"MultiMedia21 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
+ {"MultiMedia21 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
+ {"MultiMedia21 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
+ {"MultiMedia21 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+ {"MultiMedia21 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
+
{"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"},
{"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"},
{"MultiMedia4 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"},
@@ -13685,6 +13853,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"MM_UL18", NULL, "MultiMedia18 Mixer"},
{"MM_UL19", NULL, "MultiMedia19 Mixer"},
{"MM_UL20", NULL, "MultiMedia20 Mixer"},
+ {"MM_UL21", NULL, "MultiMedia21 Mixer"},
{"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
@@ -13702,6 +13871,9 @@ static const struct snd_soc_dapm_route intercon[] = {
{"AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
{"AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
{"AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"AUX_PCM_RX Audio Mixer", "MultiMedia21", "MM_DL21"},
+ {"AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_UL6"},
+ {"AUX_PCM_RX Audio Mixer", "MultiMedia21", "MM_UL21"},
{"AUX_PCM_RX", NULL, "AUX_PCM_RX Audio Mixer"},
{"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -13720,6 +13892,9 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
{"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
{"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia21", "MM_DL21"},
+ {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia6", "MM_UL6"},
+ {"SEC_AUX_PCM_RX Audio Mixer", "MultiMedia21", "MM_UL21"},
{"SEC_AUX_PCM_RX", NULL, "SEC_AUX_PCM_RX Audio Mixer"},
{"TERT_AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
diff --git a/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c
index 6bb85ca8e84e..5c5f7bc482c8 100644
--- a/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-transcode-loopback-q6-v2.c
@@ -100,7 +100,7 @@ static void loopback_event_handler(uint32_t opcode,
return;
}
- cstream = trans->source.cstream;
+ cstream = trans->sink.cstream;
ac = trans->audio_client;
/*
@@ -223,6 +223,7 @@ static int msm_transcode_loopback_open(struct snd_compr_stream *cstream)
ret = -EINVAL;
goto exit;
}
+ msm_adsp_init_mixer_ctl_pp_event_queue(rtd);
}
pr_debug("%s: num stream%d, stream name %s\n", __func__,
@@ -237,8 +238,7 @@ static int msm_transcode_loopback_open(struct snd_compr_stream *cstream)
}
runtime->private_data = trans;
- if (trans->num_streams == 1)
- msm_adsp_init_mixer_ctl_pp_event_queue(rtd);
+
exit:
mutex_unlock(&trans->lock);
return ret;
@@ -283,14 +283,14 @@ static int msm_transcode_loopback_free(struct snd_compr_stream *cstream)
trans->num_streams--;
stop_transcoding(trans);
- if (cstream->direction == SND_COMPRESS_PLAYBACK)
+ if (cstream->direction == SND_COMPRESS_PLAYBACK) {
memset(&trans->sink, 0, sizeof(struct loopback_stream));
- else if (cstream->direction == SND_COMPRESS_CAPTURE)
+ msm_adsp_clean_mixer_ctl_pp_event_queue(rtd);
+ } else if (cstream->direction == SND_COMPRESS_CAPTURE) {
memset(&trans->source, 0, sizeof(struct loopback_stream));
+ }
trans->session_state = LOOPBACK_SESSION_CLOSE;
- if (trans->num_streams == 1)
- msm_adsp_clean_mixer_ctl_pp_event_queue(rtd);
mutex_unlock(&trans->lock);
return ret;
}