diff options
author | guoyin.chen <guoyin.chen@freescale.com> | 2013-03-06 15:07:12 +0800 |
---|---|---|
committer | guoyin.chen <guoyin.chen@freescale.com> | 2013-03-06 15:07:12 +0800 |
commit | 4becc339ef23d54b39139a85bb6e33b7f27d67d1 (patch) | |
tree | 583571dd15b19d2e0592e15ff5ffee6e9c24ab6c /arch/arm | |
parent | f072008f5a29068baa0bc1febad8aaf2840e2568 (diff) | |
parent | 180c995fa9dfd1912e199d908ae55b2b8c479d13 (diff) |
Merge remote-tracking branch 'fsl-linux-sdk/imx_3.0.35' into imx_3.0.35_android
Conflicts:
drivers/video/mxc/ldb.c
Diffstat (limited to 'arch/arm')
24 files changed, 385 insertions, 110 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index c132e8145754..478e2a7cd721 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -235,7 +235,7 @@ void cpu_idle(void) #ifdef CONFIG_PL310_ERRATA_769419 wmb(); #endif - if (hlt_counter) { + if (hlt_counter || tick_check_broadcast_pending()) { local_irq_enable(); cpu_relax(); } else { diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.c b/arch/arm/mach-mx6/board-mx6q_arm2.c index c99d10377186..d627324d77ab 100644 --- a/arch/arm/mach-mx6/board-mx6q_arm2.c +++ b/arch/arm/mach-mx6/board-mx6q_arm2.c @@ -337,6 +337,16 @@ static int mx6_arm2_fec_phy_init(struct phy_device *phydev) { unsigned short val; + /* Ar8031 phy SmartEEE feature cause link status generates glitch, + * which cause ethernet link down/up issue, so disable SmartEEE + */ + phy_write(phydev, 0xd, 0x3); + phy_write(phydev, 0xe, 0x805d); + phy_write(phydev, 0xd, 0x4003); + val = phy_read(phydev, 0xe); + val &= ~(0x1 << 8); + phy_write(phydev, 0xe, val); + /* To enable AR8031 ouput a 125MHz clk from CLK_25M */ phy_write(phydev, 0xd, 0x7); phy_write(phydev, 0xe, 0x8016); diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.c b/arch/arm/mach-mx6/board-mx6q_sabreauto.c index cb68c8aeb89d..a5b6cc6c1cc3 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabreauto.c +++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.c @@ -347,6 +347,17 @@ static int mx6q_sabreauto_fec_phy_init(struct phy_device *phydev) unsigned short val; if (!board_is_mx6_reva()) { + /* Ar8031 phy SmartEEE feature cause link status generates + * glitch, which cause ethernet link down/up issue, so + * disable SmartEEE + */ + phy_write(phydev, 0xd, 0x3); + phy_write(phydev, 0xe, 0x805d); + phy_write(phydev, 0xd, 0x4003); + val = phy_read(phydev, 0xe); + val &= ~(0x1 << 8); + phy_write(phydev, 0xe, val); + /* To enable AR8031 ouput a 125MHz clk from CLK_25M */ phy_write(phydev, 0xd, 0x7); phy_write(phydev, 0xe, 0x8016); diff --git a/arch/arm/mach-mx6/board-mx6q_sabrelite.c b/arch/arm/mach-mx6/board-mx6q_sabrelite.c index 13d552052abc..24914fe6904b 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabrelite.c +++ b/arch/arm/mach-mx6/board-mx6q_sabrelite.c @@ -633,7 +633,7 @@ static struct i2c_board_info mxc_i2c1_board_info[] __initdata = { I2C_BOARD_INFO("mxc_hdmi_i2c", 0x50), }, { - I2C_BOARD_INFO("ov5642", 0x3c), + I2C_BOARD_INFO("ov564x", 0x3c), .platform_data = (void *)&camera_data, }, }; diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c index 183f1b9afe42..a53d6105e0b0 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabresd.c +++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c @@ -257,6 +257,16 @@ static int mx6q_sabresd_fec_phy_init(struct phy_device *phydev) { unsigned short val; + /* Ar8031 phy SmartEEE feature cause link status generates glitch, + * which cause ethernet link down/up issue, so disable SmartEEE + */ + phy_write(phydev, 0xd, 0x3); + phy_write(phydev, 0xe, 0x805d); + phy_write(phydev, 0xd, 0x4003); + val = phy_read(phydev, 0xe); + val &= ~(0x1 << 8); + phy_write(phydev, 0xe, val); + /* To enable AR8031 ouput a 125MHz clk from CLK_25M */ phy_write(phydev, 0xd, 0x7); phy_write(phydev, 0xe, 0x8016); @@ -785,7 +795,7 @@ static struct i2c_board_info mxc_i2c0_board_info[] __initdata = { I2C_BOARD_INFO("wm89**", 0x1a), }, { - I2C_BOARD_INFO("ov5642", 0x3c), + I2C_BOARD_INFO("ov564x", 0x3c), .platform_data = (void *)&camera_data, }, { @@ -1091,6 +1101,14 @@ static void imx6q_sabresd_usbotg_vbus(bool on) gpio_set_value(SABRESD_USB_OTG_PWR, 0); } +static void imx6q_sabresd_host1_vbus(bool on) +{ + if (on) + gpio_set_value(SABRESD_USB_H1_PWR, 1); + else + gpio_set_value(SABRESD_USB_H1_PWR, 0); +} + static void __init imx6q_sabresd_init_usb(void) { int ret = 0; @@ -1113,13 +1131,14 @@ static void __init imx6q_sabresd_init_usb(void) ret); return; } - gpio_direction_output(SABRESD_USB_H1_PWR, 1); + gpio_direction_output(SABRESD_USB_H1_PWR, 0); if (board_is_mx6_reva()) mxc_iomux_set_gpr_register(1, 13, 1, 1); else mxc_iomux_set_gpr_register(1, 13, 1, 0); mx6_set_otghost_vbus_func(imx6q_sabresd_usbotg_vbus); + mx6_set_host1_vbus_func(imx6q_sabresd_host1_vbus); } diff --git a/arch/arm/mach-mx6/usb_dr.c b/arch/arm/mach-mx6/usb_dr.c index 8f909321e219..7c8ef2f16447 100644 --- a/arch/arm/mach-mx6/usb_dr.c +++ b/arch/arm/mach-mx6/usb_dr.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 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 @@ -65,6 +65,7 @@ static struct fsl_usb2_platform_data dr_utmi_config = { .transceiver = "utmi", .phy_regs = USB_PHY0_BASE_ADDR, .dr_discharge_line = _dr_discharge_line, + .lowpower = true, /* Default driver low power is true */ }; /* Platform data for wakeup operation */ @@ -74,51 +75,6 @@ static struct fsl_usb2_wakeup_platform_data dr_wakeup_config = { .usb_wakeup_exhandle = usbotg_wakeup_event_clear, }; -static void fsl_platform_otg_set_usb_phy_dis( - struct fsl_usb2_platform_data *pdata, bool enable) -{ - u32 usb_phy_ctrl_dcdt = 0; - void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); - usb_phy_ctrl_dcdt = __raw_readl( - MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL) & - BM_USBPHY_CTRL_ENHOSTDISCONDETECT; - if (enable) { - if (usb_phy_ctrl_dcdt == 0) { - __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS, - anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_CLR); - - __raw_writel(BM_USBPHY_PWD_RXPWDENV, - MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_PWD_SET); - - udelay(300); - - __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, - MX6_IO_ADDRESS(pdata->phy_regs) - + HW_USBPHY_CTRL_SET); - - UOG_USBSTS |= (1 << 7); - - while ((UOG_USBSTS & (1 << 7)) == 0) - ; - - udelay(2); - - __raw_writel(BM_USBPHY_PWD_RXPWDENV, - MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_PWD_CLR); - - __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS, - anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET); - - } - } else { - if (usb_phy_ctrl_dcdt - == BM_USBPHY_CTRL_ENHOSTDISCONDETECT) - __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, - MX6_IO_ADDRESS(pdata->phy_regs) - + HW_USBPHY_CTRL_CLR); - } -} - static void usbotg_internal_phy_clock_gate(bool on) { void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR); @@ -208,9 +164,6 @@ static void usbotg_uninit_ext(struct platform_device *pdev) { otg_used--; if (!otg_used) { - enter_phy_lowpower_suspend(pdev->dev.platform_data, true); - mdelay(3); - clk_disable(usb_phy1_clk); clk_put(usb_phy1_clk); @@ -387,6 +340,51 @@ static void usbotg_wakeup_event_clear(void) #ifdef CONFIG_USB_EHCI_ARC_OTG /* Beginning of host related operation for DR port */ +static void fsl_platform_otg_set_usb_phy_dis( + struct fsl_usb2_platform_data *pdata, bool enable) +{ + u32 usb_phy_ctrl_dcdt = 0; + void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); + usb_phy_ctrl_dcdt = __raw_readl( + MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL) & + BM_USBPHY_CTRL_ENHOSTDISCONDETECT; + if (enable) { + if (usb_phy_ctrl_dcdt == 0) { + __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS, + anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_CLR); + + __raw_writel(BM_USBPHY_PWD_RXPWDENV, + MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_PWD_SET); + + udelay(300); + + __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, + MX6_IO_ADDRESS(pdata->phy_regs) + + HW_USBPHY_CTRL_SET); + + UOG_USBSTS |= (1 << 7); + + while ((UOG_USBSTS & (1 << 7)) == 0) + ; + + udelay(2); + + __raw_writel(BM_USBPHY_PWD_RXPWDENV, + MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_PWD_CLR); + + __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS, + anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET); + + } + } else { + if (usb_phy_ctrl_dcdt + == BM_USBPHY_CTRL_ENHOSTDISCONDETECT) + __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, + MX6_IO_ADDRESS(pdata->phy_regs) + + HW_USBPHY_CTRL_CLR); + } +} + static void _host_platform_rh_suspend_swfix(struct fsl_usb2_platform_data *pdata) { void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR); @@ -612,11 +610,11 @@ static int __init mx6_usb_dr_init(void) void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); struct imx_fsl_usb2_wakeup_data imx6q_fsl_otg_wakeup_data = imx_fsl_usb2_wakeup_data_entry_single(MX6Q, 0, OTG); - struct imx_mxc_ehci_data imx6q_mxc_ehci_otg_data = + struct imx_mxc_ehci_data __maybe_unused imx6q_mxc_ehci_otg_data = imx_mxc_ehci_data_entry_single(MX6Q, 0, OTG); - struct imx_fsl_usb2_udc_data imx6q_fsl_usb2_udc_data = + struct imx_fsl_usb2_udc_data __maybe_unused imx6q_fsl_usb2_udc_data = imx_fsl_usb2_udc_data_entry_single(MX6Q); - struct imx_fsl_usb2_otg_data imx6q_fsl_usb2_otg_data = + struct imx_fsl_usb2_otg_data __maybe_unused imx6q_fsl_usb2_otg_data = imx_fsl_usb2_otg_data_entry_single(MX6Q); /* Some phy and power's special controls for otg diff --git a/arch/arm/mach-mx6/usb_h1.c b/arch/arm/mach-mx6/usb_h1.c index eb79bf35b16c..d983e2870045 100644 --- a/arch/arm/mach-mx6/usb_h1.c +++ b/arch/arm/mach-mx6/usb_h1.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 @@ -401,8 +401,7 @@ static int __init mx6_usb_h1_init(void) imx_mxc_ehci_data_entry_single(MX6SL, 1, HS1)}; mx6_get_host1_vbus_func(&mx6_set_usb_host1_vbus); - if (mx6_set_usb_host1_vbus) - mx6_set_usb_host1_vbus(true); + usbh1_config.platform_driver_vbus = mx6_set_usb_host1_vbus; /* Some phy and power's special controls for host1 * 1. The external charger detector needs to be disabled @@ -457,8 +456,6 @@ static void __exit mx6_usb_h1_exit(void) | BM_ANADIG_USB2_PLL_480_CTRL_POWER \ | BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS, \ anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR); - if (mx6_set_usb_host1_vbus) - mx6_set_usb_host1_vbus(false); return ; } diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index 6ff1c9072104..1aa1780231d0 100755 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -3,7 +3,7 @@ # # Common support -obj-y := clock.o gpio.o time.o devices.o cpu.o system.o irq-common.o usb_common.o usb_wakeup.o +obj-y := clock.o gpio.o time.o devices.o cpu.o system.o irq-common.o usb_common.o usb_wakeup.o fuse.o # MX51 uses the TZIC interrupt controller, older platforms use AVIC obj-$(CONFIG_MXC_TZIC) += tzic.o diff --git a/arch/arm/plat-mxc/devices/platform-ahci-imx.c b/arch/arm/plat-mxc/devices/platform-ahci-imx.c index 30bfeaaac3d6..90d994c27f9b 100755 --- a/arch/arm/plat-mxc/devices/platform-ahci-imx.c +++ b/arch/arm/plat-mxc/devices/platform-ahci-imx.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -54,6 +54,9 @@ struct platform_device *__init imx_add_ahci( }, }; + if (!fuse_dev_is_available(MXC_DEV_SATA)) + return ERR_PTR(-ENODEV); + return imx_add_platform_device_dmamask("ahci", 0 /* -1? */, res, ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32)); diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/plat-mxc/devices/platform-fec.c index 20422cf6e76f..0a03ea9b92b2 100644 --- a/arch/arm/plat-mxc/devices/platform-fec.c +++ b/arch/arm/plat-mxc/devices/platform-fec.c @@ -6,7 +6,7 @@ * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. * - * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. */ #include <linux/dma-mapping.h> #include <asm/sizes.h> @@ -74,6 +74,9 @@ struct platform_device *__init imx_add_fec( }, }; + if (!fuse_dev_is_available(MXC_DEV_ENET)) + return ERR_PTR(-ENODEV); + return imx_add_platform_device_dmamask(data->devid, 0, res, ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32)); diff --git a/arch/arm/plat-mxc/devices/platform-imx-epdc-fb.c b/arch/arm/plat-mxc/devices/platform-imx-epdc-fb.c index 404a264e7ddc..459e6cc3ea0c 100644 --- a/arch/arm/plat-mxc/devices/platform-imx-epdc-fb.c +++ b/arch/arm/plat-mxc/devices/platform-imx-epdc-fb.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. */ /* @@ -55,6 +55,9 @@ struct platform_device *__init imx_add_imx_epdc( }, }; + if (!fuse_dev_is_available(MXC_DEV_EPDC)) + return ERR_PTR(-ENODEV); + return imx_add_platform_device_dmamask("imx_epdc_fb", -1, res, ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32)); } diff --git a/arch/arm/plat-mxc/devices/platform-imx-hdmi-soc-dai.c b/arch/arm/plat-mxc/devices/platform-imx-hdmi-soc-dai.c index 813f954517bb..26f4ae71edf1 100644 --- a/arch/arm/plat-mxc/devices/platform-imx-hdmi-soc-dai.c +++ b/arch/arm/plat-mxc/devices/platform-imx-hdmi-soc-dai.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Freescale Semiconductor, Inc. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. */ /* @@ -42,6 +42,9 @@ struct platform_device *__init imx_add_hdmi_soc_dai( }, }; + if (!fuse_dev_is_available(MXC_DEV_HDMI)) + return ERR_PTR(-ENODEV); + return imx_add_platform_device("imx-hdmi-soc-dai", 0, res, ARRAY_SIZE(res), NULL, 0); } diff --git a/arch/arm/plat-mxc/devices/platform-imx-hdmi-soc.c b/arch/arm/plat-mxc/devices/platform-imx-hdmi-soc.c index 33c8a685e8a4..7be6756c1ac8 100644 --- a/arch/arm/plat-mxc/devices/platform-imx-hdmi-soc.c +++ b/arch/arm/plat-mxc/devices/platform-imx-hdmi-soc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -22,7 +22,12 @@ #include <mach/devices-common.h> struct platform_device *__init imx_add_hdmi_soc(void) -{ return imx_add_platform_device("mxc_hdmi_soc", 0, +{ + + if (!fuse_dev_is_available(MXC_DEV_HDMI)) + return ERR_PTR(-ENODEV); + + return imx_add_platform_device("mxc_hdmi_soc", 0, NULL, 0, NULL, 0); } diff --git a/arch/arm/plat-mxc/devices/platform-imx-pcie.c b/arch/arm/plat-mxc/devices/platform-imx-pcie.c index cf3609365129..7e0d630f92e2 100644 --- a/arch/arm/plat-mxc/devices/platform-imx-pcie.c +++ b/arch/arm/plat-mxc/devices/platform-imx-pcie.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -55,6 +55,9 @@ struct platform_device *__init imx_add_pcie( }, }; + if (!fuse_dev_is_available(MXC_DEV_PCIE)) + return ERR_PTR(-ENODEV); + return imx_add_platform_device("imx-pcie", -1, res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); diff --git a/arch/arm/plat-mxc/devices/platform-imx-pxp.c b/arch/arm/plat-mxc/devices/platform-imx-pxp.c index 418489e1c4ea..fed58d09306d 100644 --- a/arch/arm/plat-mxc/devices/platform-imx-pxp.c +++ b/arch/arm/plat-mxc/devices/platform-imx-pxp.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. */ /* @@ -54,18 +54,27 @@ struct platform_device *__init imx_add_imx_pxp( }, }; + if (!fuse_dev_is_available(MXC_DEV_PXP)) + return ERR_PTR(-ENODEV); + return imx_add_platform_device_dmamask("imx-pxp", -1, res, ARRAY_SIZE(res), NULL, 0, DMA_BIT_MASK(32)); } struct platform_device *__init imx_add_imx_pxp_client() { - return imx_add_platform_device("imx-pxp-client", -1, + if (!fuse_dev_is_available(MXC_DEV_PXP)) + return ERR_PTR(-ENODEV); + + return imx_add_platform_device("imx-pxp-client", -1, NULL, 0, NULL, 0); } struct platform_device *__init imx_add_imx_pxp_v4l2() { - return imx_add_platform_device_dmamask("pxp-v4l2", -1, + if (!fuse_dev_is_available(MXC_DEV_PXP)) + return ERR_PTR(-ENODEV); + + return imx_add_platform_device_dmamask("pxp-v4l2", -1, NULL, 0, NULL, 0, DMA_BIT_MASK(32)); } diff --git a/arch/arm/plat-mxc/devices/platform-imx_vpu.c b/arch/arm/plat-mxc/devices/platform-imx_vpu.c index 83faed6e7b6a..9e00b2fd22aa 100755 --- a/arch/arm/plat-mxc/devices/platform-imx_vpu.c +++ b/arch/arm/plat-mxc/devices/platform-imx_vpu.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. * Jason Chen <jason.chen@freescale.com> * * This program is free software; you can redistribute it and/or modify it under @@ -167,15 +167,9 @@ struct platform_device *__init imx_add_vpu( pdata.iram_enable = data->iram_enable; pdata.iram_size = data->iram_size; -#ifdef CONFIG_SOC_IMX6Q - if (cpu_is_mx6dl() || cpu_is_mx6q()) { - #define HW_OCOTP_CFGn(n) (0x00000410 + (n) * 0x10) - unsigned int vpu_disable; - vpu_disable = readl(MX6_IO_ADDRESS(OCOTP_BASE_ADDR) + HW_OCOTP_CFGn(3)); - if (vpu_disable & 0x00008000) - return ERR_PTR(-ENODEV); - } -#endif + if (!fuse_dev_is_available(MXC_DEV_VPU)) + return ERR_PTR(-ENODEV); + if (cpu_is_mx6dl()) pdata.iram_enable = false; diff --git a/arch/arm/plat-mxc/devices/platform-mxc-hdmi-core.c b/arch/arm/plat-mxc/devices/platform-mxc-hdmi-core.c index e0c1906166a2..2c9a32a9b568 100644 --- a/arch/arm/plat-mxc/devices/platform-mxc-hdmi-core.c +++ b/arch/arm/plat-mxc/devices/platform-mxc-hdmi-core.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -45,6 +45,9 @@ struct platform_device *__init imx_add_mxc_hdmi_core( }, }; + if (!fuse_dev_is_available(MXC_DEV_HDMI)) + return ERR_PTR(-ENODEV); + return imx_add_platform_device_dmamask("mxc_hdmi_core", -1, res, ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32)); } diff --git a/arch/arm/plat-mxc/devices/platform-mxc_hdmi.c b/arch/arm/plat-mxc/devices/platform-mxc_hdmi.c index d4952620e223..cdbdae4999db 100644 --- a/arch/arm/plat-mxc/devices/platform-mxc_hdmi.c +++ b/arch/arm/plat-mxc/devices/platform-mxc_hdmi.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. */ /* @@ -43,6 +43,10 @@ struct platform_device *__init imx_add_mxc_hdmi( .flags = IORESOURCE_IRQ, }, }; + + if (!fuse_dev_is_available(MXC_DEV_HDMI)) + return ERR_PTR(-ENODEV); + imx_add_platform_device("mxc_hdmi_cec", 0, res, ARRAY_SIZE(res), NULL, 0); return imx_add_platform_device_dmamask("mxc_hdmi", -1, diff --git a/arch/arm/plat-mxc/devices/platform-mxc_mlb.c b/arch/arm/plat-mxc/devices/platform-mxc_mlb.c index 661595fd5f38..8925f3ee0690 100644 --- a/arch/arm/plat-mxc/devices/platform-mxc_mlb.c +++ b/arch/arm/plat-mxc/devices/platform-mxc_mlb.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 @@ -44,8 +44,6 @@ struct platform_device *__init imx_add_mlb( struct platform_device *__init imx_add_mlb( const struct mxc_mlb_platform_data *pdata) { -#define HW_OCOTP_CFGn(n) (0x00000410 + (n) * 0x10) - unsigned int mlb_disable = 0; struct resource res[] = { { .start = MLB_BASE_ADDR, @@ -69,9 +67,9 @@ struct platform_device *__init imx_add_mlb( }, }; - mlb_disable = readl(MX6_IO_ADDRESS(OCOTP_BASE_ADDR) + HW_OCOTP_CFGn(2)); - if (mlb_disable & 0x04000000) + if (!fuse_dev_is_available(MXC_DEV_MLB)) return ERR_PTR(-ENODEV); + return imx_add_platform_device("mxc_mlb150", 0, res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); } diff --git a/arch/arm/plat-mxc/devices/platform-viv_gpu.c b/arch/arm/plat-mxc/devices/platform-viv_gpu.c index 9b0219695c00..52c9b082b6ae 100644 --- a/arch/arm/plat-mxc/devices/platform-viv_gpu.c +++ b/arch/arm/plat-mxc/devices/platform-viv_gpu.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. */ /* @@ -90,13 +90,36 @@ struct platform_device *__init imx_add_viv_gpu( }, }; - if (cpu_is_mx6q() || cpu_is_mx6sl()) - res_count = ARRAY_SIZE(res); - else if (cpu_is_mx6dl()) - /* No openVG on i.mx6 Solo/DL */ - res_count = ARRAY_SIZE(res) - 2; + res_count = ARRAY_SIZE(res); BUG_ON(!res_count); + if (!fuse_dev_is_available(MXC_DEV_3D)) { + res[1].start = 0; + res[1].end = 0; + res[2].start = -1; + res[2].end = -1; + } + + if (!fuse_dev_is_available(MXC_DEV_2D)) { + res[3].start = 0; + res[3].end = 0; + res[4].start = -1; + res[4].end = -1; + } + + if (!fuse_dev_is_available(MXC_DEV_OVG)) { + res[5].start = 0; + res[5].end = 0; + res[6].start = -1; + res[6].end = -1; + } + + /* None GPU core exists */ + if ((res[2].start == -1) && + (res[4].start == -1) && + (res[6].start == -1)) + return ERR_PTR(-ENODEV); + return imx_add_platform_device_dmamask("galcore", 0, res, res_count, pdata, sizeof(*pdata), diff --git a/arch/arm/plat-mxc/fuse.c b/arch/arm/plat-mxc/fuse.c new file mode 100644 index 000000000000..1238e76b75a2 --- /dev/null +++ b/arch/arm/plat-mxc/fuse.c @@ -0,0 +1,165 @@ +/* + * Copyright (C) 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <linux/io.h> +#include <linux/kernel.h> +#include <mach/hardware.h> + +#define HW_OCOTP_CFGn(n) (0x00000410 + (n) * 0x10) + +/* Note: the names oder is the same as device enum order defined in mxc.h */ +static char *names[] = { + "pxp", "ovg", "dsi_csi2", "enet", "mlb", + "epdc", "hdmi", "pcie", "sata", "dtcp", + "2d", "3d", "vpu", "divx3", "rv", + "sorensen", +}; + +int fuse_dev_is_available(enum mxc_dev_type dev) +{ + u32 uninitialized_var(reg); + u32 uninitialized_var(mask); + int ret; + + if (!cpu_is_mx6()) + return 1; + + /* mx6sl is still not supported */ + if (cpu_is_mx6sl()) + return 1; + + switch (dev) { + case MXC_DEV_PXP: + if (cpu_is_mx6q()) + return 0; + + if (cpu_is_mx6dl()) { + reg = HW_OCOTP_CFGn(2); + mask = 0x80000000; + } + break; + case MXC_DEV_OVG: + if (cpu_is_mx6dl()) + return 0; + + if (cpu_is_mx6q()) { + reg = HW_OCOTP_CFGn(2); + mask = 0x40000000; + } + break; + case MXC_DEV_DSI_CSI2: + if (cpu_is_mx6dl() || cpu_is_mx6q()) { + reg = HW_OCOTP_CFGn(2); + mask = 0x10000000; + } + break; + case MXC_DEV_ENET: + if (cpu_is_mx6dl() || cpu_is_mx6q()) { + reg = HW_OCOTP_CFGn(2); + mask = 0x08000000; + } + break; + case MXC_DEV_MLB: + if (cpu_is_mx6dl() || cpu_is_mx6q()) { + reg = HW_OCOTP_CFGn(2); + mask = 0x04000000; + } + break; + case MXC_DEV_EPDC: + if (cpu_is_mx6q()) + return 0; + + if (cpu_is_mx6dl()) { + reg = HW_OCOTP_CFGn(2); + mask = 0x02000000; + } + break; + case MXC_DEV_HDMI: + if (cpu_is_mx6dl() || cpu_is_mx6q()) { + reg = HW_OCOTP_CFGn(3); + mask = 0x00000080; + } + break; + case MXC_DEV_PCIE: + if (cpu_is_mx6dl() || cpu_is_mx6q()) { + reg = HW_OCOTP_CFGn(3); + mask = 0x00000040; + } + break; + case MXC_DEV_SATA: + if (cpu_is_mx6dl()) + return 0; + + if (cpu_is_mx6q()) { + reg = HW_OCOTP_CFGn(3); + mask = 0x00000020; + } + break; + case MXC_DEV_DTCP: + if (cpu_is_mx6dl() || cpu_is_mx6q()) { + reg = HW_OCOTP_CFGn(3); + mask = 0x00000010; + } + break; + case MXC_DEV_2D: + if (cpu_is_mx6dl() || cpu_is_mx6q()) { + reg = HW_OCOTP_CFGn(3); + mask = 0x00000008; + } + break; + case MXC_DEV_3D: + if (cpu_is_mx6dl() || cpu_is_mx6q()) { + reg = HW_OCOTP_CFGn(3); + mask = 0x00000004; + } + break; + case MXC_DEV_VPU: + if (cpu_is_mx6dl() || cpu_is_mx6q()) { + reg = HW_OCOTP_CFGn(3); + mask = 0x00008000; + } + break; + case MXC_DEV_DIVX3: + if (cpu_is_mx6dl() || cpu_is_mx6q()) { + reg = HW_OCOTP_CFGn(3); + mask = 0x00000400; + } + break; + case MXC_DEV_RV: + if (cpu_is_mx6dl() || cpu_is_mx6q()) { + reg = HW_OCOTP_CFGn(3); + mask = 0x00000200; + } + break; + case MXC_DEV_SORENSEN: + if (cpu_is_mx6dl() || cpu_is_mx6q()) { + reg = HW_OCOTP_CFGn(3); + mask = 0x00000100; + } + break; + default: + /* we treat the unkown device is avaiable by default */ + return 1; + } + + ret = readl(MX6_IO_ADDRESS(OCOTP_BASE_ADDR) + reg) & mask; + pr_debug("fuse_check: %s is %s\n", names[dev], ret ? + "unavailable" : "available"); + + return !ret; +} diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h index ee763a829bf2..ea60442a236f 100755 --- a/arch/arm/plat-mxc/include/mach/mxc.h +++ b/arch/arm/plat-mxc/include/mach/mxc.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007, 2011-2012 Freescale Semiconductor, Inc. + * Copyright 2004-2007, 2011-2013 Freescale Semiconductor, Inc. * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) * * This program is free software; you can redistribute it and/or @@ -278,6 +278,28 @@ int tzic_enable_wake(int is_idle); extern void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode); extern int tzic_enable_wake(int is_idle); + +/* available disableable devices in fuse */ +enum mxc_dev_type { + MXC_DEV_PXP, + MXC_DEV_OVG, + MXC_DEV_DSI_CSI2, + MXC_DEV_ENET, + MXC_DEV_MLB, + MXC_DEV_EPDC, + MXC_DEV_HDMI, + MXC_DEV_PCIE, + MXC_DEV_SATA, + MXC_DEV_DTCP, + MXC_DEV_2D, + MXC_DEV_3D, + MXC_DEV_VPU, + MXC_DEV_DIVX3, + MXC_DEV_RV, + MXC_DEV_SORENSEN, +}; +extern int fuse_dev_is_available(enum mxc_dev_type dev); + #endif #if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2) diff --git a/arch/arm/plat-mxc/usb_wakeup.c b/arch/arm/plat-mxc/usb_wakeup.c index 5d31d3621205..00af25f71a6a 100755 --- a/arch/arm/plat-mxc/usb_wakeup.c +++ b/arch/arm/plat-mxc/usb_wakeup.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 @@ -37,7 +37,6 @@ struct wakeup_ctrl { struct task_struct *thread; struct completion event; }; -static struct wakeup_ctrl *g_ctrl; extern int usb_event_is_otg_wakeup(struct fsl_usb2_platform_data *pdata); extern void usb_debounce_id_vbus(void); @@ -218,7 +217,7 @@ static int wakeup_dev_probe(struct platform_device *pdev) status = IS_ERR(ctrl->thread) ? -1 : 0; if (status) goto error2; - g_ctrl = ctrl; + platform_set_drvdata(pdev, ctrl); printk(KERN_DEBUG "the wakeup pdata is 0x%p\n", pdata); return 0; @@ -231,13 +230,14 @@ error1: static int wakeup_dev_exit(struct platform_device *pdev) { - if (g_ctrl->thread) { - g_ctrl->thread_close = true; - complete(&g_ctrl->event); - kthread_stop(g_ctrl->thread); - } - free_irq(g_ctrl->wakeup_irq, (void *)g_ctrl); - kfree(g_ctrl); + struct wakeup_ctrl *wctrl = platform_get_drvdata(pdev); + + wctrl->thread_close = true; + complete(&wctrl->event); + kthread_stop(wctrl->thread); + free_irq(wctrl->wakeup_irq, (void *)wctrl); + kfree(wctrl); + return 0; } static struct platform_driver wakeup_d = { diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 78829fab70ec..4ec53f30c310 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/types.h> #include <linux/cpu.h> +#include <linux/hardirq.h> #include <linux/kernel.h> #include <linux/notifier.h> #include <linux/signal.h> @@ -395,7 +396,10 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) static void vfp_enable(void *unused) { - u32 access = get_copro_access(); + u32 access; + + BUG_ON(preemptible()); + access = get_copro_access(); /* * Enable full access to VFP (cp10 and cp11) @@ -541,7 +545,7 @@ static int __init vfp_init(void) unsigned int cpu_arch = cpu_architecture(); if (cpu_arch >= CPU_ARCH_ARMv6) - vfp_enable(NULL); + on_each_cpu(vfp_enable, NULL, 1); /* * First check that there is a VFP that we can use. @@ -562,8 +566,6 @@ static int __init vfp_init(void) } else { hotcpu_notifier(vfp_hotplug, 0); - smp_call_function(vfp_enable, NULL, 1); - VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ printk("implementor %02x architecture %d part %02x variant %x rev %x\n", (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT, |