summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinyu Chen <b03824@freescale.com>2012-02-23 15:06:20 +0800
committerXinyu Chen <b03824@freescale.com>2012-02-23 15:06:20 +0800
commit822999502d2ce629d6f5a91c2aa8731c0c88c3d8 (patch)
tree0fe83cdaa5de477b890e1df1572733c6de50cfa7
parenta388e861bc01090367c30f327846f44452cb2395 (diff)
parent1e54cdcdb6940a58d5e09174410fe0fe28041fa3 (diff)
Merge remote branch 'fsl-linux-sdk/imx_3.0.15_12.02.01' into imx_3.0.15_android
Conflicts: arch/arm/mach-mx6/clock.c arch/arm/plat-mxc/devices/platform-imx-perfmon.c drivers/usb/gadget/arcotg_udc.c
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabrelite.c13
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabresd.c13
-rw-r--r--arch/arm/mach-mx6/clock.c8
-rw-r--r--arch/arm/mach-mx6/cpu.c4
-rw-r--r--arch/arm/mach-mx6/mm.c1
-rw-r--r--arch/arm/mach-mx6/mx6_anatop_regulator.c4
-rw-r--r--arch/arm/mach-mx6/usb_dr.c30
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx6q.h7
-rw-r--r--drivers/mfd/mxc-hdmi-core.c14
-rwxr-xr-xdrivers/usb/gadget/arcotg_udc.c30
-rwxr-xr-xdrivers/usb/otg/fsl_otg.c7
-rw-r--r--drivers/video/mxc_hdmi.c30
-rw-r--r--include/linux/fsl_devices.h7
-rw-r--r--include/linux/mfd/mxc-hdmi-core.h3
-rw-r--r--sound/soc/codecs/mxc_hdmi.c3
-rw-r--r--sound/soc/imx/imx-hdmi-dai.c5
-rw-r--r--sound/soc/imx/imx-hdmi-dma.c12
-rw-r--r--sound/soc/imx/imx-hdmi.c5
18 files changed, 148 insertions, 48 deletions
diff --git a/arch/arm/mach-mx6/board-mx6q_sabrelite.c b/arch/arm/mach-mx6/board-mx6q_sabrelite.c
index 408dc42fb718..8f29e032d74a 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabrelite.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabrelite.c
@@ -214,7 +214,11 @@ static iomux_v3_cfg_t mx6q_sabrelite_pads[] = {
/* I2C3 */
MX6Q_PAD_GPIO_5__I2C3_SCL, /* GPIO1[5] - J7 - Display card */
+#ifdef CONFIG_FEC_1588
+ MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT,
+#else
MX6Q_PAD_GPIO_16__I2C3_SDA, /* GPIO7[11] - J15 - RGB connector */
+#endif
/* DISPLAY */
MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
@@ -1103,6 +1107,15 @@ static void __init mx6_sabrelite_board_init(void)
mxc_iomux_v3_setup_multiple_pads(mx6q_sabrelite_pads,
ARRAY_SIZE(mx6q_sabrelite_pads));
+#ifdef CONFIG_FEC_1588
+ /* Set GPIO_16 input for IEEE-1588 ts_clk and RMII reference clock
+ * For MX6 GPR1 bit21 meaning:
+ * Bit21: 0 - GPIO_16 pad output
+ * 1 - GPIO_16 pad input
+ */
+ mxc_iomux_set_gpr_register(1, 21, 1, 1);
+#endif
+
gp_reg_id = sabrelite_dvfscore_data.reg_id;
mx6q_sabrelite_init_uart();
imx6q_add_mxc_hdmi_core(&hdmi_core_data);
diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c
index 3998c82013b7..aace18c9910b 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabresd.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c
@@ -234,7 +234,11 @@ static iomux_v3_cfg_t mx6q_sabresd_pads[] = {
/* I2C3 */
MX6Q_PAD_GPIO_3__I2C3_SCL, /* GPIO1[3] */
+#ifdef CONFIG_FEC_1588
+ MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT,
+#else
MX6Q_PAD_GPIO_16__I2C3_SDA, /* GPIO7[11]*/
+#endif
/* DISPLAY */
MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
@@ -1194,6 +1198,15 @@ static void __init mx6_sabresd_board_init(void)
mxc_iomux_v3_setup_multiple_pads(mx6q_sabresd_pads,
ARRAY_SIZE(mx6q_sabresd_pads));
+#ifdef CONFIG_FEC_1588
+ /* Set GPIO_16 input for IEEE-1588 ts_clk and RMII reference clock
+ * For MX6 GPR1 bit21 meaning:
+ * Bit21: 0 - GPIO_16 pad output
+ * 1 - GPIO_16 pad input
+ */
+ mxc_iomux_set_gpr_register(1, 21, 1, 1);
+#endif
+
gp_reg_id = sabresd_dvfscore_data.reg_id;
mx6q_sabresd_init_uart();
imx6q_add_mxc_hdmi_core(&hdmi_core_data);
diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c
index 578118103299..be8fbaf0e811 100644
--- a/arch/arm/mach-mx6/clock.c
+++ b/arch/arm/mach-mx6/clock.c
@@ -5207,6 +5207,8 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
clk_set_parent(&gpu2d_axi_clk, &mmdc_ch0_axi_clk[0]);
gpu2d_axi_clk.secondary = NULL;
}
+ if (cpu_is_mx6q())
+ clk_set_parent(&gpu2d_core_clk[0], &pll3_usb_otg_main_clk);
/* PCLK camera - J5 */
clk_set_parent(&clko2_clk, &osc_clk);
@@ -5272,7 +5274,11 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
if (mx6q_revision() == IMX_CHIP_REVISION_1_0) {
gpt_clk[0].parent = &ipg_perclk;
gpt_clk[0].get_rate = NULL;
- }
+ } else {
+ /* Here we use OSC 24M as GPT's clock source, no need to
+ enable gpt serial clock*/
+ gpt_clk[0].secondary = NULL;
+ }
base = ioremap(GPT_BASE_ADDR, SZ_4K);
mxc_timer_init(&gpt_clk[0], base, MXC_INT_GPT);
diff --git a/arch/arm/mach-mx6/cpu.c b/arch/arm/mach-mx6/cpu.c
index da7d442eeae7..7b7668cf0a6a 100644
--- a/arch/arm/mach-mx6/cpu.c
+++ b/arch/arm/mach-mx6/cpu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 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
@@ -38,7 +38,7 @@ extern void mx6_wait(void);
struct cpu_op *(*get_cpu_op)(int *op);
-bool enable_wait_mode = true;
+bool enable_wait_mode;
u32 arm_max_freq = CPU_AT_1GHz;
void __iomem *gpc_base;
diff --git a/arch/arm/mach-mx6/mm.c b/arch/arm/mach-mx6/mm.c
index e4daaf1fb415..6e80f0aa11a3 100644
--- a/arch/arm/mach-mx6/mm.c
+++ b/arch/arm/mach-mx6/mm.c
@@ -81,6 +81,7 @@ void __init mx6_map_io(void)
mxc_iomux_v3_init(IO_ADDRESS(MX6Q_IOMUXC_BASE_ADDR));
mxc_arch_reset_init(IO_ADDRESS(MX6Q_WDOG1_BASE_ADDR));
mx6_set_cpu_type();
+ mxc_cpu_lp_set(WAIT_CLOCKED);
}
#ifdef CONFIG_CACHE_L2X0
int mxc_init_l2x0(void)
diff --git a/arch/arm/mach-mx6/mx6_anatop_regulator.c b/arch/arm/mach-mx6/mx6_anatop_regulator.c
index 89c053a00f71..fd7e0c3fbdee 100644
--- a/arch/arm/mach-mx6/mx6_anatop_regulator.c
+++ b/arch/arm/mach-mx6/mx6_anatop_regulator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -44,7 +44,7 @@ static int get_voltage(struct anatop_regulator *sreg)
struct anatop_regulator_data *rdata = sreg->rdata;
if (sreg->rdata->control_reg) {
- u32 val = (__raw_readl(rdata->control_reg) <<
+ u32 val = (__raw_readl(rdata->control_reg) >>
rdata->vol_bit_shift) & rdata->vol_bit_mask;
uv = rdata->min_voltage + (val - rdata->min_bit_val) * 25000;
pr_debug("vddio = %d, val=%u\n", uv, val);
diff --git a/arch/arm/mach-mx6/usb_dr.c b/arch/arm/mach-mx6/usb_dr.c
index 21cf3d80699a..b0ef01add614 100644
--- a/arch/arm/mach-mx6/usb_dr.c
+++ b/arch/arm/mach-mx6/usb_dr.c
@@ -33,6 +33,7 @@
static int usbotg_init_ext(struct platform_device *pdev);
static void usbotg_uninit_ext(struct platform_device *pdev);
static void usbotg_clock_gate(bool on);
+static void _dr_discharge_line(bool enable);
/* The usb_phy1_clk do not have enable/disable function at clock.c
* and PLL output for usb1's phy should be always enabled.
@@ -61,6 +62,7 @@ static struct fsl_usb2_platform_data dr_utmi_config = {
.usb_clock_for_pm = usbotg_clock_gate,
.transceiver = "utmi",
.phy_regs = USB_PHY0_BASE_ADDR,
+ .dr_discharge_line = _dr_discharge_line,
};
/* Platform data for wakeup operation */
@@ -182,6 +184,20 @@ void mx6_set_otghost_vbus_func(driver_vbus_func driver_vbus)
{
dr_utmi_config.platform_driver_vbus = driver_vbus;
}
+
+static void _dr_discharge_line(bool enable)
+{
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
+ if (enable) {
+ __raw_writel(BF_USBPHY_DEBUG_ENHSTPULLDOWN(0x3), phy_reg + HW_USBPHY_DEBUG_SET);
+ __raw_writel(BF_USBPHY_DEBUG_HSTPULLDOWN(0x3), phy_reg + HW_USBPHY_DEBUG_SET);
+ } else {
+ __raw_writel(BF_USBPHY_DEBUG_ENHSTPULLDOWN(0x3), phy_reg + HW_USBPHY_DEBUG_CLR);
+ __raw_writel(BF_USBPHY_DEBUG_HSTPULLDOWN(0x3), phy_reg + HW_USBPHY_DEBUG_CLR);
+ }
+
+}
+
/* Below two macros are used at otg mode to indicate usb mode*/
#define ENABLED_BY_HOST (0x1 << 0)
#define ENABLED_BY_DEVICE (0x1 << 1)
@@ -395,19 +411,6 @@ static void host_wakeup_handler(struct fsl_usb2_platform_data *pdata)
#ifdef CONFIG_USB_GADGET_ARC
/* Beginning of device related operation for DR port */
-static void _gadget_discharge_dp(bool enable)
-{
- void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
- if (enable) {
- __raw_writel(BF_USBPHY_DEBUG_ENHSTPULLDOWN(0x2), phy_reg + HW_USBPHY_DEBUG_SET);
- __raw_writel(BF_USBPHY_DEBUG_HSTPULLDOWN(0x2), phy_reg + HW_USBPHY_DEBUG_SET);
- } else {
- __raw_writel(BF_USBPHY_DEBUG_ENHSTPULLDOWN(0x2), phy_reg + HW_USBPHY_DEBUG_CLR);
- __raw_writel(BF_USBPHY_DEBUG_HSTPULLDOWN(0x2), phy_reg + HW_USBPHY_DEBUG_CLR);
- }
-
-}
-
static void _device_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
{
__phy_lowpower_suspend(pdata, enable, ENABLED_BY_DEVICE);
@@ -502,7 +505,6 @@ void __init mx6_usb_dr_init(void)
dr_utmi_config.platform_resume = NULL;
dr_utmi_config.phy_lowpower_suspend = _device_phy_lowpower_suspend;
dr_utmi_config.is_wakeup_event = _is_device_wakeup;
- dr_utmi_config.gadget_discharge_dp = _gadget_discharge_dp;
dr_utmi_config.wakeup_pdata = &dr_wakeup_config;
dr_utmi_config.wakeup_handler = device_wakeup_handler;
pdev = imx6q_add_fsl_usb2_udc(&dr_utmi_config);
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx6q.h b/arch/arm/plat-mxc/include/mach/iomux-mx6q.h
index 3345cca68ecb..c6b932e7fe6c 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx6q.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx6q.h
@@ -70,6 +70,10 @@ typedef enum iomux_config {
PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+#define MX6Q_GPIO_16_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
#define MX6Q_DISP_PAD_CLT MX6Q_HIGH_DRV
#define MX6Q_I2C_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_ODE | \
@@ -6032,7 +6036,8 @@ typedef enum iomux_config {
#define MX6Q_PAD_GPIO_16__ENET_1588_EVENT2_IN \
(_MX6Q_PAD_GPIO_16__ENET_1588_EVENT2_IN | MUX_PAD_CTRL(NO_PAD_CTRL))
#define MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT \
- (_MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+ (_MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT | \
+ MUX_PAD_CTRL(MX6Q_GPIO_16_PAD_CTRL))
#define MX6Q_PAD_GPIO_16__USDHC1_LCTL \
(_MX6Q_PAD_GPIO_16__USDHC1_LCTL | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
#define MX6Q_PAD_GPIO_16__SPDIF_IN1 \
diff --git a/drivers/mfd/mxc-hdmi-core.c b/drivers/mfd/mxc-hdmi-core.c
index 1aa92a01c40c..18fd1a67ba83 100644
--- a/drivers/mfd/mxc-hdmi-core.c
+++ b/drivers/mfd/mxc-hdmi-core.c
@@ -63,6 +63,7 @@ static int hdmi_ratio;
int mxc_hdmi_ipu_id;
int mxc_hdmi_disp_id;
static struct mxc_edid_cfg hdmi_core_edid_cfg;
+static int hdmi_core_init;
u8 hdmi_readb(unsigned int reg)
{
@@ -487,6 +488,16 @@ void hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg)
spin_unlock_irqrestore(&edid_spinlock, flags);
}
+void hdmi_set_registered(int registered)
+{
+ hdmi_core_init = registered;
+}
+
+int hdmi_get_registered(void)
+{
+ return hdmi_core_init;
+}
+
static int mxc_hdmi_core_probe(struct platform_device *pdev)
{
struct fsl_mxc_hdmi_core_platform_data *pdata = pdev->dev.platform_data;
@@ -498,6 +509,9 @@ static int mxc_hdmi_core_probe(struct platform_device *pdev)
overflow_lo = false;
overflow_hi = false;
#endif
+
+ hdmi_core_init = 0;
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENOENT;
diff --git a/drivers/usb/gadget/arcotg_udc.c b/drivers/usb/gadget/arcotg_udc.c
index 1cc50da4c9c2..5a1aab94b405 100755
--- a/drivers/usb/gadget/arcotg_udc.c
+++ b/drivers/usb/gadget/arcotg_udc.c
@@ -295,21 +295,21 @@ static void nuke(struct fsl_ep *ep, int status)
/*------------------------------------------------------------------
Internal Hardware related function
------------------------------------------------------------------*/
-static void dr_discharge_dp(struct fsl_usb2_platform_data *pdata)
+static void dr_discharge_line(struct fsl_usb2_platform_data *pdata, bool enable)
{
- /* enable pulldown dp */
- if (pdata->gadget_discharge_dp)
- pdata->gadget_discharge_dp(true);
+ /* enable/disable pulldown dp and dm */
+ if (pdata->dr_discharge_line) {
+ pdata->dr_discharge_line(enable);
/*
- * Some boards are very slow change line state from J to SE0 for DP,
- * So, we need to discharge DP, otherwise there is a wakeup interrupt
+ * Some platforms, like mx6x, are very slow change line state
+ * to SE0 for dp and dm.
+ * So, we need to discharge dp and dm, otherwise there is a wakeup interrupt
* after we enable the wakeup function.
*/
- gadget_wait_line_to_se0();
+ if (enable)
+ gadget_wait_line_to_se0();
+ }
- /* Disable pulldown dp */
- if (pdata->gadget_discharge_dp)
- pdata->gadget_discharge_dp(false);
}
static inline void
@@ -400,7 +400,7 @@ static int dr_controller_setup(struct fsl_udc *udc)
tmp |= USB_MODE_ES;
fsl_writel(tmp, &dr_regs->usbmode);
/* wait dp to 0v */
- dr_discharge_dp(pdata);
+ dr_discharge_line(pdata, true);
fsl_platform_set_device_mode(pdata);
@@ -506,6 +506,8 @@ static void dr_controller_run(struct fsl_udc *udc)
/* Clear stopped bit */
udc->stopped = 0;
+ /* disable pulldown dp and dm */
+ dr_discharge_line(udc->pdata, false);
/* The usb line has already been connected to pc */
temp = fsl_readl(&dr_regs->usbcmd);
temp |= USB_CMD_RUN_STOP;
@@ -2169,8 +2171,8 @@ static void fsl_gadget_disconnect_event(struct work_struct *work)
pdata = udc->pdata;
- /* wait dp to 0v */
- dr_discharge_dp(pdata);
+ /* wait line to se0 */
+ dr_discharge_line(pdata, true);
/*
* Wait class drivers finish, an well-behaviour class driver should
@@ -2226,6 +2228,8 @@ bool try_wake_up_udc(struct fsl_udc *udc)
if (udc->suspended) /*let the system pm resume the udc */
return true;
udc->stopped = 0;
+ /* disable pulldown dp and dm */
+ dr_discharge_line(pdata, false);
fsl_writel(tmp | USB_CMD_RUN_STOP, &dr_regs->usbcmd);
printk(KERN_DEBUG "%s: udc out low power mode\n", __func__);
} else {
diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c
index 7ee9fcad8d5e..b797161f798d 100755
--- a/drivers/usb/otg/fsl_otg.c
+++ b/drivers/usb/otg/fsl_otg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* Author: Li Yang <LeoLi@freescale.com>
* Jerry Huang <Chang-Ming.Huang@freescale.com>
@@ -722,6 +722,8 @@ static void fsl_otg_event(struct work_struct *work)
struct fsl_otg *og = container_of(work, struct fsl_otg, otg_event.work);
struct otg_fsm *fsm = &og->fsm;
struct otg_transceiver *otg = &og->otg;
+ struct fsl_usb2_platform_data *pdata;
+ pdata = og->otg.dev->platform_data;
mutex_lock(&pm_mutex);
b_session_irq_enable(false);
@@ -749,6 +751,9 @@ static void fsl_otg_event(struct work_struct *work)
fsl_otg_wait_stable_vbus(true);
b_session_irq_enable(false);
fsl_otg_start_host(fsm, 1);
+ if (pdata->dr_discharge_line)
+ pdata->dr_discharge_line(false);
+
}
mutex_unlock(&pm_mutex);
}
diff --git a/drivers/video/mxc_hdmi.c b/drivers/video/mxc_hdmi.c
index 5215ac59940b..e34a949e4140 100644
--- a/drivers/video/mxc_hdmi.c
+++ b/drivers/video/mxc_hdmi.c
@@ -1701,7 +1701,8 @@ static void mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi)
static int mxc_hdmi_power_on(struct mxc_dispdrv_handle *disp)
{
struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
- mxc_hdmi_phy_init(hdmi);
+ if (hdmi->fb_reg && hdmi->cable_plugin)
+ mxc_hdmi_phy_init(hdmi);
return 0;
}
@@ -2060,11 +2061,13 @@ static int mxc_hdmi_fb_event(struct notifier_block *nb,
case FB_EVENT_FB_REGISTERED:
dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_FB_REGISTERED\n");
mxc_hdmi_fb_registered(hdmi);
+ hdmi_set_registered(1);
break;
case FB_EVENT_FB_UNREGISTERED:
dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_FB_UNREGISTERED\n");
hdmi->fb_reg = false;
+ hdmi_set_registered(0);
break;
case FB_EVENT_MODE_CHANGE:
@@ -2096,6 +2099,8 @@ static int mxc_hdmi_disp_init(struct mxc_dispdrv_handle *disp,
struct mxc_dispdrv_setting *setting)
{
int ret = 0;
+ u32 i;
+ const struct fb_videomode *mode;
struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
struct fsl_mxc_hdmi_platform_data *plat = hdmi->pdev->dev.platform_data;
int irq = platform_get_irq(hdmi->pdev, 0);
@@ -2184,8 +2189,27 @@ static int mxc_hdmi_disp_init(struct mxc_dispdrv_handle *disp,
spin_lock_init(&hdmi->irq_lock);
- fb_add_videomode(&vga_mode, &hdmi->fbi->modelist);
- fb_videomode_to_var(&hdmi->fbi->var, &vga_mode);
+ /* Set the default mode and modelist when disp init. */
+ fb_find_mode(&hdmi->fbi->var, hdmi->fbi,
+ hdmi->dft_mode_str, NULL, 0, NULL,
+ hdmi->default_bpp);
+
+ console_lock();
+
+ fb_destroy_modelist(&hdmi->fbi->modelist);
+
+ /*Add all no interlaced CEA mode to default modelist */
+ for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
+ mode = &mxc_cea_mode[i];
+ if (!(mode->vmode & FB_VMODE_INTERLACED) && (mode->xres != 0))
+ fb_add_videomode(mode, &hdmi->fbi->modelist);
+ }
+
+ /*Add XGA and SXGA to default modelist */
+ fb_add_videomode(&xga_mode, &hdmi->fbi->modelist);
+ fb_add_videomode(&sxga_mode, &hdmi->fbi->modelist);
+
+ console_unlock();
INIT_DELAYED_WORK(&hdmi->hotplug_work, hotplug_worker);
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index e96cca48cbf8..63c4407fc51f 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -124,7 +124,12 @@ struct fsl_usb2_platform_data {
void (*wakeup_handler)(struct fsl_usb2_platform_data *);
void (*hsic_post_ops)(void);
void (*hsic_device_connected)(void);
- void (*gadget_discharge_dp) (bool);
+ /*
+ * Some platforms, like i.mx6x needs to discharge dp/dm at device mode
+ * or there is wakeup interrupt caused by dp/dm change when the cable
+ * is disconnected with Host.
+ */
+ void (*dr_discharge_line) (bool);
struct fsl_usb2_wakeup_platform_data *wakeup_pdata;
struct platform_device *pdev;
diff --git a/include/linux/mfd/mxc-hdmi-core.h b/include/linux/mfd/mxc-hdmi-core.h
index b607feec147a..0b241838f1b9 100644
--- a/include/linux/mfd/mxc-hdmi-core.h
+++ b/include/linux/mfd/mxc-hdmi-core.h
@@ -46,4 +46,7 @@ void hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg);
extern int mxc_hdmi_ipu_id;
extern int mxc_hdmi_disp_id;
+void hdmi_set_registered(int registered);
+int hdmi_get_registered(void);
+
#endif
diff --git a/sound/soc/codecs/mxc_hdmi.c b/sound/soc/codecs/mxc_hdmi.c
index 70c9b8c9bfe0..4d9a5719eeae 100644
--- a/sound/soc/codecs/mxc_hdmi.c
+++ b/sound/soc/codecs/mxc_hdmi.c
@@ -348,6 +348,9 @@ static int mxc_hdmi_codec_soc_probe(struct snd_soc_codec *codec)
struct mxc_hdmi_priv *hdmi_priv;
int ret = 0;
+ if (!hdmi_get_registered())
+ return -ENOMEM;
+
hdmi_priv = kzalloc(sizeof(struct mxc_hdmi_priv), GFP_KERNEL);
if (hdmi_priv == NULL)
return -ENOMEM;
diff --git a/sound/soc/imx/imx-hdmi-dai.c b/sound/soc/imx/imx-hdmi-dai.c
index 71cb3a56530f..0a1686bfcacd 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 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
*
* Based on stmp3xxx_spdif_dai.c
* Vladimir Barinov <vbarinov@embeddedalley.com>
@@ -42,6 +42,9 @@ static int imx_hdmi_dai_probe(struct platform_device *pdev)
struct imx_hdmi *hdmi_data;
int ret = 0;
+ if (!hdmi_get_registered())
+ return -ENOMEM;
+
hdmi_data = kzalloc(sizeof(*hdmi_data), GFP_KERNEL);
if (!hdmi_data)
return -ENOMEM;
diff --git a/sound/soc/imx/imx-hdmi-dma.c b/sound/soc/imx/imx-hdmi-dma.c
index d0c4d52e9c56..930cc2cc5785 100644
--- a/sound/soc/imx/imx-hdmi-dma.c
+++ b/sound/soc/imx/imx-hdmi-dma.c
@@ -310,16 +310,12 @@ static irqreturn_t hdmi_dma_isr(int irq, void *dev_id)
spin_lock_irqsave(&rtd->irq_lock, flags);
- if (!rtd->tx_active) {
- spin_unlock_irqrestore(&rtd->irq_lock, flags);
- return IRQ_HANDLED;
- }
-
hdmi_dma_irq_mute(1);
status = hdmi_dma_get_irq_status();
hdmi_dma_clear_irq_status(status);
- if (status & HDMI_IH_AHBDMAAUD_STAT0_DONE) {
+ if (runtime && runtime->dma_area && rtd->tx_active &&
+ (status & HDMI_IH_AHBDMAAUD_STAT0_DONE)) {
rtd->offset += rtd->period_bytes;
rtd->offset %= rtd->period_bytes * rtd->periods;
@@ -605,12 +601,14 @@ static int hdmi_dma_trigger(struct snd_pcm_substream *substream, int cmd)
}
dumpregs();
hdmi_dma_irq_mask(0);
+ hdmi_dma_priv->tx_active = true;
hdmi_dma_start();
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ hdmi_dma_priv->tx_active = false;
hdmi_dma_stop();
hdmi_dma_irq_mask(1);
break;
@@ -662,7 +660,6 @@ static void hdmi_dma_irq_enable(struct imx_hdmi_dma_runtime_data *rtd)
hdmi_irq_enable(hdmi_dma_priv->irq);
hdmi_dma_irq_mute(0);
hdmi_dma_irq_mask(0);
- hdmi_dma_priv->tx_active = true;
spin_unlock_irqrestore(&hdmi_dma_priv->irq_lock, flags);
@@ -678,7 +675,6 @@ static void hdmi_dma_irq_disable(struct imx_hdmi_dma_runtime_data *rtd)
hdmi_dma_irq_mute(1);
hdmi_irq_disable(rtd->irq);
hdmi_dma_clear_irq_status(0xff);
- rtd->tx_active = false;
spin_unlock_irqrestore(&rtd->irq_lock, flags);
}
diff --git a/sound/soc/imx/imx-hdmi.c b/sound/soc/imx/imx-hdmi.c
index f2316c1fe081..a30d478af9de 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 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
*
* based on stmp3780_devb_spdif.c
*
@@ -57,6 +57,9 @@ static int __init imx_hdmi_init(void)
{
int ret = 0;
+ if (!hdmi_get_registered())
+ return -ENOMEM;
+
imx_hdmi_snd_device = platform_device_alloc("soc-audio", 4);
if (!imx_hdmi_snd_device) {
pr_err("%s - failed platform_device_alloc\n", __func__);