diff options
author | guoyin.chen <guoyin.chen@freescale.com> | 2013-04-03 11:07:09 +0800 |
---|---|---|
committer | guoyin.chen <guoyin.chen@freescale.com> | 2013-04-03 11:07:09 +0800 |
commit | 8fa723312b9701e767c2eda46e4aabb21e21ccb3 (patch) | |
tree | bcdb59722202cce2d2277d2fd7a785141cdf8bac | |
parent | 029767ec3d45796a2d6a58debe3844cf6b814ec7 (diff) | |
parent | 573bab0be2427d6664420eaf9d8e272dbe9d840f (diff) |
Merge remote-tracking branch 'fsl-linux-sdk/imx_3.0.35_4.0.0' into imx_3.0.35_android
Conflicts:
drivers/net/fec.c
33 files changed, 328 insertions, 110 deletions
diff --git a/arch/arm/configs/imx6_defconfig b/arch/arm/configs/imx6_defconfig index 3b2d31e4c4d2..13a4ef171e2e 100644 --- a/arch/arm/configs/imx6_defconfig +++ b/arch/arm/configs/imx6_defconfig @@ -332,6 +332,7 @@ CONFIG_ARCH_MXC_AUDMUX_V2=y CONFIG_IRAM_ALLOC=y CONFIG_CLK_DEBUG=y CONFIG_DMA_ZONE_SIZE=184 +#CONFIG_MX6_ENET_IRQ_TO_GPIO is not set # # System MMU diff --git a/arch/arm/mach-mx6/Kconfig b/arch/arm/mach-mx6/Kconfig index 59d8ab313f73..df954b40d8e8 100644 --- a/arch/arm/mach-mx6/Kconfig +++ b/arch/arm/mach-mx6/Kconfig @@ -319,4 +319,11 @@ config MACH_IMX_BLUETOOTH_RFKILL ---help--- Say Y to get the standard rfkill interface of Bluetooth +config MX6_ENET_IRQ_TO_GPIO + bool "Route ENET interrupts to GPIO" + default n + help + Enabling this will direct all the ENET interrupts to a board specific GPIO. + This will allow the system to enter WAIT mode when ENET is active. + endif diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.c b/arch/arm/mach-mx6/board-mx6q_arm2.c index d627324d77ab..8a2687d04f36 100644 --- a/arch/arm/mach-mx6/board-mx6q_arm2.c +++ b/arch/arm/mach-mx6/board-mx6q_arm2.c @@ -156,6 +156,12 @@ #define MX6_ARM2_CAN2_STBY MX6_ARM2_IO_EXP_GPIO2(1) +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO +#define MX6_ENET_IRQ IMX_GPIO_NR(1, 6) +#define IOMUX_OBSRV_MUX1_OFFSET 0x3c +#define OBSRV_MUX1_MASK 0x3f +#define OBSRV_MUX1_ENET_IRQ 0x9 +#endif #define BMCR_PDOWN 0x0800 /* PHY Powerdown */ @@ -388,6 +394,9 @@ static struct fec_platform_data fec_data __initdata = { .init = mx6_arm2_fec_phy_init, .power_hibernate = mx6_arm2_fec_power_hibernate, .phy = PHY_INTERFACE_MODE_RGMII, +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + .gpio_irq = MX6_ENET_IRQ, +#endif }; static int mx6_arm2_spi_cs[] = { @@ -2200,8 +2209,14 @@ static void __init mx6_arm2_init(void) imx6q_add_anatop_thermal_imx(1, &mx6_arm2_anatop_thermal_data); - if (!esai_record) + if (!esai_record) { imx6_init_fec(fec_data); +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + /* Make sure the IOMUX_OBSRV_MUX1 is set to ENET_IRQ. */ + mxc_iomux_set_specialbits_register(IOMUX_OBSRV_MUX1_OFFSET, + OBSRV_MUX1_ENET_IRQ, OBSRV_MUX1_MASK); +#endif + } imx6q_add_pm_imx(0, &mx6_arm2_pm_data); imx6q_add_sdhci_usdhc_imx(3, &mx6_arm2_sd4_data); diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.h b/arch/arm/mach-mx6/board-mx6q_arm2.h index eb06ef89bdd8..2a6a2052b3f9 100644 --- a/arch/arm/mach-mx6/board-mx6q_arm2.h +++ b/arch/arm/mach-mx6/board-mx6q_arm2.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2012, 2013 Freescale Semiconductor, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -183,10 +183,14 @@ static iomux_v3_cfg_t mx6q_arm2_pads[] = { /* USBOTG ID pin */ MX6Q_PAD_GPIO_1__USBOTG_ID, +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1, +#else /* MLB150 */ MX6Q_PAD_GPIO_3__MLB_MLBCLK, MX6Q_PAD_GPIO_6__MLB_MLBSIG, MX6Q_PAD_GPIO_2__MLB_MLBDAT, +#endif }; static iomux_v3_cfg_t mx6q_arm2_i2c3_pads[] = { diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.c b/arch/arm/mach-mx6/board-mx6q_sabreauto.c index 1d54e2c1037d..2700a249c20e 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabreauto.c +++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.c @@ -115,6 +115,13 @@ #define SABREAUTO_MAX7310_2_BASE_ADDR IMX_GPIO_NR(8, 8) #define SABREAUTO_MAX7310_3_BASE_ADDR IMX_GPIO_NR(8, 16) +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO +#define MX6_ENET_IRQ IMX_GPIO_NR(1, 6) +#define IOMUX_OBSRV_MUX1_OFFSET 0x3c +#define OBSRV_MUX1_MASK 0x3f +#define OBSRV_MUX1_ENET_IRQ 0x9 +#endif + #define SABREAUTO_IO_EXP_GPIO1(x) (SABREAUTO_MAX7310_1_BASE_ADDR + (x)) #define SABREAUTO_IO_EXP_GPIO2(x) (SABREAUTO_MAX7310_2_BASE_ADDR + (x)) #define SABREAUTO_IO_EXP_GPIO3(x) (SABREAUTO_MAX7310_3_BASE_ADDR + (x)) @@ -409,6 +416,9 @@ static struct fec_platform_data fec_data __initdata = { .init = mx6q_sabreauto_fec_phy_init, .power_hibernate = mx6q_sabreauto_fec_power_hibernate, .phy = PHY_INTERFACE_MODE_RGMII, +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + .gpio_irq = MX6_ENET_IRQ, +#endif }; static int mx6q_sabreauto_spi_cs[] = { @@ -1689,9 +1699,15 @@ static void __init mx6_board_init(void) imx6q_add_anatop_thermal_imx(1, &mx6q_sabreauto_anatop_thermal_data); - if (!can0_enable) + if (!can0_enable) { imx6_init_fec(fec_data); +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + /* Make sure the IOMUX_OBSRV_MUX1 is set to ENET_IRQ. */ + mxc_iomux_set_specialbits_register(IOMUX_OBSRV_MUX1_OFFSET, + OBSRV_MUX1_ENET_IRQ, OBSRV_MUX1_MASK); +#endif + } imx6q_add_pm_imx(0, &mx6q_sabreauto_pm_data); imx6q_add_sdhci_usdhc_imx(2, &mx6q_sabreauto_sd3_data); diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.h b/arch/arm/mach-mx6/board-mx6q_sabreauto.h index b1e2b9eec10b..e4d62f1baaa5 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabreauto.h +++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -208,10 +208,14 @@ static iomux_v3_cfg_t mx6q_sabreauto_pads[] = { /* HDMI */ MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE, +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1, +#else /* MLB150 */ MX6Q_PAD_ENET_TXD1__MLB_MLBCLK, MX6Q_PAD_GPIO_6__MLB_MLBSIG, MX6Q_PAD_GPIO_2__MLB_MLBDAT, +#endif }; static iomux_v3_cfg_t mx6q_sabreauto_can0_pads[] = { diff --git a/arch/arm/mach-mx6/board-mx6q_sabrelite.c b/arch/arm/mach-mx6/board-mx6q_sabrelite.c index 24914fe6904b..338c16ab6a52 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabrelite.c +++ b/arch/arm/mach-mx6/board-mx6q_sabrelite.c @@ -94,6 +94,13 @@ #define MX6Q_SABRELITE_CSI0_RST IMX_GPIO_NR(1, 8) #define MX6Q_SABRELITE_CSI0_PWN IMX_GPIO_NR(1, 6) +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO +#define MX6_ENET_IRQ IMX_GPIO_NR(1, 6) +#define IOMUX_OBSRV_MUX1_OFFSET 0x3c +#define OBSRV_MUX1_MASK 0x3f +#define OBSRV_MUX1_ENET_IRQ 0x9 +#endif + #define MX6Q_SABRELITE_SD3_WP_PADCFG (PAD_CTL_PKE | PAD_CTL_PUE | \ PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_MED | \ PAD_CTL_DSE_40ohm | PAD_CTL_HYS) @@ -322,7 +329,9 @@ static iomux_v3_cfg_t mx6q_sabrelite_csi0_sensor_pads[] = { MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC, MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK, MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC, +#ifndef CONFIG_MX6_ENET_IRQ_TO_GPIO MX6Q_PAD_GPIO_6__GPIO_1_6, /* J5 - Camera GP */ +#endif MX6Q_PAD_GPIO_8__GPIO_1_8, /* J5 - Camera Reset */ MX6Q_PAD_SD1_DAT0__GPIO_1_16, /* J5 - Camera GP */ MX6Q_PAD_NANDF_D5__GPIO_2_5, /* J16 - MIPI GP */ @@ -468,6 +477,9 @@ static int mx6q_sabrelite_fec_phy_init(struct phy_device *phydev) static struct fec_platform_data fec_data __initdata = { .init = mx6q_sabrelite_fec_phy_init, .phy = PHY_INTERFACE_MODE_RGMII, +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + .gpio_irq = MX6_ENET_IRQ, +#endif }; static int mx6q_sabrelite_spi_cs[] = { @@ -1259,6 +1271,11 @@ static void __init mx6_sabrelite_board_init(void) imx6q_add_anatop_thermal_imx(1, &mx6q_sabrelite_anatop_thermal_data); imx6_init_fec(fec_data); +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + /* Make sure the IOMUX_OBSRV_MUX1 is set to ENET_IRQ. */ + mxc_iomux_set_specialbits_register(IOMUX_OBSRV_MUX1_OFFSET, + OBSRV_MUX1_ENET_IRQ, OBSRV_MUX1_MASK); +#endif imx6q_add_pm_imx(0, &mx6q_sabrelite_pm_data); imx6q_add_sdhci_usdhc_imx(3, &mx6q_sabrelite_sd4_data); imx6q_add_sdhci_usdhc_imx(2, &mx6q_sabrelite_sd3_data); diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c index 72f5c3c07308..739ae4083ebf 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabresd.c +++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c @@ -201,6 +201,13 @@ #define SABRESD_ELAN_RST IMX_GPIO_NR(3, 8) #define SABRESD_ELAN_INT IMX_GPIO_NR(3, 28) +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO +#define MX6_ENET_IRQ IMX_GPIO_NR(1, 6) +#define IOMUX_OBSRV_MUX1_OFFSET 0x3c +#define OBSRV_MUX1_MASK 0x3f +#define OBSRV_MUX1_ENET_IRQ 0x9 +#endif + static struct clk *sata_clk; static struct clk *clko; static int mma8451_position; @@ -303,6 +310,9 @@ static int mx6q_sabresd_fec_phy_init(struct phy_device *phydev) static struct fec_platform_data fec_data __initdata = { .init = mx6q_sabresd_fec_phy_init, .phy = PHY_INTERFACE_MODE_RGMII, +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + .gpio_irq = MX6_ENET_IRQ, +#endif }; static int mx6q_sabresd_spi_cs[] = { @@ -1943,6 +1953,12 @@ static void __init mx6_sabresd_board_init(void) imx6q_add_anatop_thermal_imx(1, &mx6q_sabresd_anatop_thermal_data); imx6_init_fec(fec_data); +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + /* Make sure the IOMUX_OBSRV_MUX1 is set to ENET_IRQ. */ + mxc_iomux_set_specialbits_register(IOMUX_OBSRV_MUX1_OFFSET, + OBSRV_MUX1_ENET_IRQ, OBSRV_MUX1_MASK); +#endif + imx6q_add_pm_imx(0, &mx6q_sabresd_pm_data); /* Move sd4 to first because sd4 connect to emmc. diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.h b/arch/arm/mach-mx6/board-mx6q_sabresd.h index a1f5cd9166a3..b2bb8c923f0f 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabresd.h +++ b/arch/arm/mach-mx6/board-mx6q_sabresd.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -132,9 +132,13 @@ static iomux_v3_cfg_t mx6q_sabresd_pads[] = { MX6Q_PAD_KEY_COL3__I2C2_SCL, MX6Q_PAD_KEY_ROW3__I2C2_SDA, +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1, +#else /* I2C3 */ MX6Q_PAD_GPIO_3__I2C3_SCL, /* GPIO1[3] */ MX6Q_PAD_GPIO_6__I2C3_SDA, +#endif /* DISPLAY */ MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK, diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index c45fa2cafe71..512be6a40ec3 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -51,6 +51,7 @@ extern int lp_med_freq; extern int wait_mode_arm_podf; extern int lp_audio_freq; extern int cur_arm_podf; +extern bool enet_is_active; void __iomem *apll_base; @@ -3724,6 +3725,23 @@ static unsigned long _clk_enet_get_rate(struct clk *clk) return 500000000 / div; } +static int _clk_enet_enable(struct clk *clk) +{ +#ifndef CONFIG_MX6_ENET_IRQ_TO_GPIO + enet_is_active = true; +#endif + _clk_enable(clk); + return 0; +} + +static void _clk_enet_disable(struct clk *clk) +{ + _clk_disable(clk); +#ifndef CONFIG_MX6_ENET_IRQ_TO_GPIO + enet_is_active = false; +#endif +} + static struct clk enet_clk[] = { { __INIT_CLK_DEBUG(enet_clk) @@ -3731,8 +3749,8 @@ static struct clk enet_clk[] = { .parent = &pll8_enet_main_clk, .enable_reg = MXC_CCM_CCGR1, .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET, - .enable = _clk_enable, - .disable = _clk_disable, + .enable = _clk_enet_enable, + .disable = _clk_enet_disable, .set_rate = _clk_enet_set_rate, .get_rate = _clk_enet_get_rate, .secondary = &enet_clk[1], diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c index 61649c5ed5d8..c9f520a85ba8 100644 --- a/arch/arm/mach-mx6/system.c +++ b/arch/arm/mach-mx6/system.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,6 +57,7 @@ volatile unsigned int num_cpu_idle; volatile unsigned int num_cpu_idle_lock = 0x0; int wait_mode_arm_podf; int cur_arm_podf; +bool enet_is_active; void arch_idle_with_workaround(int cpu); extern void *mx6sl_wfi_iram_base; @@ -406,7 +407,7 @@ void arch_idle_multi_core(void) void arch_idle(void) { - if (enable_wait_mode) { + if (enable_wait_mode && !enet_is_active) { mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); if (mem_clk_on_in_wait) { u32 reg; diff --git a/arch/arm/mach-mx6/usb_dr.c b/arch/arm/mach-mx6/usb_dr.c index 7c8ef2f16447..8fb850397c10 100644 --- a/arch/arm/mach-mx6/usb_dr.c +++ b/arch/arm/mach-mx6/usb_dr.c @@ -144,6 +144,10 @@ static int usbotg_init_ext(struct platform_device *pdev) ret = usbotg_init(pdev); if (ret) { + clk_disable(usb_oh3_clk); + clk_put(usb_oh3_clk); + clk_disable(usb_phy1_clk); + clk_put(usb_phy1_clk); printk(KERN_ERR "otg init fails......\n"); return ret; } diff --git a/arch/arm/mach-mx6/usb_h1.c b/arch/arm/mach-mx6/usb_h1.c index d983e2870045..d4b7001a111c 100644 --- a/arch/arm/mach-mx6/usb_h1.c +++ b/arch/arm/mach-mx6/usb_h1.c @@ -148,6 +148,8 @@ static int fsl_usb_host_init_ext(struct platform_device *pdev) ret = fsl_usb_host_init(pdev); if (ret) { printk(KERN_ERR "host1 init fails......\n"); + clk_disable(usb_oh3_clk); + clk_put(usb_oh3_clk); return ret; } usbh1_internal_phy_clock_gate(true); diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx6q.h b/arch/arm/plat-mxc/include/mach/iomux-mx6q.h index db7e6616c4a2..36ae997d4db5 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx6q.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx6q.h @@ -97,6 +97,9 @@ PAD_CTL_SPEED_MED | PAD_CTL_PKE | PAD_CTL_PUE | \ PAD_CTL_PUS_100K_UP) +#define ENET_IRQ_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_DSE_40ohm | \ + PAD_CTL_SPEED_MED) + #define _MX6Q_PAD_SD2_DAT1__USDHC2_DAT1 \ IOMUX_PAD(0x0360, 0x004C, 0, 0x0000, 0, 0) #define _MX6Q_PAD_SD2_DAT1__ECSPI5_SS0 \ @@ -2329,8 +2332,13 @@ #define _MX6Q_PAD_GPIO_6__ESAI1_SCKT \ IOMUX_PAD(0x0600, 0x0230, 0, 0x0870, 1, 0) +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO +#define _MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 \ + IOMUX_PAD(0x0600, 0x0230, 1 | IOMUX_CONFIG_SION, 0x0000, 0, 0) +#else #define _MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 \ IOMUX_PAD(0x0600, 0x0230, 1, 0x0000, 0, 0) +#endif #define _MX6Q_PAD_GPIO_6__I2C3_SDA \ IOMUX_PAD(0x0600, 0x0230, 2 | IOMUX_CONFIG_SION, 0x08AC, 1, 0) #define _MX6Q_PAD_GPIO_6__CCM_CCM_OUT_0 \ @@ -5932,22 +5940,27 @@ #define MX6Q_PAD_GPIO_3__MLB_MLBCLK \ (_MX6Q_PAD_GPIO_3__MLB_MLBCLK | MUX_PAD_CTRL(MX6Q_MLB150_PAD_CTRL)) -#define MX6Q_PAD_GPIO_6__ESAI1_SCKT \ - (_MX6Q_PAD_GPIO_6__ESAI1_SCKT | MUX_PAD_CTRL(NO_PAD_CTRL)) +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO +#define MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 \ + (_MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 | MUX_PAD_CTRL(ENET_IRQ_PAD_CTRL)) +#else #define MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 \ (_MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX6Q_PAD_GPIO_6__ESAI1_SCKT \ + (_MX6Q_PAD_GPIO_6__ESAI1_SCKT | MUX_PAD_CTRL(NO_PAD_CTRL)) +#define MX6Q_PAD_GPIO_6__GPIO_1_6 \ + (_MX6Q_PAD_GPIO_6__GPIO_1_6 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX6Q_PAD_GPIO_6__I2C3_SDA \ (_MX6Q_PAD_GPIO_6__I2C3_SDA | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX6Q_PAD_GPIO_6__CCM_CCM_OUT_0 \ (_MX6Q_PAD_GPIO_6__CCM_CCM_OUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX6Q_PAD_GPIO_6__CSU_CSU_INT_DEB \ (_MX6Q_PAD_GPIO_6__CSU_CSU_INT_DEB | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX6Q_PAD_GPIO_6__GPIO_1_6 \ - (_MX6Q_PAD_GPIO_6__GPIO_1_6 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX6Q_PAD_GPIO_6__USDHC2_LCTL \ (_MX6Q_PAD_GPIO_6__USDHC2_LCTL | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL)) #define MX6Q_PAD_GPIO_6__MLB_MLBSIG \ (_MX6Q_PAD_GPIO_6__MLB_MLBSIG | MUX_PAD_CTRL(MX6Q_MLB150_PAD_CTRL)) +#endif #define MX6Q_PAD_GPIO_2__ESAI1_FST \ (_MX6Q_PAD_GPIO_2__ESAI1_FST | MUX_PAD_CTRL(NO_PAD_CTRL)) diff --git a/arch/arm/plat-mxc/usb_common.c b/arch/arm/plat-mxc/usb_common.c index a327d3016619..f6acb8af5448 100755 --- a/arch/arm/plat-mxc/usb_common.c +++ b/arch/arm/plat-mxc/usb_common.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -182,7 +182,7 @@ void fsl_usb_xcvr_unregister(struct fsl_xcvr_ops *xcvr_ops) pr_debug("%s\n", __func__); for (i = 0; i < MXC_NUMBER_USB_TRANSCEIVER; i++) { - if (g_xc_ops[i] == xcvr_ops) { + if (g_xc_ops[i] && (g_xc_ops[i] == xcvr_ops)) { g_xc_ops[i] = NULL; return; } @@ -203,7 +203,7 @@ static struct fsl_xcvr_ops *fsl_usb_get_xcvr(char *name) } for (i = 0; i < MXC_NUMBER_USB_TRANSCEIVER; i++) { - if (strcmp(g_xc_ops[i]->name, name) == 0) { + if (g_xc_ops[i] && (strcmp(g_xc_ops[i]->name, name) == 0)) { return g_xc_ops[i]; } } diff --git a/drivers/media/video/mxc/capture/csi_v4l2_capture.c b/drivers/media/video/mxc/capture/csi_v4l2_capture.c index a1c5d5ce8c25..745440911a1f 100644 --- a/drivers/media/video/mxc/capture/csi_v4l2_capture.c +++ b/drivers/media/video/mxc/capture/csi_v4l2_capture.c @@ -1741,7 +1741,9 @@ static int csi_v4l2_master_attach(struct v4l2_int_device *slave) } csi_enable_mclk(CSI_MCLK_I2C, true, true); + vidioc_int_s_power(cam->sensor, 1); vidioc_int_dev_init(slave); + vidioc_int_s_power(cam->sensor, 0); csi_enable_mclk(CSI_MCLK_I2C, false, false); cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt); diff --git a/drivers/media/video/mxc/capture/ov5640.c b/drivers/media/video/mxc/capture/ov5640.c index 042675a552bb..4ef5c4277be5 100644 --- a/drivers/media/video/mxc/capture/ov5640.c +++ b/drivers/media/video/mxc/capture/ov5640.c @@ -31,6 +31,7 @@ #include <media/v4l2-chip-ident.h> #include <media/v4l2-int-device.h> #include "mxc_v4l2_capture.h" +#include "fsl_csi.h" #define OV5640_VOLTAGE_ANALOG 2800000 #define OV5640_VOLTAGE_DIGITAL_CORE 1500000 @@ -827,6 +828,7 @@ static int ov5640_get_light_freq(void) light_frequency = 50; } else { /* 60Hz */ + light_frequency = 60; } } @@ -1821,6 +1823,9 @@ static int ov5640_probe(struct i2c_client *client, if (plat_data->pwdn) plat_data->pwdn(0); +#ifdef CONFIG_SOC_IMX6SL + csi_enable_mclk(CSI_MCLK_I2C, true, true); +#endif retval = ov5640_read_reg(OV5640_CHIP_ID_HIGH_BYTE, &chip_id_high); if (retval < 0 || chip_id_high != 0x56) { pr_warning("camera ov5640 is not found\n"); @@ -1837,6 +1842,10 @@ static int ov5640_probe(struct i2c_client *client, if (plat_data->pwdn) plat_data->pwdn(1); +#ifdef CONFIG_SOC_IMX6SL + csi_enable_mclk(CSI_MCLK_I2C, false, false); +#endif + camera_plat = plat_data; ov5640_int_device.priv = &ov5640_data; diff --git a/drivers/media/video/mxc/capture/ov5640_mipi.c b/drivers/media/video/mxc/capture/ov5640_mipi.c index 04f5ee73b5b9..a373e5bed450 100644 --- a/drivers/media/video/mxc/capture/ov5640_mipi.c +++ b/drivers/media/video/mxc/capture/ov5640_mipi.c @@ -904,6 +904,7 @@ int OV5640_get_light_freq(void) light_freq = 50; } else { /* 60Hz */ + light_freq = 60; } } return light_freq; diff --git a/drivers/media/video/mxc/output/mxc_vout.c b/drivers/media/video/mxc/output/mxc_vout.c index a42100afa6c5..626bad59e151 100644 --- a/drivers/media/video/mxc/output/mxc_vout.c +++ b/drivers/media/video/mxc/output/mxc_vout.c @@ -545,12 +545,14 @@ static int show_buf(struct mxc_vout_output *vout, int idx, fbi->var.yoffset = ipos->y + 1; var.xoffset = ipos->x; var.yoffset = ipos->y; + var.vmode |= FB_VMODE_YWRAP; ret = fb_pan_display(fbi, &var); fbi->fix.smem_start = fb_base; console_unlock(); } else { console_lock(); var.yoffset = idx * fbi->var.yres; + var.vmode &= ~FB_VMODE_YWRAP; ret = fb_pan_display(fbi, &var); console_unlock(); } diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c index 6e1457566771..3829999b51be 100644 --- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c +++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c @@ -583,17 +583,21 @@ _IsGPUPresent( { gceSTATUS status; gcsHAL_QUERY_CHIP_IDENTITY identity; - gctUINT32 control = - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (64) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | - ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) ; + gctUINT32 control; gcmkHEADER_ARG("Hardware=0x%x", Hardware); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00000, + &control)); + + control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))); + control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00000, diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c index 3c7cf3994c04..7d0032e3bff8 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c @@ -23,6 +23,8 @@ #if gcdENABLE_VG +#define ENABLE_VG_TRY_VIRTUAL_MEMORY 0 + #define _GC_OBJ_ZONE gcvZONE_VG /******************************************************************************\ @@ -331,11 +333,18 @@ gckKERNEL_AllocateLinearMemory( else if (pool == gcvPOOL_SYSTEM) { /* Advance to virtual memory. */ +#if ENABLE_VG_TRY_VIRTUAL_MEMORY pool = gcvPOOL_VIRTUAL; +#else + /*VG non-contiguous memory support is not ready yet, disable it temporary*/ + status = gcvSTATUS_OUT_OF_MEMORY; + break; +#endif } else { /* Out of pools. */ + status = gcvSTATUS_OUT_OF_MEMORY; break; } } diff --git a/drivers/mxc/thermal/thermal.c b/drivers/mxc/thermal/thermal.c index 109ea2b6cf00..4931ce1fa252 100644 --- a/drivers/mxc/thermal/thermal.c +++ b/drivers/mxc/thermal/thermal.c @@ -43,6 +43,7 @@ #include <linux/cpufreq.h> #include <linux/clk.h> #include "anatop_driver.h" +#include <mach/hardware.h> /* register define of anatop */ #define HW_ANADIG_ANA_MISC0 (0x00000150) @@ -137,6 +138,9 @@ #define ANATOP_DEBUG false #define THERMAL_FUSE_NAME "/sys/fsl_otp/HW_OCOTP_ANA1" +#define FACTOR1 15976 +#define FACTOR2 4297157 + /* variables */ unsigned long anatop_base; unsigned int ratio; @@ -147,6 +151,7 @@ static bool suspend_flag; static unsigned int thermal_irq; bool cooling_cpuhotplug; bool cooling_device_disable; +static bool calibration_valid; unsigned long temperature_cooling; static const struct anatop_device_id thermal_device_ids[] = { {ANATOP_THERMAL_HID}, @@ -846,12 +851,22 @@ static int __init anatop_thermal_cooling_device_disable(char *str) } __setup("no_cooling_device", anatop_thermal_cooling_device_disable); +static int __init anatop_thermal_use_calibration(char *str) +{ + calibration_valid = true; + pr_info("%s: use calibration data for thermal sensor!\n", __func__); + + return 1; +} +__setup("use_calibration", anatop_thermal_use_calibration); + static int anatop_thermal_counting_ratio(unsigned int fuse_data) { int ret = -EINVAL; pr_info("Thermal calibration data is 0x%x\n", fuse_data); - if (fuse_data == 0 || fuse_data == 0xffffffff || (fuse_data & 0xff) == 0) { + if (fuse_data == 0 || fuse_data == 0xffffffff || + (fuse_data & 0xfff00000) == 0) { pr_info("%s: invalid calibration data, disable cooling!!!\n", __func__); cooling_device_disable = true; ratio = DEFAULT_RATIO; @@ -868,7 +883,19 @@ static int anatop_thermal_counting_ratio(unsigned int fuse_data) raw_hot = (fuse_data & 0xfff00) >> 8; hot_temp = fuse_data & 0xff; - ratio = ((raw_25c - raw_hot) * 100) / (hot_temp - 25); + if (!calibration_valid && !cpu_is_mx6sl()) + /* + * The universal equation for thermal sensor + * is slope = 0.4297157 - (0.0015976 * 25C fuse), + * here we convert them to integer to make them + * easy for counting, FACTOR1 is 15976, + * FACTOR2 is 4297157. Our ratio = -100 * slope. + */ + ratio = ((FACTOR1 * raw_25c - FACTOR2) + 50000) / 100000; + else + ratio = ((raw_25c - raw_hot) * 100) / (hot_temp - 25); + + pr_info("Thermal sensor with ratio = %d\n", ratio); raw_n40c = raw_25c + (13 * ratio) / 20; raw_125c = raw_25c - ratio; /* Init default critical temp to set alarm */ diff --git a/drivers/net/fec.c b/drivers/net/fec.c index d09aa984c97e..ebb09eb9a6f2 100755 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -19,7 +19,7 @@ * Copyright (c) 2004-2006 Macq Electronique SA. * * Support for FEC IEEE 1588. - * Copyright (C) 2012 Freescale Semiconductor, Inc. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. */ #include <linux/module.h> @@ -27,6 +27,7 @@ #include <linux/string.h> #include <linux/ptrace.h> #include <linux/errno.h> +#include <linux/gpio.h> #include <linux/ioport.h> #include <linux/slab.h> #include <linux/interrupt.h> @@ -70,11 +71,13 @@ #define FEC_QUIRK_ENET_MAC (1 << 0) /* Controller needs driver to swap frame */ #define FEC_QUIRK_SWAP_FRAME (1 << 1) +/* ENET IP errata ticket TKT168103 */ +#define FEC_QUIRK_BUG_TKT168103 (1 << 2) static struct platform_device_id fec_devtype[] = { { .name = "enet", - .driver_data = FEC_QUIRK_ENET_MAC, + .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_BUG_TKT168103, }, { .name = "fec", @@ -82,7 +85,8 @@ static struct platform_device_id fec_devtype[] = { }, { .name = "imx28-fec", - .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME, + .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME | + FEC_QUIRK_BUG_TKT168103, }, { } }; @@ -229,6 +233,7 @@ struct fec_enet_private { int link; int full_duplex; struct completion mdio_done; + struct delayed_work fixup_trigger_tx; struct fec_ptp_private *ptp_priv; uint ptimer_present; @@ -278,13 +283,44 @@ static void *swap_buffer(void *bufaddr, int len) return bufaddr; } +static inline +void *fec_enet_get_pre_txbd(struct net_device *ndev) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + struct bufdesc *bdp = fep->cur_tx; + + if (bdp == fep->tx_bd_base) + return bdp + TX_RING_SIZE; + else + return bdp - 1; + +} + +/* MTIP enet IP have one IC issue recorded at PDM ticket:TKT168103 + * The TDAR bit after being set by software is not acted upon by the + * ENET module due to the timing of when the ENET state machine + * clearing the TDAR bit occurring coincident or momentarily after + * the software sets the bit. + * This forces ENET module to check the Transmit buffer descriptor + * and take action if the “ready” flag is set. Otherwise the ENET + * returns to idle mode. + */ +static void fixup_trigger_tx_func(struct work_struct *work) +{ + struct fec_enet_private *fep = + container_of(work, struct fec_enet_private, + fixup_trigger_tx.work); + + writel(0, fep->hwp + FEC_X_DES_ACTIVE); +} + static netdev_tx_t fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); const struct platform_device_id *id_entry = platform_get_device_id(fep->pdev); - struct bufdesc *bdp; + struct bufdesc *bdp, *bdp_pre; void *bufaddr; unsigned short status; unsigned long estatus; @@ -300,7 +336,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) /* Fill in a Tx ring entry */ bdp = fep->cur_tx; - status = bdp->cbd_sc; if (status & BD_ENET_TX_READY) { @@ -373,6 +408,12 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) /* Trigger transmission start */ writel(0, fep->hwp + FEC_X_DES_ACTIVE); + bdp_pre = fec_enet_get_pre_txbd(ndev); + if ((id_entry->driver_data & FEC_QUIRK_BUG_TKT168103) && + !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) + schedule_delayed_work(&fep->fixup_trigger_tx, + msecs_to_jiffies(1)); + /* If this was the last BD in the ring, start at the beginning again. */ if (status & BD_ENET_TX_WRAP) bdp = fep->tx_bd_base; @@ -1832,6 +1873,17 @@ fec_probe(struct platform_device *pdev) if (pdata) fep->phy_interface = pdata->phy; +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + gpio_request(pdata->gpio_irq, "gpio_enet_irq"); + gpio_direction_input(pdata->gpio_irq); + + irq = gpio_to_irq(pdata->gpio_irq); + ret = request_irq(irq, fec_enet_interrupt, + IRQF_TRIGGER_RISING, + pdev->name, ndev); + if (ret) + goto failed_irq; +#else /* This device has up to three irqs on some platforms */ for (i = 0; i < 3; i++) { irq = platform_get_irq(pdev, i); @@ -1846,6 +1898,7 @@ fec_probe(struct platform_device *pdev) goto failed_irq; } } +#endif fep->clk = clk_get(&pdev->dev, "fec_clk"); if (IS_ERR(fep->clk)) { @@ -1878,6 +1931,8 @@ fec_probe(struct platform_device *pdev) netif_carrier_off(ndev); clk_disable(fep->clk); + INIT_DELAYED_WORK(&fep->fixup_trigger_tx, fixup_trigger_tx_func); + ret = register_netdev(ndev); if (ret) goto failed_register; @@ -1894,11 +1949,15 @@ failed_init: clk_disable(fep->clk); clk_put(fep->clk); failed_clk: +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + free_irq(irq, ndev); +#else for (i = 0; i < 3; i++) { irq = platform_get_irq(pdev, i); if (irq > 0) free_irq(irq, ndev); } +#endif failed_irq: iounmap(fep->hwp); failed_ioremap: @@ -1916,6 +1975,7 @@ fec_drv_remove(struct platform_device *pdev) struct fec_enet_private *fep = netdev_priv(ndev); struct resource *r; + cancel_delayed_work_sync(&fep->fixup_trigger_tx); fec_stop(ndev); fec_enet_mii_remove(fep); clk_disable(fep->clk); diff --git a/drivers/power/sabresd_battery.c b/drivers/power/sabresd_battery.c index 648922139790..b84f0d4ad7a4 100755 --- a/drivers/power/sabresd_battery.c +++ b/drivers/power/sabresd_battery.c @@ -2,7 +2,7 @@ * sabresd_battery.c - Maxim 8903 USB/Adapter Charger Driver * * Copyright (C) 2011 Samsung Electronics - * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. * Based on max8903_charger.c * 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 @@ -300,12 +300,8 @@ static void max8903_battery_update_status(struct max8903_data *data) temp_last = temp; } if (data->charger_online == 0 && temp_last != 0) { - if (temp < temp_last) { - temp_last = temp; - data->voltage_uV = temp; - } else { - data->voltage_uV = temp_last; - } + temp_last = temp; + data->voltage_uV = temp; } if (data->charger_online == 1 || data->usb_charger_online == 1) { data->voltage_uV = temp; diff --git a/drivers/usb/host/ehci-arc.c b/drivers/usb/host/ehci-arc.c index c79eea2bf25c..e2000bd2e635 100755 --- a/drivers/usb/host/ehci-arc.c +++ b/drivers/usb/host/ehci-arc.c @@ -315,7 +315,7 @@ err2: usb_put_hcd(hcd); err1: dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval); - if (pdata->exit) + if (pdata->exit && pdata->pdev) pdata->exit(pdata->pdev); return retval; } @@ -373,7 +373,7 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd, * do platform specific un-initialization: * release iomux pins clocks, etc. */ - if (pdata->exit) + if (pdata->exit && pdata->pdev) pdata->exit(pdata->pdev); iounmap(hcd->regs); diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c index 6c24409b73f6..429b7b863c24 100644 --- a/drivers/video/mxc/mxc_ipuv3_fb.c +++ b/drivers/video/mxc/mxc_ipuv3_fb.c @@ -470,9 +470,15 @@ static int mxcfb_set_par(struct fb_info *fbi) if (mxc_fbi->ovfbi) mxc_fbi_fg = (struct mxcfb_info *)mxc_fbi->ovfbi->par; - if (mxc_fbi->ovfbi && mxc_fbi_fg) - if (mxc_fbi_fg->next_blank == FB_BLANK_UNBLANK) + if (mxc_fbi->ovfbi && mxc_fbi_fg) { + if (mxc_fbi_fg->cur_blank == FB_BLANK_UNBLANK) { + dev_warn(fbi->device, "overlay is still on.\n"); + return 0; + } + if ((mxc_fbi_fg->next_blank == FB_BLANK_UNBLANK) && + mxcfb_need_to_set_par(mxc_fbi->ovfbi)) ovfbi_enable = true; + } if (!mxcfb_need_to_set_par(fbi)) return 0; @@ -496,6 +502,7 @@ static int mxcfb_set_par(struct fb_info *fbi) ipu_disable_irq(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch_nf_irq); ipu_disable_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch, true); ipu_uninit_channel(mxc_fbi_fg->ipu, mxc_fbi_fg->ipu_ch); + mxc_fbi_fg->cur_blank = FB_BLANK_POWERDOWN; } ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq); @@ -679,6 +686,10 @@ static int mxcfb_set_par(struct fb_info *fbi) } mxc_fbi->cur_var = fbi->var; + if (ovfbi_enable) { + mxc_fbi_fg->cur_blank = FB_BLANK_UNBLANK; + mxc_fbi_fg->cur_var = mxc_fbi->ovfbi->var; + } return retval; } diff --git a/include/linux/fec.h b/include/linux/fec.h index 8f69cb58d458..a9d659456eba 100644 --- a/include/linux/fec.h +++ b/include/linux/fec.h @@ -3,7 +3,7 @@ * Copyright (c) 2009 Orex Computed Radiography * Baruch Siach <baruch@tkos.co.il> * - * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. * * Header file for the FEC platform data * @@ -21,6 +21,9 @@ struct fec_platform_data { int (*power_hibernate) (struct phy_device *); phy_interface_t phy; unsigned char mac[ETH_ALEN]; +#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO + unsigned int gpio_irq; +#endif }; #endif diff --git a/sound/soc/codecs/cs42888.c b/sound/soc/codecs/cs42888.c index 698ff4b59826..03f160b8cfad 100644 --- a/sound/soc/codecs/cs42888.c +++ b/sound/soc/codecs/cs42888.c @@ -1,6 +1,6 @@ /* * cs42888.c -- CS42888 ALSA SoC Audio Driver - * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved. */ /* * The code contained herein is licensed under the GNU General Public @@ -129,6 +129,11 @@ static const char *cs42888_supply_names[CS42888_NUM_SUPPLIES] = { #define CS42888_TRANS_ADC_SNGVOL_MASK (1 << CS42888_TRANS_ADC_SNGVOL_OFFSET) #define CS42888_TRANS_ADC_SZC_MASK (3 << CS42888_TRANS_ADC_SZC_OFFSET) +#define CS42888_TRANS_DAC_SZC_IC (0 << CS42888_TRANS_DAC_SZC_OFFSET) +#define CS42888_TRANS_DAC_SZC_ZC (1 << CS42888_TRANS_DAC_SZC_OFFSET) +#define CS42888_TRANS_DAC_SZC_SR (2 << CS42888_TRANS_DAC_SZC_OFFSET) +#define CS42888_TRANS_DAC_SZC_SRZC (3 << CS42888_TRANS_DAC_SZC_OFFSET) + #define CS42888_MUTE_AOUT8 (0x1 << 7) #define CS42888_MUTE_AOUT7 (0x1 << 6) #define CS42888_MUTE_AOUT6 (0x1 << 5) @@ -717,7 +722,6 @@ static int cs42888_hw_params(struct snd_pcm_substream *substream, pr_err("i2c write failed\n"); return ret; } - msleep(400); ret = cs42888_fill_cache(codec); if (ret < 0) { @@ -884,6 +888,8 @@ static int cs42888_probe(struct snd_soc_codec *codec) /* Disable auto-mute */ val = snd_soc_read(codec, CS42888_TRANS); val &= ~CS42888_TRANS_AMUTE_MASK; + val &= ~CS42888_TRANS_DAC_SZC_MASK; + val |= CS42888_TRANS_DAC_SZC_SR; ret = snd_soc_write(codec, CS42888_TRANS, val); if (ret < 0) { pr_err("i2c write failed\n"); diff --git a/sound/soc/codecs/mxc_spdif.c b/sound/soc/codecs/mxc_spdif.c index 77e62aefe422..b358f719f195 100644 --- a/sound/soc/codecs/mxc_spdif.c +++ b/sound/soc/codecs/mxc_spdif.c @@ -888,8 +888,10 @@ static int mxc_spdif_capture_get(struct snd_kcontrol *kcontrol, clk_enable(plat_data->spdif_clk); - if (!(__raw_readl(spdif_base_addr + SPDIF_REG_SIS) & INT_CNEW)) + if (!(__raw_readl(spdif_base_addr + SPDIF_REG_SIS) & INT_CNEW)) { + clk_disable(plat_data->spdif_clk); return -EAGAIN; + } cstatus = __raw_readl(spdif_base_addr + SPDIF_REG_SRCSLH); ucontrol->value.iec958.status[0] = (cstatus >> 16) & 0xFF; diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 6e7a5e9e9444..3ec5cc7e06c4 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -2337,61 +2337,6 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5, 4, 1, 0, inmix_tlv), }; -static int sysclk_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); - unsigned long timeout; - int src; - int fll; - - src = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_SRC_MASK; - - switch (src) { - case 0: /* MCLK */ - fll = 0; - break; - case 0x200: /* FLL */ - fll = 1; - break; - default: - dev_err(codec->dev, "Unknown SYSCLK source %x\n", src); - return -EINVAL; - } - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (fll) { - try_wait_for_completion(&wm8962->fll_lock); - - snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, - WM8962_FLL_ENA, WM8962_FLL_ENA); - - timeout = msecs_to_jiffies(5); - timeout = wait_for_completion_timeout(&wm8962->fll_lock, - timeout); - - if (wm8962->irq && timeout == 0) - dev_err(codec->dev, - "Timed out starting FLL\n"); - } - break; - - case SND_SOC_DAPM_POST_PMD: - if (fll) - snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, - WM8962_FLL_ENA, 0); - break; - - default: - BUG(); - return -EINVAL; - } - - return 0; -} - static int cp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -2677,8 +2622,7 @@ SND_SOC_DAPM_INPUT("DMICDAT"), SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0), -SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event, SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), @@ -3418,7 +3362,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, struct _fll_div fll_div = {0}; unsigned long timeout; int ret; - int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA; + int fll1 = 0; /* Any change? */ if (source == wm8962->fll_src && Fref == wm8962->fll_fref && @@ -3441,6 +3385,9 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, if (ret != 0) return ret; + /* Parameters good, disable so we can reprogram */ + snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0); + switch (fll_id) { case WM8962_FLL_MCLK: case WM8962_FLL_BCLK: @@ -3461,6 +3408,9 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, if (fll_div.theta || fll_div.lambda) fll1 |= WM8962_FLL_FRAC; + /* Stop the FLL while we reconfigure */ + snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0); + snd_soc_update_bits(codec, WM8962_FLL_CONTROL_2, WM8962_FLL_OUTDIV_MASK | WM8962_FLL_REFCLK_DIV_MASK, @@ -3478,7 +3428,9 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK | - WM8962_FLL_ENA, fll1); + WM8962_FLL_ENA, fll1 | WM8962_FLL_ENA); + + fll1 |= WM8962_FLL_ENA; dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); diff --git a/sound/soc/imx/imx-hdmi-dai.c b/sound/soc/imx/imx-hdmi-dai.c index 0a1686bfcacd..06805f38c5e2 100644 --- a/sound/soc/imx/imx-hdmi-dai.c +++ b/sound/soc/imx/imx-hdmi-dai.c @@ -1,7 +1,7 @@ /* * ALSA SoC HDMI Audio Layer for MXS * - * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. * * Based on stmp3xxx_spdif_dai.c * Vladimir Barinov <vbarinov@embeddedalley.com> @@ -42,8 +42,10 @@ static int imx_hdmi_dai_probe(struct platform_device *pdev) struct imx_hdmi *hdmi_data; int ret = 0; - if (!hdmi_get_registered()) - return -ENOMEM; + if (!hdmi_get_registered()) { + dev_err(&pdev->dev, "Failed: Load HDMI-video first.\n"); + return -ENODEV; + } hdmi_data = kzalloc(sizeof(*hdmi_data), GFP_KERNEL); if (!hdmi_data) diff --git a/sound/soc/imx/imx-hdmi.c b/sound/soc/imx/imx-hdmi.c index a30d478af9de..f214cffc4a53 100644 --- a/sound/soc/imx/imx-hdmi.c +++ b/sound/soc/imx/imx-hdmi.c @@ -1,7 +1,7 @@ /* * ASoC HDMI Transmitter driver for IMX development boards * - * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. * * based on stmp3780_devb_spdif.c * @@ -57,8 +57,10 @@ static int __init imx_hdmi_init(void) { int ret = 0; - if (!hdmi_get_registered()) - return -ENOMEM; + if (!hdmi_get_registered()) { + pr_err("Initialize HDMI-audio failed. Load HDMI-video first!\n"); + return -ENODEV; + } imx_hdmi_snd_device = platform_device_alloc("soc-audio", 4); if (!imx_hdmi_snd_device) { diff --git a/sound/soc/imx/imx-wm8962.c b/sound/soc/imx/imx-wm8962.c index 367c2f8e9aa6..9c5682ff3e68 100644 --- a/sound/soc/imx/imx-wm8962.c +++ b/sound/soc/imx/imx-wm8962.c @@ -165,8 +165,8 @@ static int imx_hifi_hw_params(struct snd_pcm_substream *substream, else pll_out = sample_rate * 256; - ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL_OSC, - WM8962_FLL_OSC, priv->sysclk, + ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL_MCLK, + WM8962_FLL_MCLK, priv->sysclk, pll_out); if (ret < 0) pr_err("Failed to start FLL: %d\n", ret); @@ -216,6 +216,14 @@ static int imx_hifi_hw_free(struct snd_pcm_substream *substream) pr_err("Failed to set MUTE: %d\n", ret); return ret; } + + /* Disable FLL */ + ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL, + WM8962_FLL_MCLK, 0, 0); + if (ret < 0) { + pr_err("Failed to set FLL: %d\n", ret); + return ret; + } } return 0; } |