diff options
32 files changed, 240 insertions, 110 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 25fa0ede0d1b..553f545ece19 100755 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1247,6 +1247,16 @@ config ARM_ERRATA_754327 This workaround defines cpu_relax() as smp_mb(), preventing correctly written polling loops from denying visibility of updates to memory. +config ARM_ERRATA_775420 + bool "ARM errata: A data cache maintenance operation which aborts, might lead to deadlock" + depends on CPU_V7 + help + This option enables the workaround for the 775420 Cortex-A9 (r2p2, + r2p6,r2p8,r2p10,r3p0) erratum. In case a date cache maintenance + operation aborts with MMU exception, it might cause the processor + to deadlock. This workaround puts DSB before executing ISB if + an abort may occur on cache maintenance. + endmenu source "arch/arm/common/Kconfig" diff --git a/arch/arm/configs/imx6_defconfig b/arch/arm/configs/imx6_defconfig index 5ad4a002676d..b6fd6b6810a5 100644 --- a/arch/arm/configs/imx6_defconfig +++ b/arch/arm/configs/imx6_defconfig @@ -382,6 +382,7 @@ CONFIG_ARM_ERRATA_751472=y # CONFIG_ARM_ERRATA_753970 is not set CONFIG_ARM_ERRATA_754322=y # CONFIG_ARM_ERRATA_754327 is not set +CONFIG_ARM_ERRATA_775420=y CONFIG_ARM_GIC=y # @@ -392,7 +393,7 @@ CONFIG_ARM_AMBA=y # CONFIG_ARCH_SUPPORTS_MSI is not set # CONFIG_PCCARD is not set CONFIG_ARM_ERRATA_764369=y -# CONFIG_PL310_ERRATA_769419 is not set +CONFIG_PL310_ERRATA_769419=y # # Kernel Features diff --git a/arch/arm/configs/imx6_updater_defconfig b/arch/arm/configs/imx6_updater_defconfig index e562767d1133..2eea5275b841 100644 --- a/arch/arm/configs/imx6_updater_defconfig +++ b/arch/arm/configs/imx6_updater_defconfig @@ -391,6 +391,7 @@ CONFIG_ARM_ERRATA_751472=y # CONFIG_ARM_ERRATA_753970 is not set CONFIG_ARM_ERRATA_754322=y # CONFIG_ARM_ERRATA_754327 is not set +CONFIG_ARM_ERRATA_775420=y CONFIG_ARM_GIC=y # @@ -401,7 +402,7 @@ CONFIG_ARM_AMBA=y # CONFIG_ARCH_SUPPORTS_MSI is not set # CONFIG_PCCARD is not set # CONFIG_ARM_ERRATA_764369 is not set -# CONFIG_PL310_ERRATA_769419 is not set +CONFIG_PL310_ERRATA_769419=y # # Kernel Features diff --git a/arch/arm/configs/imx6s_defconfig b/arch/arm/configs/imx6s_defconfig index 1cae0463855e..14e9ba52ee0a 100644 --- a/arch/arm/configs/imx6s_defconfig +++ b/arch/arm/configs/imx6s_defconfig @@ -384,6 +384,7 @@ CONFIG_CPU_HAS_PMU=y CONFIG_ARM_ERRATA_743622=y # CONFIG_ARM_ERRATA_753970 is not set CONFIG_ARM_ERRATA_754322=y +CONFIG_ARM_ERRATA_775420=y CONFIG_ARM_GIC=y # diff --git a/arch/arm/configs/imx6s_updater_defconfig b/arch/arm/configs/imx6s_updater_defconfig index b80f40128dfc..3fffe50065f3 100644 --- a/arch/arm/configs/imx6s_updater_defconfig +++ b/arch/arm/configs/imx6s_updater_defconfig @@ -385,6 +385,7 @@ CONFIG_CPU_HAS_PMU=y CONFIG_ARM_ERRATA_743622=y # CONFIG_ARM_ERRATA_753970 is not set CONFIG_ARM_ERRATA_754322=y +CONFIG_ARM_ERRATA_775420=y CONFIG_ARM_GIC=y # diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.c b/arch/arm/mach-mx6/board-mx6sl_arm2.c index a29f3bcb9b07..09d3c182ec45 100755 --- a/arch/arm/mach-mx6/board-mx6sl_arm2.c +++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c @@ -877,6 +877,7 @@ static struct imx_epdc_fb_platform_data epdc_data = { .put_pins = epdc_put_pins, .enable_pins = epdc_enable_pins, .disable_pins = epdc_disable_pins, + .pg_display_mix = true, }; static int spdc_get_pins(void) @@ -1104,6 +1105,7 @@ static struct mxc_fb_platform_data fb_data[] = { .mode_str = "SEIKO-WVGA", .mode = video_modes, .num_modes = ARRAY_SIZE(video_modes), + .pg_display_mix = true, }, }; diff --git a/arch/arm/mach-mx6/board-mx6sl_evk.c b/arch/arm/mach-mx6/board-mx6sl_evk.c index adc8b463b78b..7561ba90fa15 100644 --- a/arch/arm/mach-mx6/board-mx6sl_evk.c +++ b/arch/arm/mach-mx6/board-mx6sl_evk.c @@ -1084,6 +1084,7 @@ static struct imx_epdc_fb_platform_data epdc_data = { .put_pins = epdc_put_pins, .enable_pins = epdc_enable_pins, .disable_pins = epdc_disable_pins, + .pg_display_mix = true, }; static int spdc_get_pins(void) @@ -1316,6 +1317,7 @@ static struct mxc_fb_platform_data wvga_fb_data[] = { .mode_str = "SEIKO-WVGA", .mode = wvga_video_modes, .num_modes = ARRAY_SIZE(wvga_video_modes), + .pg_display_mix = true, }, }; diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index 1bf20d5857c2..c69b4609d3f3 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -3788,6 +3788,17 @@ static struct clk enet_clk[] = { }, }; +static unsigned long _clk_enet_mdc_get_rate(struct clk *clk) +{ + return clk_get_rate(clk->parent); +} + +static struct clk enet_mdc_clk = { + __INIT_CLK_DEBUG(enet_mdc_clk) + .parent = &ipg_clk, + .get_rate = _clk_enet_mdc_get_rate, +}; + static struct clk ecspi_clk[] = { { __INIT_CLK_DEBUG(ecspi0_clk) @@ -5400,7 +5411,8 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm_clk[3]), _REGISTER_CLOCK(NULL, "pcie_clk", pcie_clk[0]), _REGISTER_CLOCK(NULL, "pcie_ep_clk", pcie_ep_clk[0]), - _REGISTER_CLOCK("enet.0", NULL, enet_clk[0]), + _REGISTER_CLOCK(NULL, "fec_clk", enet_clk[0]), + _REGISTER_CLOCK(NULL, "fec_mdc_clk", enet_mdc_clk), _REGISTER_CLOCK(NULL, "imx_sata_clk", sata_clk[0]), _REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk[0]), _REGISTER_CLOCK(NULL, "usb_phy1_clk", usb_phy1_clk), diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index d8f33877bfe0..e95c45484362 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -89,6 +89,11 @@ DEFINE_SPINLOCK(mx6sl_clk_lock); #define MXC_TPRER 0x04 #define V2_TPRER_PRE24M_OFFSET 12 #define V2_TPRER_PRE24M_MASK 0xF +#define GPC_CNTR_OFFSET 0x0 +#define GPC_PGC_DISP_PGCR_OFFSET 0x240 +#define GPC_PGC_DISP_PUPSCR_OFFSET 0x244 +#define GPC_PGC_DISP_PDNSCR_OFFSET 0x248 +#define GPC_PGC_DISP_SR_OFFSET 0x24c /* We need to check the exp status again after timer expiration, * as there might be interrupt coming between the first time exp @@ -1899,6 +1904,33 @@ static struct clk i2c_clk[] = { }, }; +static int _display_mix_enable(struct clk *clk) +{ + if (cpu_is_mx6sl() && (mx6sl_revision() >= IMX_CHIP_REVISION_1_2)) { + __raw_writel(0x0, gpc_base + GPC_PGC_DISP_PGCR_OFFSET); + __raw_writel(0x20, gpc_base + GPC_CNTR_OFFSET); + __raw_writel(0x1, gpc_base + GPC_PGC_DISP_SR_OFFSET); + } + return 0; +} + +static void _display_mix_disable(struct clk *clk) +{ + if (cpu_is_mx6sl() && (mx6sl_revision() >= IMX_CHIP_REVISION_1_2)) { + __raw_writel(0x101, gpc_base + GPC_PGC_DISP_PUPSCR_OFFSET); + __raw_writel(0x101, gpc_base + GPC_PGC_DISP_PDNSCR_OFFSET); + + __raw_writel(0x1, gpc_base + GPC_PGC_DISP_PGCR_OFFSET); + __raw_writel(0x10, gpc_base + GPC_CNTR_OFFSET); + } +} + +static struct clk display_mix = { + __INIT_CLK_DEBUG(display_mix) + .enable = _display_mix_enable, + .disable = _display_mix_disable, +}; + static int _clk_ipu1_set_parent(struct clk *clk, struct clk *parent) { int mux; @@ -2037,6 +2069,7 @@ static struct clk ipu2_clk = { .set_rate = _clk_ipu2_set_rate, .get_rate = _clk_ipu2_get_rate, .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .secondary = &display_mix, }; static struct clk usdhc_dep_clk = { @@ -2803,6 +2836,7 @@ static struct clk pxp_axi_clk = { .round_rate = _clk_pxp_epdc_axi_round_rate, .get_rate = _clk_pxp_axi_get_rate, .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .secondary = &display_mix, }; static struct clk epdc_axi_clk = { @@ -2818,6 +2852,7 @@ static struct clk epdc_axi_clk = { .round_rate = _clk_pxp_epdc_axi_round_rate, .get_rate = _clk_epdc_axi_get_rate, .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .secondary = &display_mix, }; static unsigned long _clk_lcdif_pix_get_rate(struct clk *clk) @@ -2967,6 +3002,7 @@ static struct clk lcdif_pix_clk = { .round_rate = _clk_epdc_lcdif_pix_round_rate, .get_rate = _clk_lcdif_pix_get_rate, .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .secondary = &display_mix, }; static struct clk epdc_pix_clk = { @@ -2982,6 +3018,7 @@ static struct clk epdc_pix_clk = { .round_rate = _clk_epdc_lcdif_pix_round_rate, .get_rate = _clk_epdc_pix_get_rate, .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .secondary = &display_mix, }; static unsigned long _clk_spdif_round_rate(struct clk *clk, unsigned long rate) @@ -3195,6 +3232,17 @@ static struct clk fec_clk[] = { }, }; +static unsigned long _clk_fec_mdc_get_rate(struct clk *clk) +{ + return clk_get_rate(clk->parent); +} + +static struct clk fec_mdc_clk = { + __INIT_CLK_DEBUG(fec_mdc_clk) + .parent = &ipg_clk, + .get_rate = _clk_fec_mdc_get_rate, +}; + static struct clk ecspi_clk[] = { { __INIT_CLK_DEBUG(ecspi0_clk) @@ -3974,7 +4022,8 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm_clk[1]), _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm_clk[2]), _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm_clk[3]), - _REGISTER_CLOCK("fec.0", NULL, fec_clk[0]), + _REGISTER_CLOCK(NULL, "fec_clk", fec_clk[0]), + _REGISTER_CLOCK(NULL, "fec_mdc_clk", fec_mdc_clk), _REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk[0]), _REGISTER_CLOCK(NULL, "usb_phy1_clk", usb_phy1_clk), _REGISTER_CLOCK(NULL, "usb_phy3_clk", usb_phy3_clk), diff --git a/arch/arm/mach-mx6/pm.c b/arch/arm/mach-mx6/pm.c index d9c04e11bed0..f2efa00efb47 100644 --- a/arch/arm/mach-mx6/pm.c +++ b/arch/arm/mach-mx6/pm.c @@ -50,11 +50,7 @@ #define GPC_ISR3_OFFSET 0x20 #define GPC_ISR4_OFFSET 0x24 #define GPC_CNTR_OFFSET 0x0 -#define GPC_PGC_DISP_PGCR_OFFSET 0x240 -#define GPC_PGC_DISP_PUPSCR_OFFSET 0x244 -#define GPC_PGC_DISP_PDNSCR_OFFSET 0x248 -#define GPC_PGC_DISP_SR_OFFSET 0x24c -#define GPC_PGC_GPU_PGCR_OFFSET 0x260 +#define GPC_PGC_DISP_PGCR_OFFSET 0x240 #define GPC_PGC_CPU_PDN_OFFSET 0x2a0 #define GPC_PGC_CPU_PUPSCR_OFFSET 0x2a4 #define GPC_PGC_CPU_PDNSCR_OFFSET 0x2a8 @@ -174,47 +170,6 @@ static void usb_power_up_handler(void) } -static void disp_power_down(void) -{ - if (cpu_is_mx6sl() && (mx6sl_revision() >= IMX_CHIP_REVISION_1_2)) { - - __raw_writel(0xFFFFFFFF, gpc_base + GPC_PGC_DISP_PUPSCR_OFFSET); - __raw_writel(0xFFFFFFFF, gpc_base + GPC_PGC_DISP_PDNSCR_OFFSET); - - __raw_writel(0x1, gpc_base + GPC_PGC_DISP_PGCR_OFFSET); - __raw_writel(0x10, gpc_base + GPC_CNTR_OFFSET); - - /* Disable EPDC/LCDIF pix clock, and EPDC/LCDIF/PXP axi clock */ - __raw_writel(ccgr3 & - ~MXC_CCM_CCGRx_CG5_MASK & - ~MXC_CCM_CCGRx_CG4_MASK & - ~MXC_CCM_CCGRx_CG3_MASK & - ~MXC_CCM_CCGRx_CG2_MASK & - ~MXC_CCM_CCGRx_CG1_MASK, MXC_CCM_CCGR3); - - } -} - -static void disp_power_up(void) -{ - if (cpu_is_mx6sl() && (mx6sl_revision() >= IMX_CHIP_REVISION_1_2)) { - /* - * Need to enable EPDC/LCDIF pix clock, and - * EPDC/LCDIF/PXP axi clock before power up. - */ - __raw_writel(ccgr3 | - MXC_CCM_CCGRx_CG5_MASK | - MXC_CCM_CCGRx_CG4_MASK | - MXC_CCM_CCGRx_CG3_MASK | - MXC_CCM_CCGRx_CG2_MASK | - MXC_CCM_CCGRx_CG1_MASK, MXC_CCM_CCGR3); - - __raw_writel(0x0, gpc_base + GPC_PGC_DISP_PGCR_OFFSET); - __raw_writel(0x20, gpc_base + GPC_CNTR_OFFSET); - __raw_writel(0x1, gpc_base + GPC_PGC_DISP_SR_OFFSET); - } -} - static void mx6_suspend_store(void) { /* save some settings before suspend */ @@ -319,14 +274,12 @@ static int mx6_suspend_enter(suspend_state_t state) switch (state) { case PM_SUSPEND_MEM: - disp_power_down(); usb_power_down_handler(); mxc_cpu_lp_set(ARM_POWER_OFF); arm_pg = true; break; case PM_SUSPEND_STANDBY: if (cpu_is_mx6sl()) { - disp_power_down(); usb_power_down_handler(); mxc_cpu_lp_set(STOP_XTAL_ON); arm_pg = true; @@ -394,10 +347,8 @@ static int mx6_suspend_enter(suspend_state_t state) restore_gic_dist_state(0, &gds); restore_gic_cpu_state(0, &gcs); } - if (state == PM_SUSPEND_MEM || (cpu_is_mx6sl())) { + if (state == PM_SUSPEND_MEM || (cpu_is_mx6sl())) usb_power_up_handler(); - disp_power_up(); - } mx6_suspend_restore(); diff --git a/arch/arm/mach-mx6/usb_dr.c b/arch/arm/mach-mx6/usb_dr.c index e6496bc9cd50..c02158b4a2fc 100644 --- a/arch/arm/mach-mx6/usb_dr.c +++ b/arch/arm/mach-mx6/usb_dr.c @@ -248,10 +248,12 @@ static void enter_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, boo usbotg_internal_phy_clock_gate(false); } else { - if (UOG_PORTSC1 & PORTSC_PHCD) { + if (UOG_PORTSC1 & PORTSC_PHCD) UOG_PORTSC1 &= ~PORTSC_PHCD; - mdelay(1); - } + + /* Wait PHY clock stable */ + mdelay(1); + usbotg_internal_phy_clock_gate(true); tmp = (BM_USBPHY_PWD_TXPWDFS | BM_USBPHY_PWD_TXPWDIBIAS diff --git a/arch/arm/mach-mx6/usb_h1.c b/arch/arm/mach-mx6/usb_h1.c index 6de99d96142b..657c1cb09b34 100644 --- a/arch/arm/mach-mx6/usb_h1.c +++ b/arch/arm/mach-mx6/usb_h1.c @@ -260,7 +260,7 @@ static void usbh1_platform_rh_resume_swfix(struct fsl_usb2_platform_data *pdata) { u32 index = 0; - if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH) + if ((UH1_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH) return ; while ((UH1_PORTSC1 & PORTSC_PORT_FORCE_RESUME) && (index < 1000)) { @@ -293,7 +293,7 @@ static void usbh1_platform_rh_resume(struct fsl_usb2_platform_data *pdata) /*for mx6sl ,we do not need any sw fix*/ if (cpu_is_mx6sl()) return ; - if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH) + if ((UH1_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH) return ; while ((UH1_PORTSC1 & PORTSC_PORT_FORCE_RESUME) && (index < 1000)) { @@ -332,10 +332,12 @@ static void _phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool ena usbh1_internal_phy_clock_gate(false); } else { - if (UH1_PORTSC1 & PORTSC_PHCD) { + if (UH1_PORTSC1 & PORTSC_PHCD) UH1_PORTSC1 &= ~PORTSC_PHCD; - mdelay(1); - } + + /* Wait PHY clock stable */ + mdelay(1); + usbh1_internal_phy_clock_gate(true); tmp = (BM_USBPHY_PWD_TXPWDFS | BM_USBPHY_PWD_TXPWDIBIAS diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index 1ed1fd361308..428b2431c207 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S @@ -211,6 +211,9 @@ ENTRY(v7_coherent_user_range) * isn't mapped, just try the next page. */ 9001: +#ifdef CONFIG_ARM_ERRATA_775420 + dsb +#endif mov r12, r12, lsr #12 mov r12, r12, lsl #12 add r12, r12, #4096 diff --git a/arch/arm/plat-mxc/include/mach/epdc.h b/arch/arm/plat-mxc/include/mach/epdc.h index 36aac88230c8..08fef76148f3 100644 --- a/arch/arm/plat-mxc/include/mach/epdc.h +++ b/arch/arm/plat-mxc/include/mach/epdc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. * * 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 the @@ -36,6 +36,7 @@ struct imx_epdc_fb_platform_data { void (*put_pins) (void); void (*enable_pins) (void); void (*disable_pins) (void); + bool pg_display_mix; }; struct imx_spdc_panel_init_set { diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 2222617b3bed..2c1d3ae34161 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -658,21 +658,28 @@ static void test_ahash_speed(const char *algo, unsigned int sec, struct tcrypt_result tresult; struct ahash_request *req; struct crypto_ahash *tfm; - static char output[1024]; + const int output_size = 1024; + char *output = kmalloc(output_size, GFP_KERNEL); int i, ret; + if (!output) { + printk(KERN_INFO "\nUnable to allocate output buffer memory\n"); + return; + } + printk(KERN_INFO "\ntesting speed of async %s\n", algo); tfm = crypto_alloc_ahash(algo, 0, 0); if (IS_ERR(tfm)) { pr_err("failed to load transform for %s: %ld\n", algo, PTR_ERR(tfm)); + kfree(output); return; } - if (crypto_ahash_digestsize(tfm) > sizeof(output)) { + if (crypto_ahash_digestsize(tfm) > output_size) { pr_err("digestsize(%u) > outputbuffer(%zu)\n", - crypto_ahash_digestsize(tfm), sizeof(output)); + crypto_ahash_digestsize(tfm), output_size); goto out; } @@ -716,6 +723,7 @@ static void test_ahash_speed(const char *algo, unsigned int sec, ahash_request_free(req); out: + kfree(output); crypto_free_ahash(tfm); } diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 9048f469337f..bee75e8c85c5 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -358,7 +358,7 @@ void __iomem *sdma_iram_malloc(size_t size, unsigned long *buf) return sdma_iram_phys_to_virt(*buf); } -void sdma_iram_free(unsigned long *buf, u32 size) +void sdma_iram_free(unsigned long buf, size_t size) { if (!sdma_iram_pool) return; @@ -449,7 +449,7 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size, int ret; #ifdef CONFIG_SDMA_IRAM - buf_virt = sdma_iram_malloc(size, (unsigned long)&buf_phys); + buf_virt = sdma_iram_malloc(size, (unsigned long *)&buf_phys); #else buf_virt = dma_alloc_coherent(NULL, size, @@ -939,7 +939,7 @@ static int sdma_request_channel(struct sdma_channel *sdmac) #ifdef CONFIG_SDMA_IRAM sdmac->bd = sdma_iram_malloc(sizeof(sdmac->bd), - (unsigned long)&sdmac->bd_phys); + (unsigned long *)&sdmac->bd_phys); #else sdmac->bd = dma_alloc_noncached(NULL, PAGE_SIZE, &sdmac->bd_phys, GFP_KERNEL); #endif @@ -1502,7 +1502,7 @@ static int __init sdma_init(struct sdma_engine *sdma) sdma->channel_control = sdma_iram_malloc(MAX_DMA_CHANNELS * sizeof(struct sdma_channel_control) + sizeof(struct sdma_context_data), - &ccb_phys); + (unsigned long *)&ccb_phys); #else sdma->channel_control = dma_alloc_coherent(NULL, MAX_DMA_CHANNELS * sizeof (struct sdma_channel_control) + diff --git a/drivers/dma/pxp/pxp_dma_v2.c b/drivers/dma/pxp/pxp_dma_v2.c index c6098774ecf2..f0b50b7a1c05 100644 --- a/drivers/dma/pxp/pxp_dma_v2.c +++ b/drivers/dma/pxp/pxp_dma_v2.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. * * 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 @@ -800,6 +800,8 @@ static void pxp_clk_enable(struct pxps *pxp) } clk_enable(pxp->clk); + /* Pull PxP out of reset */ + __raw_writel(0, pxp->base + HW_PXP_CTRL); pxp->clk_stat = CLK_STAT_ON; mutex_unlock(&pxp->clk_mutex); @@ -818,6 +820,13 @@ static void pxp_clk_disable(struct pxps *pxp) spin_lock_irqsave(&pxp->lock, flags); if ((pxp->pxp_ongoing == 0) && list_empty(&head)) { + /* Put the PXP into reset as the Display MIX is going + * to be Power gated. + */ + while (__raw_readl(pxp->base + HW_PXP_CTRL) + & BM_PXP_CTRL_ENABLE) + ; + __raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL); spin_unlock_irqrestore(&pxp->lock, flags); clk_disable(pxp->clk); pxp->clk_stat = CLK_STAT_OFF; @@ -1627,11 +1636,11 @@ static int pxp_suspend(struct platform_device *pdev, pm_message_t state) { struct pxps *pxp = platform_get_drvdata(pdev); + /* Need to call the enable/disable sequence here to + * ensure that the PXP is in the right state before the + * SOC enters suspend state. + */ pxp_clk_enable(pxp); - while (__raw_readl(pxp->base + HW_PXP_CTRL) & BM_PXP_CTRL_ENABLE) - ; - - __raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL); pxp_clk_disable(pxp); return 0; @@ -1641,9 +1650,11 @@ static int pxp_resume(struct platform_device *pdev) { struct pxps *pxp = platform_get_drvdata(pdev); + /* Need to call the enable/disable sequence here to + * ensure that the PXP is in the right state after the + * SOC exits suspend state. + */ pxp_clk_enable(pxp); - /* Pull PxP out of reset */ - __raw_writel(0, pxp->base + HW_PXP_CTRL); pxp_clk_disable(pxp); return 0; diff --git a/drivers/media/video/mxc/capture/csi_v4l2_capture.c b/drivers/media/video/mxc/capture/csi_v4l2_capture.c index 5458ee6ed054..58cfa016b183 100644 --- a/drivers/media/video/mxc/capture/csi_v4l2_capture.c +++ b/drivers/media/video/mxc/capture/csi_v4l2_capture.c @@ -458,8 +458,7 @@ static int csi_allocate_frame_buf(cam_data *cam, int count) cam->frame[i].buffer.index = i; cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED; cam->frame[i].buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - cam->frame[i].buffer.length = PAGE_ALIGN(cam->v2f.fmt. - pix.sizeimage); + cam->frame[i].buffer.length = cam->v2f.fmt.pix.sizeimage; cam->frame[i].buffer.memory = V4L2_MEMORY_MMAP; cam->frame[i].buffer.m.offset = cam->frame[i].paddress; cam->frame[i].index = i; @@ -526,7 +525,7 @@ static int csi_v4l2_prepare_bufs(cam_data *cam, struct v4l2_buffer *buf) pr_debug("In MVC:csi_v4l2_prepare_bufs\n"); if (buf->index < 0 || buf->index >= FRAME_NUM || buf->length < - PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage)) { + cam->v2f.fmt.pix.sizeimage) { pr_err("ERROR: v4l2 capture: csi_v4l2_prepare_bufs buffers " "not allocated,index=%d, length=%d\n", buf->index, buf->length); @@ -589,8 +588,7 @@ static int csi_streamon(cam_data *cam) return -ENOBUFS; } cam->dummy_frame.buffer.type = V4L2_BUF_TYPE_PRIVATE; - cam->dummy_frame.buffer.length = - PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage); + cam->dummy_frame.buffer.length = cam->v2f.fmt.pix.sizeimage; cam->dummy_frame.buffer.m.offset = cam->dummy_frame.paddress; spin_lock_irqsave(&cam->queue_int_lock, flags); @@ -949,9 +947,16 @@ static int csi_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm) vidioc_int_g_ifparm(cam->sensor, &ifparm); cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt); pr_debug(" g_fmt_cap returns widthxheight of input as %d x %d\n", cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height); + cam->crop_bounds.top = cam->crop_bounds.left = 0; + cam->crop_bounds.width = cam_fmt.fmt.pix.width; + cam->crop_bounds.height = cam_fmt.fmt.pix.height; + cam->crop_current.width = cam->crop_bounds.width; + cam->crop_current.height = cam->crop_bounds.height; + exit: return err; } @@ -1340,14 +1345,45 @@ static long csi_v4l_do_ioctl(struct file *file, break; } + case VIDIOC_CROPCAP: + { + struct v4l2_cropcap *cap = arg; + + if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && + cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) { + retval = -EINVAL; + break; + } + cap->bounds = cam->crop_bounds; + cap->defrect = cam->crop_defrect; + break; + } case VIDIOC_S_CROP: { struct v4l2_crop *crop = arg; + struct v4l2_rect *b = &cam->crop_bounds; if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { retval = -EINVAL; break; } + + crop->c.top = (crop->c.top < b->top) ? b->top + : crop->c.top; + if (crop->c.top > b->top + b->height) + crop->c.top = b->top + b->height - 1; + if (crop->c.height > b->top + b->height - crop->c.top) + crop->c.height = + b->top + b->height - crop->c.top; + + crop->c.left = (crop->c.left < b->left) ? b->left + : crop->c.left; + if (crop->c.left > b->left + b->width) + crop->c.left = b->left + b->width - 1; + if (crop->c.width > b->left - crop->c.left + b->width) + crop->c.width = + b->left - crop->c.left + b->width; + crop->c.width -= crop->c.width % 8; crop->c.height -= crop->c.height % 8; @@ -1575,7 +1611,6 @@ static long csi_v4l_do_ioctl(struct file *file, case VIDIOC_G_OUTPUT: case VIDIOC_S_OUTPUT: case VIDIOC_ENUMSTD: - case VIDIOC_CROPCAP: case VIDIOC_S_STD: case VIDIOC_TRY_FMT: case VIDIOC_ENUMINPUT: @@ -1728,6 +1763,12 @@ static void init_camera_struct(cam_data *cam) cam->win.w.left = 0; cam->win.w.top = 0; cam->still_counter = 0; + /* setup cropping */ + cam->crop_bounds.left = 0; + cam->crop_bounds.width = 640; + cam->crop_bounds.top = 0; + cam->crop_bounds.height = 480; + cam->crop_current = cam->crop_defrect = cam->crop_bounds; cam->enc_callback = camera_callback; csi_start_callback(cam); @@ -1926,6 +1967,20 @@ static int csi_v4l2_master_attach(struct v4l2_int_device *slave) /* Used to detect TV in (type 1) vs. camera (type 0) */ cam->device_type = cam_fmt.fmt.pix.priv; + cam->crop_bounds.top = cam->crop_bounds.left = 0; + cam->crop_bounds.width = cam_fmt.fmt.pix.width; + cam->crop_bounds.height = cam_fmt.fmt.pix.height; + + /* This also is the max crop size for this device. */ + cam->crop_defrect.top = cam->crop_defrect.left = 0; + cam->crop_defrect.width = cam_fmt.fmt.pix.width; + cam->crop_defrect.height = cam_fmt.fmt.pix.height; + + /* At this point, this is also the current image size. */ + cam->crop_current.top = cam->crop_current.left = 0; + cam->crop_current.width = cam_fmt.fmt.pix.width; + cam->crop_current.height = cam_fmt.fmt.pix.height; + pr_debug("End of %s: v2f pix widthxheight %d x %d\n", __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height); diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index 2a5623c5a213..92cf704fec4e 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c @@ -285,7 +285,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, mem->size = PAGE_ALIGN(buf->bsize); mem->vaddr = dma_alloc_coherent(q->dev, mem->size, &mem->dma_handle, - GFP_DMA | GFP_KERNEL | __GFP_NOFAIL); + GFP_DMA | GFP_KERNEL); if (!mem->vaddr) { dev_err(q->dev, "dma_alloc_coherent size %ld failed\n", mem->size); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 8c1d5b2502c2..013029492951 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -840,7 +840,7 @@ static ssize_t mmc_boot_info_show(struct device *dev, "Supports high speed timing during boot" : "Does not support high speed timing during boot", - card->ext_csd.boot_size * 128, + card->ext_csd.boot_size >> 10, card->ext_csd.boot_config, !!(card->ext_csd.boot_config & 0x40), diff --git a/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c b/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c index 011fc33ab17e..1764623816f2 100644 --- a/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c +++ b/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -381,11 +381,11 @@ static long hdmi_cec_ioctl(struct file *filp, u_int cmd, val &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE; hdmi_writeb(val, HDMI_MC_CLKDIS); hdmi_writeb(0x02, HDMI_CEC_CTRL); + val = HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE; + hdmi_writeb(val, HDMI_CEC_POLARITY); val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ARB_LOST; hdmi_writeb(val, HDMI_CEC_MASK); hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0); - val = HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE; - hdmi_writeb(val, HDMI_CEC_POLARITY); mutex_lock(&hdmi_cec_data.lock); hdmi_cec_data.cec_state = true; mutex_unlock(&hdmi_cec_data.lock); diff --git a/drivers/mxc/ipu3/ipu_device.c b/drivers/mxc/ipu3/ipu_device.c index b10ce2a16f3a..ce347754abdc 100644 --- a/drivers/mxc/ipu3/ipu_device.c +++ b/drivers/mxc/ipu3/ipu_device.c @@ -852,7 +852,7 @@ static int update_split_setting(struct ipu_task_entry *t, bool vdi_split) &left_stripe, &right_stripe); if (ret) - dev_err(t->dev, "Warn: no:0x%x,calc_stripes ret:%d\n", + dev_dbg(t->dev, "Warn: no:0x%x,calc_stripes ret:%d\n", t->task_no, ret); t->set.sp_setting.iw = left_stripe.input_width; t->set.sp_setting.ow = left_stripe.output_width; diff --git a/drivers/mxc/mlb/mxc_mlb150.c b/drivers/mxc/mlb/mxc_mlb150.c index 3cc0289c57b8..fa75d09f7537 100755 --- a/drivers/mxc/mlb/mxc_mlb150.c +++ b/drivers/mxc/mlb/mxc_mlb150.c @@ -1907,9 +1907,9 @@ static int mxc_mlb150_open(struct inode *inode, struct file *filp) pr_err("can not alloc rx/tx buffers: %d\n", buf_size); return ret; } - pr_debug("IRAM Range: Virt 0x%x - 0x%x, Phys 0x%x - 0x%x, size: 0x%x\n", - buf_addr, (buf_addr + buf_size - 1), phy_addr, - (phy_addr + buf_size - 1), buf_size); + pr_debug("IRAM Range: Virt 0x%p - 0x%p, Phys 0x%x - 0x%x, size: 0x%x\n", + buf_addr, (buf_addr + buf_size - 1), (u32)phy_addr, + (u32)(phy_addr + buf_size - 1), buf_size); pdevinfo->rbuf_base_virt = buf_addr; pdevinfo->rbuf_base_phy = phy_addr; memset(buf_addr, 0, buf_size); @@ -1918,7 +1918,7 @@ static int mxc_mlb150_open(struct inode *inode, struct file *filp) ++j, buf_addr += ring_buf_size, phy_addr += ring_buf_size) { pdevinfo->rx_rbuf.virt_bufs[j] = buf_addr; pdevinfo->rx_rbuf.phy_addrs[j] = phy_addr; - pr_debug("RX Ringbuf[%d]: 0x%x 0x%x\n", j, buf_addr, phy_addr); + pr_debug("RX Ringbuf[%d]: 0x%p 0x%x\n", j, buf_addr, (u32)phy_addr); } pdevinfo->rx_rbuf.unit_size = ring_buf_size; pdevinfo->rx_rbuf.total_size = buf_size; @@ -1927,7 +1927,7 @@ static int mxc_mlb150_open(struct inode *inode, struct file *filp) ++j, buf_addr += ring_buf_size, phy_addr += ring_buf_size) { pdevinfo->tx_rbuf.virt_bufs[j] = buf_addr; pdevinfo->tx_rbuf.phy_addrs[j] = phy_addr; - pr_debug("TX Ringbuf[%d]: 0x%x 0x%x\n", j, buf_addr, phy_addr); + pr_debug("TX Ringbuf[%d]: 0x%p 0x%x\n", j, buf_addr, (u32)phy_addr); } pdevinfo->tx_rbuf.unit_size = ring_buf_size; diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c index 8c36d6abf852..8a219db2e4a5 100644 --- a/drivers/mxc/vpu/mxc_vpu.c +++ b/drivers/mxc/vpu/mxc_vpu.c @@ -126,7 +126,7 @@ static int vpu_alloc_dma_buffer(struct vpu_mem_desc *mem) mem->cpu_addr = (unsigned long) dma_alloc_coherent(NULL, PAGE_ALIGN(mem->size), (dma_addr_t *) (&mem->phy_addr), - GFP_DMA | GFP_KERNEL | __GFP_NOFAIL); + GFP_DMA | GFP_KERNEL); pr_debug("[ALLOC] mem alloc cpu_addr = 0x%x\n", mem->cpu_addr); if ((void *)(mem->cpu_addr) == NULL) { printk(KERN_ERR "Physical memory allocation error!\n"); diff --git a/drivers/net/fec.c b/drivers/net/fec.c index d2fea018f927..7d792e80de7f 100755 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -197,6 +197,7 @@ struct fec_enet_private { struct net_device *netdev; struct clk *clk; + struct clk *mdc_clk; /* The saved address of a sent-in-place packet/buffer, for skfree(). */ unsigned char *tx_bounce[TX_RING_SIZE]; @@ -1140,9 +1141,8 @@ static int fec_enet_mii_init(struct platform_device *pdev) /* * Set MII speed to 2.5 MHz (= clk_get_rate() / 2 * phy_speed) */ - fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk), + fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->mdc_clk), (FEC_ENET_MII_CLK << 2)) << 1; - /* set hold time to 2 internal clock cycle */ if (cpu_is_mx6q() || cpu_is_mx6dl()) fep->phy_speed |= FEC_ENET_HOLD_TIME; @@ -1873,7 +1873,7 @@ fec_probe(struct platform_device *pdev) if (pdata) fep->phy_interface = pdata->phy; - if (pdata->gpio_irq < 0) { + if (pdata->gpio_irq > 0) { gpio_request(pdata->gpio_irq, "gpio_enet_irq"); gpio_direction_input(pdata->gpio_irq); @@ -1906,6 +1906,11 @@ fec_probe(struct platform_device *pdev) ret = PTR_ERR(fep->clk); goto failed_clk; } + fep->mdc_clk = clk_get(&pdev->dev, "fec_mdc_clk"); + if (IS_ERR(fep->mdc_clk)) { + ret = PTR_ERR(fep->mdc_clk); + goto failed_clk; + } clk_enable(fep->clk); ret = fec_enet_init(ndev); @@ -1949,6 +1954,7 @@ failed_mii_init: failed_init: clk_disable(fep->clk); clk_put(fep->clk); + clk_put(fep->mdc_clk); failed_clk: if (pdata->gpio_irq < 0) free_irq(irq, ndev); @@ -1981,6 +1987,7 @@ fec_drv_remove(struct platform_device *pdev) fec_enet_mii_remove(fep); clk_disable(fep->clk); clk_put(fep->clk); + clk_put(fep->mdc_clk); iounmap((void __iomem *)ndev->base_addr); if (fep->ptimer_present) fec_ptp_cleanup(fep->ptp_priv); diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c index 00bd2e609525..abf11b80d517 100755 --- a/drivers/usb/otg/fsl_otg.c +++ b/drivers/usb/otg/fsl_otg.c @@ -551,13 +551,9 @@ int fsl_otg_start_host(struct otg_fsm *fsm, int on) goto end; else { VDBG("host off......\n"); - if (host_pdrv->suspend) { + if (host_pdrv->suspend) retval = host_pdrv->suspend(host_pdev, otg_suspend_state); - if (fsm->id) - /* default-b */ - fsl_otg_drv_vbus(dev->platform_data, 0); - } otg_dev->host_working = 0; } } @@ -670,8 +666,6 @@ static int fsl_otg_set_host(struct otg_transceiver *otg_p, struct usb_bus *host) otg_dev->host_working = 0; - otg_statemachine(&otg_dev->fsm); - return 0; } @@ -703,7 +697,6 @@ static int fsl_otg_set_peripheral(struct otg_transceiver *otg_p, otg_dev->otg.gadget = 0; otg_dev->fsm.b_bus_req = 0; pdata->port_enables = 0; - otg_statemachine(&otg_dev->fsm); return 0; } pdata->port_enables = 1; diff --git a/drivers/usb/otg/otg_fsm.c b/drivers/usb/otg/otg_fsm.c index 9e16afe02de4..85b7148f65bb 100755 --- a/drivers/usb/otg/otg_fsm.c +++ b/drivers/usb/otg/otg_fsm.c @@ -1,6 +1,6 @@ /* OTG Finite State Machine from OTG spec * - * Copyright (C) 2006-2011 Freescale Semiconductor, Inc. + * Copyright (C) 2006-2013 Freescale Semiconductor, Inc. * * Author: Li Yang <LeoLi@freescale.com> * Jerry Huang <Chang-Ming.Huang@freescale.com> @@ -254,6 +254,8 @@ int otg_statemachine(struct otg_fsm *fsm) enum usb_otg_state state; unsigned long flags; + return 0; + spin_lock_irqsave(&fsm->lock, flags); state = fsm->transceiver->state; diff --git a/drivers/video/mxc/mxc_elcdif_fb.c b/drivers/video/mxc/mxc_elcdif_fb.c index b3691b540522..2c38b0e9379c 100644 --- a/drivers/video/mxc/mxc_elcdif_fb.c +++ b/drivers/video/mxc/mxc_elcdif_fb.c @@ -79,6 +79,7 @@ struct mxc_elcdif_fb_data { struct semaphore flip_sem; struct fb_var_screeninfo var; u32 pseudo_palette[16]; + bool pg_display_mix; }; struct elcdif_signal_cfg { @@ -1186,6 +1187,12 @@ static int mxc_elcdif_fb_blank(int blank, struct fb_info *info) } if (data->cur_blank != FB_BLANK_UNBLANK) { + + if (data->pg_display_mix) { + mxc_elcdif_stop(); + mxc_elcdif_dma_release(); + data->running = false; + } if (g_elcdif_axi_clk_enable) { clk_disable(g_elcdif_axi_clk); g_elcdif_axi_clk_enable = false; @@ -1492,6 +1499,8 @@ static int mxc_elcdif_fb_probe(struct platform_device *pdev) if (ret) goto err3; + data->pg_display_mix = pdata->pg_display_mix; + platform_set_drvdata(pdev, fbi); return 0; diff --git a/drivers/video/mxc/mxc_epdc_fb.c b/drivers/video/mxc/mxc_epdc_fb.c index 4103498dc1b0..71697f2749d9 100644 --- a/drivers/video/mxc/mxc_epdc_fb.c +++ b/drivers/video/mxc/mxc_epdc_fb.c @@ -1089,7 +1089,10 @@ static void epdc_powerup(struct mxc_epdc_fb_data *fb_data) clk_enable(fb_data->epdc_clk_axi); clk_enable(fb_data->epdc_clk_pix); - __raw_writel(EPDC_CTRL_CLKGATE, EPDC_CTRL_CLEAR); + if (fb_data->pdata->pg_display_mix) + epdc_init_settings(fb_data); + else + __raw_writel(EPDC_CTRL_CLKGATE, EPDC_CTRL_CLEAR); /* Enable power to the EPD panel */ ret = regulator_enable(fb_data->display_regulator); diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index ac56f18c53a3..892cba580c22 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -247,6 +247,7 @@ struct mxc_fb_platform_data { int num_modes; char *mode_str; u32 interface_pix_fmt; + bool pg_display_mix; }; struct fsl_mxc_lcd_platform_data { diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index b370349c0a8f..b54ddb751adb 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -4111,7 +4111,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) WM8962_INR_VOL_MASK, 0x3f); snd_soc_update_bits(codec, WM8962_LEFT_ADC_VOLUME, WM8962_ADCL_VOL_MASK, 0xd8); - snd_soc_update_bits(codec, WM8962_LEFT_ADC_VOLUME, + snd_soc_update_bits(codec, WM8962_RIGHT_ADC_VOLUME, WM8962_ADCR_VOL_MASK, 0xd8); snd_soc_update_bits(codec, WM8962_RIGHT_INPUT_MIXER_VOLUME, WM8962_IN3R_MIXINR_VOL_MASK, 0x7); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index e62ad5ffce66..b3ab124652be 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -748,6 +748,9 @@ static int soc_codec_close(struct snd_pcm_substream *substream) codec_dai->active--; codec->active--; + if (!cpu_dai->active && !codec_dai->active) + rtd->rate = 0; + /* Muting the DAC suppresses artifacts caused during digital * shutdown, for example from stopping clocks. */ |