aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorguoyin.chen <guoyin.chen@freescale.com>2015-11-06 15:35:54 +0800
committerguoyin.chen <guoyin.chen@freescale.com>2015-11-06 15:35:54 +0800
commit0178da8d0207290467c801866fc98eb03f43431b (patch)
tree3e45b1b9f2a26d49162992c6d4d4ba1c1fc28a11
parent8cb4f07ce0a29100fee20b685d2d027dd05c1eb7 (diff)
parent44869a7d1715ec022d17f793cd20a5cc7dc34ffa (diff)
downloadfreescale-0178da8d0207290467c801866fc98eb03f43431b.tar.gz
Merge remote-tracking branch 'fsl-linux-sdk/imx_3.14.y' into imx_3.14.y_android
-rw-r--r--arch/arm/boot/dts/Makefile1
-rw-r--r--arch/arm/boot/dts/imx6qdl-sabresd.dtsi1
-rw-r--r--arch/arm/boot/dts/imx6qp-sabresd.dts4
-rw-r--r--arch/arm/boot/dts/imx6sx-sabreauto-m4.dts1
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb-btwifi.dts5
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-evk-btwifi.dts43
-rw-r--r--arch/arm/boot/dts/imx6ul-14x14-evk.dts15
-rw-r--r--arch/arm/boot/dts/imx6ul-9x9-evk-btwifi.dts10
-rw-r--r--arch/arm/boot/dts/imx6ul-9x9-evk.dts3
-rw-r--r--arch/arm/boot/dts/imx6ul-evk-btwifi.dtsi53
-rw-r--r--arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-m4.dts21
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-epdc.dts4
-rw-r--r--arch/arm/boot/dts/imx7d-sdb-m4.dts22
-rw-r--r--arch/arm/boot/dts/imx7d-sdb.dts4
-rw-r--r--arch/arm/configs/imx_v7_defconfig6
-rw-r--r--arch/arm/mach-imx/busfreq-imx.c3
-rw-r--r--arch/arm/mach-imx/common.h2
-rw-r--r--arch/arm/mach-imx/gpcv2.c50
-rw-r--r--arch/arm/mach-imx/mu.c47
-rw-r--r--arch/arm/mach-imx/pm-imx7.c53
-rw-r--r--arch/arm/mach-imx/suspend-imx7.S11
-rw-r--r--drivers/dma/pxp/pxp_dma_v2.c2
-rw-r--r--drivers/mmc/core/core.c6
-rw-r--r--drivers/mmc/core/mmc.c172
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c25
-rw-r--r--drivers/mmc/host/sdhci.c76
-rw-r--r--drivers/mmc/host/sdhci.h4
-rwxr-xr-xdrivers/mxc/sim/imx_sim.c50
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_sdio.c10
-rw-r--r--drivers/pci/host/pci-imx6.c6
-rw-r--r--drivers/tty/serial/imx.c19
-rw-r--r--drivers/video/mxsfb.c23
-rw-r--r--include/linux/mmc/card.h2
-rw-r--r--include/linux/mmc/host.h2
-rw-r--r--include/linux/mmc/mmc.h2
-rw-r--r--include/linux/mmc/sdhci.h1
-rw-r--r--include/sound/soc-dapm.h3
-rw-r--r--include/sound/soc.h1
-rw-r--r--sound/soc/codecs/wm8960.c2
-rw-r--r--sound/soc/codecs/wm8962.c5
-rw-r--r--sound/soc/soc-core.c1
-rw-r--r--sound/soc/soc-dapm.c20
42 files changed, 479 insertions, 312 deletions
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 715db929d34..a50978f3eb3 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -236,6 +236,7 @@ dtb-$(CONFIG_ARCH_MXC) += \
imx6ul-14x14-evk-btwifi.dtb \
imx6ul-14x14-evk-csi.dtb \
imx6ul-9x9-evk.dtb \
+ imx6ul-9x9-evk-btwifi.dtb \
imx6ul-9x9-evk-ldo.dtb \
imx6ul-9x9-evk-csi.dtb \
vf610-cosmic.dtb \
diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
index 79c48b212fa..d39576be2d9 100644
--- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
@@ -501,6 +501,7 @@
regulator-max-microvolt = <3300000>;
regulator-boot-on;
regulator-always-on;
+ regulator-ramp-delay = <6250>;
};
sw3a_reg: sw3a {
diff --git a/arch/arm/boot/dts/imx6qp-sabresd.dts b/arch/arm/boot/dts/imx6qp-sabresd.dts
index a4f066c0757..a77b375353c 100644
--- a/arch/arm/boot/dts/imx6qp-sabresd.dts
+++ b/arch/arm/boot/dts/imx6qp-sabresd.dts
@@ -13,6 +13,10 @@
model = "Freescale i.MX6 Quad Plus SABRE Smart Device Board";
};
+&cpu0 {
+ arm-supply = <&sw2_reg>;
+};
+
&iomuxc {
imx6qdl-sabresd {
pinctrl_usdhc2: usdhc2grp {
diff --git a/arch/arm/boot/dts/imx6sx-sabreauto-m4.dts b/arch/arm/boot/dts/imx6sx-sabreauto-m4.dts
index 3696c1a1fd6..f76bab1e31b 100644
--- a/arch/arm/boot/dts/imx6sx-sabreauto-m4.dts
+++ b/arch/arm/boot/dts/imx6sx-sabreauto-m4.dts
@@ -61,6 +61,7 @@
};
&qspi_m4 {
+ reg = <0x021e0000 0x4000>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6sx-sdb-btwifi.dts b/arch/arm/boot/dts/imx6sx-sdb-btwifi.dts
index 575ed3ce79f..a74d274a099 100644
--- a/arch/arm/boot/dts/imx6sx-sdb-btwifi.dts
+++ b/arch/arm/boot/dts/imx6sx-sdb-btwifi.dts
@@ -24,7 +24,6 @@
regulator-name = "wlreg_on";
gpio = <&gpio6 10 0>;
startup-delay-us = <100>;
- regulator-always-on;
enable-active-high;
};
};
@@ -93,6 +92,10 @@
bus-width = <1>;
};
+&vcc_sd3 {
+ regulator-always-on;
+};
+
&usdhc3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_wifi>;
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk-btwifi.dts b/arch/arm/boot/dts/imx6ul-14x14-evk-btwifi.dts
index 97a21dc54f6..4613799a97c 100644
--- a/arch/arm/boot/dts/imx6ul-14x14-evk-btwifi.dts
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk-btwifi.dts
@@ -6,46 +6,5 @@
* published by the Free Software Foundation.
*/
-/*
- * NOTE: This DTS file is written for plugging in Murata Wi-Fi/BT EVK into Slot
- * SD1 and using Murata i.MX InterConnect Ver 2.0 Adapter. Bluetooth UART &
- * control signals are connected via ribbon cable (J1701 connector).
- */
-
#include "imx6ul-14x14-evk.dts"
-
-/ {
- regulators {
- wlreg_on: fixedregulator@100 {
- compatible = "regulator-fixed";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- regulator-name = "wlreg_on";
- gpio = <&gpio5 1 0>;
- startup-delay-us = <100>;
- enable-active-high;
- };
- };
-
- bcmdhd_wlan_0: bcmdhd_wlan@0 {
- compatible = "android,bcmdhd_wlan";
- wlreg_on-supply = <&wlreg_on>;
- };
-};
-
-&iomuxc {
- imx6ul-evk-murata-v2 {
- pinctrl_wifi: wifigrp {
- fsl,pins = <
- MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x03029
- >;
- };
- };
-};
-
-&usdhc1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_wifi>;
- no-1-8-v;
- wifi-host; /* add hook for SD card detect mechanism for BCMDHD driver */
-};
+#include "imx6ul-evk-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dts b/arch/arm/boot/dts/imx6ul-14x14-evk.dts
index f2ef1f27a0b..6c98f61cca1 100644
--- a/arch/arm/boot/dts/imx6ul-14x14-evk.dts
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dts
@@ -284,7 +284,11 @@
assigned-clocks = <&clks IMX6UL_CLK_SIM_SEL>;
assigned-clock-parents = <&clks IMX6UL_CLK_SIM_PODF>;
assigned-clock-rates = <240000000>;
- pinctrl-assert-gpios = <&gpio4 23 GPIO_ACTIVE_LOW>;
+ /* GPIO_ACTIVE_HIGH/LOW:sim card voltage control
+ * NCN8025:Vcc = ACTIVE_HIGH?5V:3V
+ * TDA8035:Vcc = ACTIVE_HIGH?5V:1.8V
+ */
+ pinctrl-assert-gpios = <&gpio4 23 GPIO_ACTIVE_HIGH>;
port = <1>;
sven_low_active;
status = "okay";
@@ -345,6 +349,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc2>;
no-1-8-v;
+ non-removable;
keep-power-in-suspend;
enable-sdio-wakeup;
status = "okay";
@@ -544,10 +549,10 @@
pinctrl_sim2_1: sim2grp-1 {
fsl,pins = <
MX6UL_PAD_CSI_DATA03__SIM2_PORT1_PD 0xb808
- MX6UL_PAD_CSI_DATA04__SIM2_PORT1_CLK 0x31
- MX6UL_PAD_CSI_DATA05__SIM2_PORT1_RST_B 0xb808
- MX6UL_PAD_CSI_DATA06__SIM2_PORT1_SVEN 0xb808
- MX6UL_PAD_CSI_DATA07__SIM2_PORT1_TRXD 0xb809
+ MX6UL_PAD_CSI_DATA04__SIM2_PORT1_CLK 0x11
+ MX6UL_PAD_CSI_DATA05__SIM2_PORT1_RST_B 0xb810
+ MX6UL_PAD_CSI_DATA06__SIM2_PORT1_SVEN 0xb810
+ MX6UL_PAD_CSI_DATA07__SIM2_PORT1_TRXD 0xb811
MX6UL_PAD_CSI_DATA02__GPIO4_IO23 0x3008
>;
};
diff --git a/arch/arm/boot/dts/imx6ul-9x9-evk-btwifi.dts b/arch/arm/boot/dts/imx6ul-9x9-evk-btwifi.dts
new file mode 100644
index 00000000000..de89052d97f
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-9x9-evk-btwifi.dts
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "imx6ul-9x9-evk.dts"
+#include "imx6ul-evk-btwifi.dtsi"
diff --git a/arch/arm/boot/dts/imx6ul-9x9-evk.dts b/arch/arm/boot/dts/imx6ul-9x9-evk.dts
index 3b9047c30df..e04ff804612 100644
--- a/arch/arm/boot/dts/imx6ul-9x9-evk.dts
+++ b/arch/arm/boot/dts/imx6ul-9x9-evk.dts
@@ -758,7 +758,7 @@
pinctrl-0 = <&pinctrl_usdhc1>;
pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
- cd-gpios = <&gpio1 19 0>;
+ cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
keep-power-in-suspend;
enable-sdio-wakeup;
vmmc-supply = <&reg_sd1_vmmc>;
@@ -769,6 +769,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc2>;
no-1-8-v;
+ non-removable;
keep-power-in-suspend;
enable-sdio-wakeup;
status = "okay";
diff --git a/arch/arm/boot/dts/imx6ul-evk-btwifi.dtsi b/arch/arm/boot/dts/imx6ul-evk-btwifi.dtsi
new file mode 100644
index 00000000000..99a67cf8991
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ul-evk-btwifi.dtsi
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * NOTE: This DTS file is written for plugging in Murata Wi-Fi/BT EVK into Slot
+ * SD1 and using Murata i.MX InterConnect Ver 2.0 Adapter. Bluetooth UART &
+ * control signals are connected via ribbon cable (J1701 connector).
+ */
+
+/ {
+ regulators {
+ wlreg_on: fixedregulator@100 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "wlreg_on";
+ gpio = <&gpio5 1 0>;
+ startup-delay-us = <100>;
+ enable-active-high;
+ };
+ };
+
+ bcmdhd_wlan_0: bcmdhd_wlan@0 {
+ compatible = "android,bcmdhd_wlan";
+ wlreg_on-supply = <&wlreg_on>;
+ };
+};
+
+&iomuxc {
+ imx6ul-evk-murata-v2 {
+ pinctrl_wifi: wifigrp {
+ fsl,pins = <
+ MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x03029
+ >;
+ };
+ };
+};
+
+&reg_sd1_vmmc {
+ regulator-always-on;
+};
+
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_wifi>;
+ no-1-8-v;
+ wifi-host; /* add hook for SD card detect mechanism for BCMDHD driver */
+};
diff --git a/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-m4.dts b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-m4.dts
index 46b359f2a97..1c8de620f2d 100644
--- a/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-m4.dts
+++ b/arch/arm/boot/dts/imx7d-12x12-lpddr3-arm2-m4.dts
@@ -5,6 +5,10 @@
memory {
linux,usable-memory = <0x80000000 0x3ff00000>;
};
+
+ gpio-keys {
+ status = "disabled";
+ };
};
&adc1 {
@@ -15,17 +19,6 @@
status = "disabled";
};
-&iomuxc {
- imx7d-12x12-lpddr3-arm2 {
- pinctrl_uart2_1: uart2grp-1 {
- fsl,pins = <
- MX7D_PAD_UART2_RX_DATA__UART2_DCE_RX 0x79
- MX7D_PAD_UART2_TX_DATA__UART2_DCE_TX 0x79
- >;
- };
- };
-};
-
&gpt3 {
status = "disabled";
};
@@ -47,11 +40,7 @@
};
&uart2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart2_1>;
- assigned-clocks = <&clks IMX7D_UART2_ROOT_SRC>;
- assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
- status = "okay";
+ status = "disabled";
};
&wdog3{
diff --git a/arch/arm/boot/dts/imx7d-sdb-epdc.dts b/arch/arm/boot/dts/imx7d-sdb-epdc.dts
index acdbf761b6a..1cef0c3c092 100644
--- a/arch/arm/boot/dts/imx7d-sdb-epdc.dts
+++ b/arch/arm/boot/dts/imx7d-sdb-epdc.dts
@@ -20,6 +20,10 @@
status = "disabled";
};
+&flexcan2 {
+ status = "disabled";
+};
+
&max17135 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx7d-sdb-m4.dts b/arch/arm/boot/dts/imx7d-sdb-m4.dts
index d0bb0496c43..a6642a8d828 100644
--- a/arch/arm/boot/dts/imx7d-sdb-m4.dts
+++ b/arch/arm/boot/dts/imx7d-sdb-m4.dts
@@ -13,6 +13,11 @@
linux,usable-memory = <0x80000000 0x3ff00000>;
reg = <0x80000000 0x80000000>;
};
+
+ m4_tcm: tcml@007f8000 {
+ compatible = "fsl, m4_tcml";
+ reg = <0x007f8000 0x8000>;
+ };
};
&adc1 {
@@ -31,17 +36,6 @@
status = "disabled";
};
-&iomuxc {
- imx7d-sdb {
- pinctrl_uart2_1: uart2grp-1 {
- fsl,pins = <
- MX7D_PAD_UART2_RX_DATA__UART2_DCE_RX 0x79
- MX7D_PAD_UART2_TX_DATA__UART2_DCE_TX 0x79
- >;
- };
- };
-};
-
&gpt3 {
status = "disabled";
};
@@ -63,11 +57,7 @@
};
&uart2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart2_1>;
- assigned-clocks = <&clks IMX7D_UART2_ROOT_SRC>;
- assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
- status = "okay";
+ status = "disabled";
};
&wdog3{
diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
index 2086b7006dc..d84d1a78ef4 100644
--- a/arch/arm/boot/dts/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/imx7d-sdb.dts
@@ -74,7 +74,7 @@
regulator-name = "can2-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- gpio = <&gpio1 7 GPIO_ACTIVE_LOW>;
+ gpio = <&gpio2 14 GPIO_ACTIVE_LOW>;
};
reg_vref_1v8: regulator@3 {
@@ -977,7 +977,7 @@
pinctrl_hog_2: hoggrp-2 {
fsl,pins = <
MX7D_PAD_GPIO1_IO05__GPIO1_IO5 0x14
- MX7D_PAD_GPIO1_IO07__GPIO1_IO7 0x59 /* CAN_STBY */
+ MX7D_PAD_EPDC_DATA14__GPIO2_IO14 0x59 /* CAN_STBY */
MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_B 0x74
>;
};
diff --git a/arch/arm/configs/imx_v7_defconfig b/arch/arm/configs/imx_v7_defconfig
index abdf1dffcf2..e3315f315c1 100644
--- a/arch/arm/configs/imx_v7_defconfig
+++ b/arch/arm/configs/imx_v7_defconfig
@@ -152,18 +152,15 @@ CONFIG_USB_RTL8150=m
CONFIG_USB_RTL8152=m
CONFIG_USB_USBNET=m
CONFIG_USB_NET_CDC_EEM=m
-CONFIG_ATH_CARDS=y
-CONFIG_ATH6KL=m
-CONFIG_ATH6KL_SDIO=m
CONFIG_BCMDHD=m
CONFIG_BCMDHD_SDIO=y
CONFIG_BCMDHD_FW_PATH="/lib/firmware/bcm/fw_bcmdhd.bin"
CONFIG_BCMDHD_NVRAM_PATH="/lib/firmware/bcm/bcmdhd.cal"
+# CONFIG_RTL_CARDS is not set
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=m
CONFIG_KEYBOARD_GPIO=y
-CONFIG_KEYBOARD_SNVS_PWRKEY=y
CONFIG_KEYBOARD_IMX=y
CONFIG_MOUSE_PS2=m
CONFIG_MOUSE_PS2_ELANTECH=y
@@ -341,7 +338,6 @@ CONFIG_MXC_IPU=y
CONFIG_MXC_GPU_VIV=y
CONFIG_MXC_IPU_V3_PRE=y
CONFIG_MXC_MIPI_CSI2=y
-CONFIG_MXC_MLB150=m
CONFIG_MXC_SIM=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
diff --git a/arch/arm/mach-imx/busfreq-imx.c b/arch/arm/mach-imx/busfreq-imx.c
index 784c77a8294..079c90b59a9 100644
--- a/arch/arm/mach-imx/busfreq-imx.c
+++ b/arch/arm/mach-imx/busfreq-imx.c
@@ -1303,6 +1303,9 @@ static int busfreq_probe(struct platform_device *pdev)
high_bus_count++;
}
+ if (cpu_is_imx7d() && imx_src_is_m4_enabled())
+ high_bus_count++;
+
if (err) {
dev_err(busfreq_dev, "Busfreq init of ddr controller failed\n");
return err;
diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index a41a00058bf..cb3873fb211 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -101,6 +101,8 @@ bool imx_src_is_m4_enabled(void);
void mcc_receive_from_mu_buffer(unsigned int index, unsigned int *data);
void mcc_send_via_mu_buffer(unsigned int index, unsigned int data);
bool imx_mu_is_m4_in_low_freq(void);
+bool imx_mu_is_m4_in_stop(void);
+int imx_mu_lpm_ready(bool ready);
unsigned int imx_gpcv2_is_mf_mix_off(void);
int imx_gpc_mf_power_on(unsigned int irq, unsigned int on);
#ifdef CONFIG_HAVE_IMX_GPCV2
diff --git a/arch/arm/mach-imx/gpcv2.c b/arch/arm/mach-imx/gpcv2.c
index dbe99b7e0d0..56010dfd17d 100644
--- a/arch/arm/mach-imx/gpcv2.c
+++ b/arch/arm/mach-imx/gpcv2.c
@@ -116,8 +116,9 @@ void imx_gpcv2_set_slot_ack(u32 index, enum imx_gpc_slot m_core,
if (index >= MAX_SLOT_NUMBER)
pr_err("Invalid slot index!\n");
/* set slot */
- writel_relaxed((mode + 1) << (m_core * 2), gpc_base +
- GPC_SLOT0_CFG + index * 4);
+ writel_relaxed(readl_relaxed(gpc_base + GPC_SLOT0_CFG + index * 4)|
+ ((mode + 1) << (m_core * 2)),
+ gpc_base + GPC_SLOT0_CFG + index * 4);
if (ack) {
/* set ack */
@@ -306,16 +307,16 @@ void imx_gpcv2_set_cpu_power_gate_in_idle(bool pdn)
if (pdn) {
imx_gpcv2_set_slot_ack(0, CORE0_A7, false, false);
if (num_online_cpus() > 1)
- imx_gpcv2_set_slot_ack(1, CORE1_A7, false, false);
- imx_gpcv2_set_slot_ack(2, SCU_A7, false, true);
+ imx_gpcv2_set_slot_ack(2, CORE1_A7, false, false);
+ imx_gpcv2_set_slot_ack(3, SCU_A7, false, true);
imx_gpcv2_set_slot_ack(6, SCU_A7, true, false);
imx_gpcv2_set_slot_ack(7, CORE0_A7, true, false);
if (num_online_cpus() > 1)
imx_gpcv2_set_slot_ack(8, CORE1_A7, true, true);
} else {
writel_relaxed(0x0, gpc_base + GPC_SLOT0_CFG + 0 * 0x4);
- writel_relaxed(0x0, gpc_base + GPC_SLOT0_CFG + 1 * 0x4);
writel_relaxed(0x0, gpc_base + GPC_SLOT0_CFG + 2 * 0x4);
+ writel_relaxed(0x0, gpc_base + GPC_SLOT0_CFG + 3 * 0x4);
writel_relaxed(0x0, gpc_base + GPC_SLOT0_CFG + 6 * 0x4);
writel_relaxed(0x0, gpc_base + GPC_SLOT0_CFG + 7 * 0x4);
writel_relaxed(0x0, gpc_base + GPC_SLOT0_CFG + 8 * 0x4);
@@ -352,7 +353,9 @@ static void imx_gpcv2_mf_mix_off(void)
return;
pr_info("Turn off Mega/Fast mix in DSM\n");
- imx_gpcv2_set_mix_phy_gate_by_lpm(1, 5);
+
+ imx_gpcv2_set_slot_ack(1, FAST_MEGA_MIX, false, false);
+ imx_gpcv2_set_slot_ack(5, FAST_MEGA_MIX, true, false);
imx_gpcv2_set_m_core_pgc(true, GPC_PGC_FM);
}
@@ -399,8 +402,9 @@ void imx_gpcv2_pre_suspend(bool arm_power_off)
*/
imx_gpcv2_set_slot_ack(0, CORE0_A7, false, false);
imx_gpcv2_set_slot_ack(2, SCU_A7, false, true);
-
- imx_gpcv2_mf_mix_off();
+ if ((!imx_src_is_m4_enabled()) ||
+ (imx_src_is_m4_enabled() && imx_mu_is_m4_in_stop()))
+ imx_gpcv2_mf_mix_off();
imx_gpcv2_set_slot_ack(6, SCU_A7, true, false);
imx_gpcv2_set_slot_ack(7, CORE0_A7, true, true);
@@ -427,9 +431,10 @@ void imx_gpcv2_post_resume(void)
val = readl_relaxed(gpc_base + GPC_LPCR_A7_BSC);
val |= BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP;
writel_relaxed(val, gpc_base + GPC_LPCR_A7_BSC);
- /* mask m4 dsm trigger */
- writel_relaxed(readl_relaxed(gpc_base + GPC_LPCR_M4) |
- BM_LPCR_M4_MASK_DSM_TRIGGER, gpc_base + GPC_LPCR_M4);
+ /* mask m4 dsm trigger if M4 not enabled*/
+ if (!imx_src_is_m4_enabled())
+ writel_relaxed(readl_relaxed(gpc_base + GPC_LPCR_M4) |
+ BM_LPCR_M4_MASK_DSM_TRIGGER, gpc_base + GPC_LPCR_M4);
/* set mega/fast mix in A7 domain */
writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_MAPPING);
/* set SCU timing */
@@ -437,8 +442,10 @@ void imx_gpcv2_post_resume(void)
gpc_base + GPC_PGC_SCU_TIMING);
val = readl_relaxed(gpc_base + GPC_SLPCR);
- val &= ~(BM_SLPCR_EN_DSM | BM_SLPCR_VSTBY | BM_SLPCR_RBC_EN |
- BM_SLPCR_SBYOS | BM_SLPCR_BYPASS_PMIC_READY);
+ val &= ~(BM_SLPCR_EN_DSM);
+ if (!imx_src_is_m4_enabled())
+ val &= ~(BM_SLPCR_VSTBY | BM_SLPCR_RBC_EN |
+ BM_SLPCR_SBYOS | BM_SLPCR_BYPASS_PMIC_READY);
val |= BM_SLPCR_EN_A7_FASTWUP_WAIT_MODE;
writel_relaxed(val, gpc_base + GPC_SLPCR);
@@ -458,7 +465,11 @@ void imx_gpcv2_post_resume(void)
imx_gpcv2_set_m_core_pgc(false, GPC_PGC_SCU);
imx_gpcv2_set_m_core_pgc(false, GPC_PGC_FM);
for (i = 0; i < MAX_SLOT_NUMBER; i++)
+ {
+ if (i==1||i==4) /* skip slts m4 uses */
+ continue;
writel_relaxed(0x0, gpc_base + GPC_SLOT0_CFG + i * 0x4);
+ }
writel_relaxed(BM_GPC_PGC_ACK_SEL_A7_DUMMY_PUP_ACK |
BM_GPC_PGC_ACK_SEL_A7_DUMMY_PDN_ACK,
gpc_base + GPC_PGC_ACK_SEL_A7);
@@ -647,9 +658,10 @@ void __init imx_gpcv2_init(void)
val = readl_relaxed(gpc_base + GPC_LPCR_A7_BSC);
val |= BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP;
writel_relaxed(val, gpc_base + GPC_LPCR_A7_BSC);
- /* mask m4 dsm trigger */
- writel_relaxed(readl_relaxed(gpc_base + GPC_LPCR_M4) |
- BM_LPCR_M4_MASK_DSM_TRIGGER, gpc_base + GPC_LPCR_M4);
+ /* mask m4 dsm trigger if M4 not enabled*/
+ if (!imx_src_is_m4_enabled())
+ writel_relaxed(readl_relaxed(gpc_base + GPC_LPCR_M4) |
+ BM_LPCR_M4_MASK_DSM_TRIGGER, gpc_base + GPC_LPCR_M4);
/* set mega/fast mix in A7 domain */
writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_MAPPING);
/* set SCU timing */
@@ -660,8 +672,10 @@ void __init imx_gpcv2_init(void)
gpc_base + GPC_PGC_ACK_SEL_A7);
val = readl_relaxed(gpc_base + GPC_SLPCR);
- val &= ~(BM_SLPCR_EN_DSM | BM_SLPCR_VSTBY | BM_SLPCR_RBC_EN |
- BM_SLPCR_SBYOS | BM_SLPCR_BYPASS_PMIC_READY);
+ val &= ~(BM_SLPCR_EN_DSM);
+ if (!imx_src_is_m4_enabled())
+ val &= ~(BM_SLPCR_VSTBY | BM_SLPCR_RBC_EN |
+ BM_SLPCR_SBYOS | BM_SLPCR_BYPASS_PMIC_READY);
val |= BM_SLPCR_EN_A7_FASTWUP_WAIT_MODE;
writel_relaxed(val, gpc_base + GPC_SLPCR);
diff --git a/arch/arm/mach-imx/mu.c b/arch/arm/mach-imx/mu.c
index 56ab9ce18a6..69ae71844e4 100644
--- a/arch/arm/mach-imx/mu.c
+++ b/arch/arm/mach-imx/mu.c
@@ -47,6 +47,11 @@
#define MU_LPM_M4_WAKEUP_ENABLE_MASK 0xF
#define MU_LPM_M4_WAKEUP_ENABLE_SHIFT 0x0
+#define MU_LPM_M4_A7_READY 0xFFFFAAAA
+#define MU_LPM_M4_RUN_MODE 0x5A5A0001
+#define MU_LPM_M4_WAIT_MODE 0x5A5A0002
+#define MU_LPM_M4_STOP_MODE 0x5A5A0003
+
struct imx_mu_rpmsg_box {
const char *name;
struct blocking_notifier_head notifier;
@@ -62,6 +67,7 @@ static u32 m4_message;
static struct delayed_work mu_work, rpmsg_work;
static u32 m4_wake_irqs[4];
static bool m4_freq_low;
+static bool m4_in_stop;
struct imx_sema4_mutex *mcc_shm_ptr;
unsigned int imx_mcc_buffer_freed = 0, imx_mcc_buffer_queued = 0;
@@ -70,6 +76,11 @@ static DECLARE_WAIT_QUEUE_HEAD(buffer_freed_wait_queue);
/* Used for blocking recv */
static DECLARE_WAIT_QUEUE_HEAD(buffer_queued_wait_queue);
+bool imx_mu_is_m4_in_stop(void)
+{
+ return m4_in_stop;
+}
+
bool imx_mu_is_m4_in_low_freq(void)
{
return m4_freq_low;
@@ -163,10 +174,18 @@ static void mu_work_handler(struct work_struct *work)
pr_debug("receive M4 message 0x%x\n", m4_message);
switch (m4_message) {
+ case MU_LPM_M4_RUN_MODE:
+ case MU_LPM_M4_WAIT_MODE:
+ m4_in_stop = false;
+ break;
+ case MU_LPM_M4_STOP_MODE:
+ m4_in_stop = true;
+ break;
case MU_LPM_M4_REQUEST_HIGH_BUS:
request_bus_freq(BUS_FREQ_HIGH);
#ifdef CONFIG_SOC_IMX6SX
- imx6sx_set_m4_highfreq(true);
+ if (cpu_is_imx6sx())
+ imx6sx_set_m4_highfreq(true);
#endif
imx_mu_send_message(MU_LPM_HANDSHAKE_INDEX,
MU_LPM_BUS_HIGH_READY_FOR_M4);
@@ -175,10 +194,12 @@ static void mu_work_handler(struct work_struct *work)
case MU_LPM_M4_RELEASE_HIGH_BUS:
release_bus_freq(BUS_FREQ_HIGH);
#ifdef CONFIG_SOC_IMX6SX
- imx6sx_set_m4_highfreq(false);
+ if (cpu_is_imx6sx()) {
+ imx6sx_set_m4_highfreq(false);
+ imx_mu_send_message(MU_LPM_HANDSHAKE_INDEX,
+ MU_LPM_M4_FREQ_CHANGE_READY);
+ }
#endif
- imx_mu_send_message(MU_LPM_HANDSHAKE_INDEX,
- MU_LPM_M4_FREQ_CHANGE_READY);
m4_freq_low = true;
break;
default:
@@ -219,6 +240,18 @@ int imx_mu_rpmsg_send(unsigned int rpmsg)
return imx_mu_send_message(MU_RPMSG_HANDSHAKE_INDEX, rpmsg);
}
+int imx_mu_lpm_ready(bool ready)
+{
+ u32 val;
+
+ val = readl_relaxed(mu_base + MU_ACR);
+ if (ready)
+ writel_relaxed(val | BIT(0), mu_base + MU_ACR);
+ else
+ writel_relaxed(val & ~BIT(0), mu_base + MU_ACR);
+ return 0;
+}
+
int imx_mu_rpmsg_register_nb(const char *name, struct notifier_block *nb)
{
if ((name == NULL) || (nb == NULL))
@@ -566,6 +599,12 @@ static int imx_mu_probe(struct platform_device *pdev)
/* enable the bit31(GIE3) of MU_ACR, used for MCC */
writel_relaxed(readl_relaxed(mu_base + MU_ACR) | BIT(31),
mu_base + MU_ACR);
+ INIT_DELAYED_WORK(&mu_work, mu_work_handler);
+ INIT_DELAYED_WORK(&rpmsg_work, rpmsg_work_handler);
+ /* enable the bit26(RIE1) of MU_ACR */
+ writel_relaxed(readl_relaxed(mu_base + MU_ACR) |
+ BIT(26) | BIT(27), mu_base + MU_ACR);
+ imx_mu_lpm_ready(true);
} else {
INIT_DELAYED_WORK(&mu_work, mu_work_handler);
diff --git a/arch/arm/mach-imx/pm-imx7.c b/arch/arm/mach-imx/pm-imx7.c
index cd6b9185a8f..00bb02a9f5c 100644
--- a/arch/arm/mach-imx/pm-imx7.c
+++ b/arch/arm/mach-imx/pm-imx7.c
@@ -9,6 +9,7 @@
* http://www.gnu.org/copyleft/gpl.html
*/
+#include <linux/busfreq-imx.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/io.h>
@@ -115,6 +116,11 @@
#define GPIO_IMR 0x14
#define GPIO_EDGE 0x1c
+#define M4RCR 0x0C
+#define M4_SP_OFF 0x00
+#define M4_PC_OFF 0x04
+#define M4_RCR_HALT 0xAB
+#define M4_RCR_GO 0xAA
extern unsigned long iram_tlb_base_addr;
extern unsigned long iram_tlb_phys_addr;
@@ -123,6 +129,11 @@ static void __iomem *ocram_base;
static unsigned int ocram_size;
static unsigned int *lpm_ocram_saved_in_ddr;
static void __iomem *lpm_ocram_base;
+
+static unsigned int *lpm_m4tcm_saved_in_ddr;
+static void __iomem *lpm_m4tcm_base;
+static void __iomem *m4_bootrom_base;
+
static unsigned int lpm_ocram_size;
static void __iomem *ccm_base;
static void __iomem *lpsr_base;
@@ -693,6 +704,10 @@ static int imx7_pm_enter(suspend_state_t state)
imx_anatop_pre_suspend();
imx_gpcv2_pre_suspend(true);
if (imx_gpcv2_is_mf_mix_off()) {
+ /* stop m4 if mix will also be shutdown */
+ if (imx_src_is_m4_enabled() && imx_mu_is_m4_in_stop())
+ writel(M4_RCR_HALT,
+ pm_info->src_base.vbase + M4RCR);
imx7_console_save(console_saved_reg);
memcpy(ocram_saved_in_ddr, ocram_base, ocram_size);
if (lpsr_enabled) {
@@ -726,6 +741,24 @@ static int imx7_pm_enter(suspend_state_t state)
imx7_pm_is_resume_from_lpsr()) {
memcpy(ocram_base, ocram_saved_in_ddr, ocram_size);
imx7_console_restore(console_saved_reg);
+ if (imx_src_is_m4_enabled() && imx_mu_is_m4_in_stop()) {
+ /* restore M4 image */
+ memcpy(lpm_m4tcm_base,
+ lpm_m4tcm_saved_in_ddr, SZ_32K);
+ /* set sp from word in the image */
+ writel(*(lpm_m4tcm_saved_in_ddr),
+ m4_bootrom_base + M4_SP_OFF);
+ /* set PC from next word */
+ writel(*(lpm_m4tcm_saved_in_ddr+1),
+ m4_bootrom_base + M4_PC_OFF);
+ /* kick m4 to enable */
+ writel(M4_RCR_GO,
+ pm_info->src_base.vbase + M4RCR);
+ /* offset high bus count for m4 image */
+ request_bus_freq(BUS_FREQ_HIGH);
+ /* gpc wakeup */
+ imx_mu_lpm_ready(true);
+ }
}
/* clear LPSR resume address */
imx7_pm_set_lpsr_resume_addr(0);
@@ -1016,7 +1049,27 @@ void __init imx7d_pm_init(void)
{
struct device_node *np;
struct resource res;
+ if (imx_src_is_m4_enabled()) {
+ /* map the 32K of M4 TCM */
+ np = of_find_node_by_path(
+ "/tcml@007f8000");
+ if (np)
+ lpm_m4tcm_base = of_iomap(np, 0);
+ WARN_ON(!lpm_m4tcm_base);
+ /* map the m4 bootrom from dtb */
+ np = of_find_node_by_path(
+ "/soc/sram@00180000");
+ if (np)
+ m4_bootrom_base = of_iomap(np, 0);
+ WARN_ON(!m4_bootrom_base);
+
+ lpm_m4tcm_saved_in_ddr = kzalloc(SZ_32K, GFP_KERNEL);
+ WARN_ON(!lpm_m4tcm_saved_in_ddr);
+
+ /* save M4 Image to DDR */
+ memcpy(lpm_m4tcm_saved_in_ddr, lpm_m4tcm_base, SZ_32K);
+ }
np = of_find_compatible_node(NULL, NULL, "fsl,lpm-sram");
if (of_get_property(np, "fsl,enable-lpsr", NULL))
lpsr_enabled = true;
diff --git a/arch/arm/mach-imx/suspend-imx7.S b/arch/arm/mach-imx/suspend-imx7.S
index 34910ad7c24..ea0712349e6 100644
--- a/arch/arm/mach-imx/suspend-imx7.S
+++ b/arch/arm/mach-imx/suspend-imx7.S
@@ -551,6 +551,12 @@ wfi_ddr_retention_out:
restore_ttbr1
standby_out:
+ /* make sure SNVS clk is disabled */
+ ldr r11, [r0, #PM_INFO_MX7_CCM_V_OFFSET]
+ add r11, r11, #0x4000
+ ldr r7, =0x0
+ str r7, [r11, #CCM_SNVS_LPCG]
+
pop {r4-r12}
/* return to suspend finish */
mov pc, lr
@@ -585,6 +591,11 @@ resume:
dsm_ddr_self_refresh_out:
ddrc_exit_self_refresh
dsm_ddr_retention_out:
+ /* make sure SNVS clk is disabled */
+ ldr r11, [r0, #PM_INFO_MX7_CCM_P_OFFSET]
+ add r11, r11, #0x4000
+ ldr r7, =0x0
+ str r7, [r11, #CCM_SNVS_LPCG]
mov pc, lr
ENDPROC(imx7_suspend)
diff --git a/drivers/dma/pxp/pxp_dma_v2.c b/drivers/dma/pxp/pxp_dma_v2.c
index 5225bcf57a8..48d751d342c 100644
--- a/drivers/dma/pxp/pxp_dma_v2.c
+++ b/drivers/dma/pxp/pxp_dma_v2.c
@@ -1319,6 +1319,7 @@ static irqreturn_t pxp_irq(int irq, void *dev_id)
if (list_empty(&head)) {
pxp->pxp_ongoing = 0;
+ pxp->lut_state = 0;
spin_unlock_irqrestore(&pxp->lock, flags);
return IRQ_NONE;
}
@@ -1349,6 +1350,7 @@ static irqreturn_t pxp_irq(int irq, void *dev_id)
complete(&pxp->complete);
pxp->pxp_ongoing = 0;
+ pxp->lut_state = 0;
mod_timer(&pxp->clk_timer, jiffies + msecs_to_jiffies(timeout_in_ms));
spin_unlock_irqrestore(&pxp->lock, flags);
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 47a4bd339f8..79d523587b5 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2155,7 +2155,7 @@ static unsigned int mmc_do_calc_max_discard(struct mmc_card *card,
y = 0;
for (x = 1; x && x <= max_qty && max_qty - x >= qty; x <<= 1) {
timeout = mmc_erase_timeout(card, arg, qty + x);
- if (timeout > host->max_discard_to)
+ if (timeout > host->max_busy_timeout)
break;
if (timeout < last_timeout)
break;
@@ -2187,7 +2187,7 @@ unsigned int mmc_calc_max_discard(struct mmc_card *card)
struct mmc_host *host = card->host;
unsigned int max_discard, max_trim;
- if (!host->max_discard_to)
+ if (!host->max_busy_timeout)
return UINT_MAX;
/*
@@ -2207,7 +2207,7 @@ unsigned int mmc_calc_max_discard(struct mmc_card *card)
max_discard = 0;
}
pr_debug("%s: calculated max. discard sectors %u for timeout %u ms\n",
- mmc_hostname(host), max_discard, host->max_discard_to);
+ mmc_hostname(host), max_discard, host->max_busy_timeout);
return max_discard;
}
EXPORT_SYMBOL(mmc_calc_max_discard);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 0731155465b..abff3c35ce9 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -273,6 +273,97 @@ static void mmc_select_card_type(struct mmc_card *card)
card->ext_csd.card_type = card_type;
}
+static void mmc_manage_enhanced_area(struct mmc_card *card, u8 *ext_csd)
+{
+ u8 hc_erase_grp_sz, hc_wp_grp_sz;
+
+ /*
+ * Disable these attributes by default
+ */
+ card->ext_csd.enhanced_area_offset = -EINVAL;
+ card->ext_csd.enhanced_area_size = -EINVAL;
+
+ /*
+ * Enhanced area feature support -- check whether the eMMC
+ * card has the Enhanced area enabled. If so, export enhanced
+ * area offset and size to user by adding sysfs interface.
+ */
+ if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) &&
+ (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) {
+ if (card->ext_csd.partition_setting_completed) {
+ hc_erase_grp_sz =
+ ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
+ hc_wp_grp_sz =
+ ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
+
+ /*
+ * calculate the enhanced data area offset, in bytes
+ */
+ card->ext_csd.enhanced_area_offset =
+ (ext_csd[139] << 24) + (ext_csd[138] << 16) +
+ (ext_csd[137] << 8) + ext_csd[136];
+ if (mmc_card_blockaddr(card))
+ card->ext_csd.enhanced_area_offset <<= 9;
+ /*
+ * calculate the enhanced data area size, in kilobytes
+ */
+ card->ext_csd.enhanced_area_size =
+ (ext_csd[142] << 16) + (ext_csd[141] << 8) +
+ ext_csd[140];
+ card->ext_csd.enhanced_area_size *=
+ (size_t)(hc_erase_grp_sz * hc_wp_grp_sz);
+ card->ext_csd.enhanced_area_size <<= 9;
+ } else {
+ pr_warn("%s: defines enhanced area without partition setting complete\n",
+ mmc_hostname(card->host));
+ }
+ }
+}
+
+static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd)
+{
+ int idx;
+ u8 hc_erase_grp_sz, hc_wp_grp_sz;
+ unsigned int part_size;
+
+ /*
+ * General purpose partition feature support --
+ * If ext_csd has the size of general purpose partitions,
+ * set size, part_cfg, partition name in mmc_part.
+ */
+ if (ext_csd[EXT_CSD_PARTITION_SUPPORT] &
+ EXT_CSD_PART_SUPPORT_PART_EN) {
+ hc_erase_grp_sz =
+ ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
+ hc_wp_grp_sz =
+ ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
+
+ for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) {
+ if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] &&
+ !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] &&
+ !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2])
+ continue;
+ if (card->ext_csd.partition_setting_completed == 0) {
+ pr_warn("%s: has partition size defined without partition complete\n",
+ mmc_hostname(card->host));
+ break;
+ }
+ part_size =
+ (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]
+ << 16) +
+ (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1]
+ << 8) +
+ ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3];
+ part_size *= (size_t)(hc_erase_grp_sz *
+ hc_wp_grp_sz);
+ mmc_part_add(card, part_size << 19,
+ EXT_CSD_PART_CONFIG_ACC_GP0 + idx,
+ "gp%d", idx, false,
+ MMC_BLK_DATA_AREA_GP);
+ }
+ }
+}
+
/*
* Decode extended CSD.
*/
@@ -280,7 +371,6 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
{
int err = 0, idx;
unsigned int part_size;
- u8 hc_erase_grp_sz = 0, hc_wp_grp_sz = 0;
BUG_ON(!card);
@@ -382,80 +472,16 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
ext_csd[EXT_CSD_TRIM_MULT];
card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT];
if (card->ext_csd.rev >= 4) {
- /*
- * Enhanced area feature support -- check whether the eMMC
- * card has the Enhanced area enabled. If so, export enhanced
- * area offset and size to user by adding sysfs interface.
- */
- if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) &&
- (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) {
- hc_erase_grp_sz =
- ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
- hc_wp_grp_sz =
- ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
+ if (ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED] &
+ EXT_CSD_PART_SETTING_COMPLETED)
+ card->ext_csd.partition_setting_completed = 1;
+ else
+ card->ext_csd.partition_setting_completed = 0;
- card->ext_csd.enhanced_area_en = 1;
- /*
- * calculate the enhanced data area offset, in bytes
- */
- card->ext_csd.enhanced_area_offset =
- (ext_csd[139] << 24) + (ext_csd[138] << 16) +
- (ext_csd[137] << 8) + ext_csd[136];
- if (mmc_card_blockaddr(card))
- card->ext_csd.enhanced_area_offset <<= 9;
- /*
- * calculate the enhanced data area size, in kilobytes
- */
- card->ext_csd.enhanced_area_size =
- (ext_csd[142] << 16) + (ext_csd[141] << 8) +
- ext_csd[140];
- card->ext_csd.enhanced_area_size *=
- (size_t)(hc_erase_grp_sz * hc_wp_grp_sz);
- card->ext_csd.enhanced_area_size <<= 9;
- } else {
- /*
- * If the enhanced area is not enabled, disable these
- * device attributes.
- */
- card->ext_csd.enhanced_area_offset = -EINVAL;
- card->ext_csd.enhanced_area_size = -EINVAL;
- }
+ mmc_manage_enhanced_area(card, ext_csd);
- /*
- * General purpose partition feature support --
- * If ext_csd has the size of general purpose partitions,
- * set size, part_cfg, partition name in mmc_part.
- */
- if (ext_csd[EXT_CSD_PARTITION_SUPPORT] &
- EXT_CSD_PART_SUPPORT_PART_EN) {
- if (card->ext_csd.enhanced_area_en != 1) {
- hc_erase_grp_sz =
- ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
- hc_wp_grp_sz =
- ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
-
- card->ext_csd.enhanced_area_en = 1;
- }
+ mmc_manage_gp_partitions(card, ext_csd);
- for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) {
- if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] &&
- !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] &&
- !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2])
- continue;
- part_size =
- (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]
- << 16) +
- (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1]
- << 8) +
- ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3];
- part_size *= (size_t)(hc_erase_grp_sz *
- hc_wp_grp_sz);
- mmc_part_add(card, part_size << 19,
- EXT_CSD_PART_CONFIG_ACC_GP0 + idx,
- "gp%d", idx, false,
- MMC_BLK_DATA_AREA_GP);
- }
- }
card->ext_csd.sec_trim_mult =
ext_csd[EXT_CSD_SEC_TRIM_MULT];
card->ext_csd.sec_erase_mult =
@@ -1448,7 +1474,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
* If enhanced_area_en is TRUE, host needs to enable ERASE_GRP_DEF
* bit. This bit will be lost every time after a reset or power off.
*/
- if (card->ext_csd.enhanced_area_en ||
+ if (card->ext_csd.partition_setting_completed ||
(card->ext_csd.rev >= 3 && (host->caps2 & MMC_CAP2_HC_ERASE_SZ))) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_ERASE_GROUP_DEF, 1,
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 9a7d42c39dc..23919909c87 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -990,9 +990,22 @@ static int esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
return esdhc_change_pinstate(host, uhs);
}
-static unsigned int esdhc_get_max_timeout_counter(struct sdhci_host *host)
+static unsigned int esdhc_get_max_timeout_count(struct sdhci_host *host)
{
- return 1 << 28;
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
+
+ return esdhc_is_usdhc(imx_data) ? 1 << 28 : 1 << 27;
+}
+
+static void esdhc_set_timeout(struct sdhci_host *host, struct mmc_command *cmd)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
+
+ /* use maximum timeout counter */
+ sdhci_writeb(host, esdhc_is_usdhc(imx_data) ? 0xF : 0xE,
+ SDHCI_TIMEOUT_CONTROL);
}
static struct sdhci_ops sdhci_esdhc_ops = {
@@ -1004,8 +1017,10 @@ static struct sdhci_ops sdhci_esdhc_ops = {
.set_clock = esdhc_pltfm_set_clock,
.get_max_clock = esdhc_pltfm_get_max_clock,
.get_min_clock = esdhc_pltfm_get_min_clock,
+ .get_max_timeout_count = esdhc_get_max_timeout_count,
.get_ro = esdhc_pltfm_get_ro,
.platform_bus_width = esdhc_pltfm_bus_width,
+ .set_timeout = esdhc_set_timeout,
.set_uhs_signaling = esdhc_set_uhs_signaling,
};
@@ -1170,9 +1185,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
writel(readl(host->ioaddr + SDHCI_HOST_CONTROL)
| ESDHC_BURST_LEN_EN_INCR,
host->ioaddr + SDHCI_HOST_CONTROL);
-
- host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
- SDHCI_QUIRK2_NOSTD_TIMEOUT_COUNTER;
+ host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
host->mmc->caps |= MMC_CAP_1_8V_DDR;
/*
@@ -1180,8 +1193,6 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
* TO1.1, it's harmless for MX6SL
*/
writel(readl(host->ioaddr + 0x6c) | BIT(7), host->ioaddr + 0x6c);
- sdhci_esdhc_ops.get_max_timeout_counter =
- esdhc_get_max_timeout_counter;
}
if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 7a879289302..0af163737e4 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -717,19 +717,28 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host)
sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
}
-static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
+static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd)
{
u8 count;
+
+ if (host->ops->set_timeout) {
+ host->ops->set_timeout(host, cmd);
+ } else {
+ count = sdhci_calc_timeout(host, cmd);
+ sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
+ }
+}
+
+static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
+{
u8 ctrl;
struct mmc_data *data = cmd->data;
int ret;
WARN_ON(host->data);
- if (data || (cmd->flags & MMC_RSP_BUSY)) {
- count = sdhci_calc_timeout(host, cmd);
- sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
- }
+ if (data || (cmd->flags & MMC_RSP_BUSY))
+ sdhci_set_timeout(host, cmd);
if (!data)
return;
@@ -1218,7 +1227,6 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
clock_set:
if (real_div)
host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div;
-
clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
<< SDHCI_DIVIDER_HI_SHIFT;
@@ -1453,6 +1461,18 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
sdhci_set_clock(host, ios->clock);
+ if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK &&
+ host->clock) {
+ host->timeout_clk = host->mmc->actual_clock ?
+ host->mmc->actual_clock / 1000 :
+ host->clock / 1000;
+ host->mmc->max_busy_timeout =
+ host->ops->get_max_timeout_count ?
+ host->ops->get_max_timeout_count(host) :
+ 1 << 27;
+ host->mmc->max_busy_timeout /= host->timeout_clk;
+ }
+
if (ios->power_mode == MMC_POWER_OFF)
vdd_bit = sdhci_set_power(host, -1);
else
@@ -3026,36 +3046,26 @@ int sdhci_add_host(struct sdhci_host *host)
} else
mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
- host->timeout_clk =
- (caps[0] & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
- if (host->timeout_clk == 0) {
- if (host->ops->get_timeout_clock) {
- host->timeout_clk = host->ops->get_timeout_clock(host);
- } else if (!(host->quirks &
- SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
- pr_err("%s: Hardware doesn't specify timeout clock "
- "frequency.\n", mmc_hostname(mmc));
- return -ENODEV;
+ if (!(host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
+ host->timeout_clk = (caps[0] & SDHCI_TIMEOUT_CLK_MASK) >>
+ SDHCI_TIMEOUT_CLK_SHIFT;
+ if (host->timeout_clk == 0) {
+ if (host->ops->get_timeout_clock) {
+ host->timeout_clk =
+ host->ops->get_timeout_clock(host);
+ } else {
+ pr_err("%s: Hardware doesn't specify timeout clock frequency.\n",
+ mmc_hostname(mmc));
+ return -ENODEV;
+ }
}
- }
- if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT)
- host->timeout_clk *= 1000;
- if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
- host->timeout_clk = mmc->f_max / 1000;
+ if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT)
+ host->timeout_clk *= 1000;
- if (host->quirks2 & SDHCI_QUIRK2_NOSTD_TIMEOUT_COUNTER) {
- if (host->ops->get_max_timeout_counter) {
- mmc->max_discard_to =
- host->ops->get_max_timeout_counter(host)
- / host->timeout_clk;
- } else {
- pr_err("%s: Hardware doesn't specify max timeout "
- "counter\n", mmc_hostname(mmc));
- return -ENODEV;
- }
- } else {
- mmc->max_discard_to = (1 << 27) / host->timeout_clk;
+ mmc->max_busy_timeout = host->ops->get_max_timeout_count ?
+ host->ops->get_max_timeout_count(host) : 1 << 27;
+ mmc->max_busy_timeout /= host->timeout_clk;
}
mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 4d38c29892b..8c58ba527c7 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -290,7 +290,9 @@ struct sdhci_ops {
unsigned int (*get_max_clock)(struct sdhci_host *host);
unsigned int (*get_min_clock)(struct sdhci_host *host);
unsigned int (*get_timeout_clock)(struct sdhci_host *host);
- unsigned int (*get_max_timeout_counter)(struct sdhci_host *host);
+ unsigned int (*get_max_timeout_count)(struct sdhci_host *host);
+ void (*set_timeout)(struct sdhci_host *host,
+ struct mmc_command *cmd);
int (*platform_bus_width)(struct sdhci_host *host,
int width);
void (*platform_send_init_74_clocks)(struct sdhci_host *host,
diff --git a/drivers/mxc/sim/imx_sim.c b/drivers/mxc/sim/imx_sim.c
index 318f9d753e9..3687242c5ea 100755
--- a/drivers/mxc/sim/imx_sim.c
+++ b/drivers/mxc/sim/imx_sim.c
@@ -926,69 +926,36 @@ static void sim_start(struct sim_t *sim)
__raw_writel(reg_data, sim->ioaddr + sim->port_detect_reg);
};
-static void sim_activate(struct sim_t *sim)
-{
- u32 reg_data;
- pr_debug("%s Activate on the sim port.\n", __func__);
- /* activate on sequence */
- if (sim->present != SIM_PRESENT_REMOVED) {
- /*Disable Reset pin*/
- reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
- reg_data &= ~SIM_PORT_CNTL_SRST;
- /*If sven is low active, we need to set sevn to be high*/
- if (sim->sven_low_active)
- reg_data |= SIM_PORT_CNTL_SVEN;
-
- __raw_writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
-
- /*Enable VCC pin*/
- reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
-
- if (sim->sven_low_active)
- reg_data &= ~SIM_PORT_CNTL_SVEN;
- else
- reg_data |= SIM_PORT_CNTL_SVEN;
-
- __raw_writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
-
- msleep(10);
- /*Enable clock pin*/
- reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
- reg_data |= SIM_PORT_CNTL_SCEN;
- __raw_writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
- msleep(10);
- } else {
- pr_err("No card%s\n", __func__);
- }
-}
-
static void sim_cold_reset_sequency(struct sim_t *sim)
{
u32 reg_data;
sim->state = SIM_STATE_RESET_SEQUENCY;
- reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
- reg_data &= ~SIM_PORT_CNTL_SRST;
- __raw_writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
- reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
+ /*set VCC*/
+ reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
if (sim->sven_low_active)
reg_data &= ~SIM_PORT_CNTL_SVEN;
else
reg_data |= SIM_PORT_CNTL_SVEN;
-
__raw_writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
+
msleep(9);
+ /*enable CLK*/
reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
reg_data |= SIM_PORT_CNTL_SCEN;
__raw_writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
+ /*RST low time*/
sim_reset_low_timing(sim, EMV_RESET_LOW_CYCLES);
+ /*RST high*/
reg_data = __raw_readl(sim->ioaddr + sim->port_ctrl_reg);
reg_data |= SIM_PORT_CNTL_SRST;
__raw_writel(reg_data, sim->ioaddr + sim->port_ctrl_reg);
+
+ /*wait for ATR*/
sim_set_gpc_timer(sim, ATR_MAX_DELAY_CLK);
};
@@ -1406,7 +1373,6 @@ static long sim_ioctl(struct file *file,
sim_reset_module(sim);
sim_data_reset(sim);
sim_start(sim);
- sim_activate(sim);
sim_cold_reset(sim);
break;
diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c
index c7f587c8320..4b628e94234 100644
--- a/drivers/net/wireless/bcmdhd/dhd_sdio.c
+++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c
@@ -24,6 +24,10 @@
* $Id: dhd_sdio.c 506047 2014-10-02 12:43:31Z $
*/
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+
#include <typedefs.h>
#include <osl.h>
#include <bcmsdh.h>
@@ -53,6 +57,7 @@
#include <sbsdpcmdev.h>
#include <bcmsdpcm.h>
#include <bcmsdbus.h>
+#include <bcmsdh_sdmmc.h>
#include <proto/ethernet.h>
#include <proto/802.1d.h>
@@ -1737,6 +1742,9 @@ static int dhdsdio_txpkt_preprocess(dhd_bus_t *bus, void *pkt, int chan, int txs
uint32 swhdr_offset;
bool alloc_new_pkt = FALSE;
uint8 sdpcm_hdrlen = bus->txglom_enable ? SDPCM_HDRLEN_TXGLOM : SDPCM_HDRLEN;
+ sdioh_info_t *sd = bus->sdh->sdioh;
+ struct sdio_func *sdio_func = sd->func[0];
+ struct mmc_host *host = sdio_func->card->host;
*new_pkt = NULL;
osh = bus->dhd->osh;
@@ -1814,7 +1822,7 @@ static int dhdsdio_txpkt_preprocess(dhd_bus_t *bus, void *pkt, int chan, int txs
* Use the padding packet to avoid memory copy if applicable,
* otherwise, just allocate a new pkt.
*/
- if (bus->pad_pkt) {
+ if (bus->pad_pkt && (host->max_segs > 1)) {
*pad_pkt_len = chain_tail_padding;
bus->tx_tailpad_chain++;
} else {
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index 90c653d9c3e..405c184dafa 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -1412,11 +1412,7 @@ static int __init imx6_pcie_probe(struct platform_device *pdev)
* reserved ddr memory after write the ddr_test_region
* content to rc.
*/
- if (is_imx7d_pcie(imx6_pcie))
- pcie_arb_base_addr = ioremap_nocache(pp->mem_base,
- test_region_size);
- else
- pcie_arb_base_addr = ioremap_cache(pp->mem_base,
+ pcie_arb_base_addr = ioremap_nocache(pp->mem_base,
test_region_size);
if (!pcie_arb_base_addr) {
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 67b1526bd71..78b4a8ed1ae 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -246,7 +246,6 @@ struct imx_port {
unsigned int tx_bytes;
unsigned int dma_tx_nents;
struct delayed_work tsk_dma_tx;
- struct work_struct tsk_dma_rx;
wait_queue_head_t dma_wait;
unsigned int saved_reg[10];
#define DMA_TX_IS_WORKING 1
@@ -896,7 +895,6 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
}
#define RX_BUF_SIZE (PAGE_SIZE)
-static int start_rx_dma(struct imx_port *sport);
static void dma_rx_push_data(struct imx_port *sport, struct tty_struct *tty,
unsigned int start, unsigned int end)
@@ -917,9 +915,8 @@ static void dma_rx_push_data(struct imx_port *sport, struct tty_struct *tty,
}
}
-static void dma_rx_work(struct work_struct *w)
+static void dma_rx_work(struct imx_port *sport)
{
- struct imx_port *sport = container_of(w, struct imx_port, tsk_dma_rx);
struct tty_struct *tty = sport->port.state->port.tty;
unsigned int cur_idx = sport->rx_buf.cur_idx;
@@ -970,14 +967,6 @@ static void dma_rx_callback(void *data)
status = dmaengine_tx_status(chan, (dma_cookie_t)0, &state);
count = RX_BUF_SIZE - state.residue;
-
- if (readl(sport->port.membase + USR2) & USR2_IDLE) {
- /* In condition [3] the SDMA counted up too early */
- count--;
-
- writel(USR2_IDLE, sport->port.membase + USR2);
- }
-
sport->rx_buf.buf_info[sport->rx_buf.cur_idx].filled = true;
sport->rx_buf.buf_info[sport->rx_buf.cur_idx].rx_bytes = count;
sport->rx_buf.cur_idx++;
@@ -988,7 +977,7 @@ static void dma_rx_callback(void *data)
dev_err(sport->port.dev, "overwrite!\n");
if (count)
- schedule_work(&sport->tsk_dma_rx);
+ dma_rx_work(sport);
}
static int start_rx_dma(struct imx_port *sport)
@@ -1227,10 +1216,8 @@ static int imx_startup(struct uart_port *port)
&& !sport->dma_is_inited)
imx_uart_dma_init(sport);
- if (sport->dma_is_inited) {
+ if (sport->dma_is_inited)
INIT_DELAYED_WORK(&sport->tsk_dma_tx, dma_tx_work);
- INIT_WORK(&sport->tsk_dma_rx, dma_rx_work);
- }
spin_lock_irqsave(&sport->port.lock, flags);
/*
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index 3fa83dbb862..db3b830df19 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -664,6 +664,15 @@ static int mxsfb_set_par(struct fb_info *fb_info)
if (host->cur_blank != FB_BLANK_UNBLANK)
return 0;
+ line_size = fb_info->var.xres * (fb_info->var.bits_per_pixel >> 3);
+ fb_info->fix.line_length = line_size;
+ fb_size = fb_info->var.yres_virtual * line_size;
+
+ if (fb_size > fb_info->fix.smem_len) {
+ dev_err(&host->pdev->dev, "exceeds the fb buffer size limit!\n");
+ return -ENOMEM;
+ }
+
/*
* It seems, you can't re-program the controller if it is still running.
* This may lead into shifted pictures (FIFO issue?).
@@ -677,19 +686,6 @@ static int mxsfb_set_par(struct fb_info *fb_info)
/* clear the FIFOs */
writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET);
- line_size = fb_info->var.xres * (fb_info->var.bits_per_pixel >> 3);
- fb_info->fix.line_length = line_size;
- fb_size = fb_info->var.yres_virtual * line_size;
-
- /* Reallocate memory */
- if (!fb_info->fix.smem_start || (fb_size > fb_info->fix.smem_len)) {
- if (fb_info->fix.smem_start)
- mxsfb_unmap_videomem(fb_info);
-
- if (mxsfb_map_videomem(fb_info) < 0)
- return -ENOMEM;
- }
-
ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER |
CTRL_SET_BUS_WIDTH(host->ld_intf_width);
@@ -1259,6 +1255,7 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host)
fb_info->fix.line_length =
fb_info->var.xres * (fb_info->var.bits_per_pixel >> 3);
+ fb_info->fix.smem_len = SZ_32M;
/* Memory allocation for framebuffer */
if (mxsfb_map_videomem(fb_info) < 0)
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 84e005e7034..b7a90c4b22c 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -75,7 +75,7 @@ struct mmc_ext_csd {
unsigned int sec_trim_mult; /* Secure trim multiplier */
unsigned int sec_erase_mult; /* Secure erase multiplier */
unsigned int trim_timeout; /* In milliseconds */
- bool enhanced_area_en; /* enable bit */
+ bool partition_setting_completed; /* enable bit */
unsigned long long enhanced_area_offset; /* Units: Byte */
unsigned int enhanced_area_size; /* Units: KB */
unsigned int cache_size; /* Units: KB */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index d35e58b64cb..48953c7868f 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -315,7 +315,7 @@ struct mmc_host {
unsigned int max_req_size; /* maximum number of bytes in one req */
unsigned int max_blk_size; /* maximum size of one mmc block */
unsigned int max_blk_count; /* maximum number of blocks in one req */
- unsigned int max_discard_to; /* max. discard timeout in ms */
+ unsigned int max_busy_timeout; /* max busy timeout in ms */
/* private data */
spinlock_t lock; /* lock for claim and bus ops */
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 05324379821..9776b2aa3af 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -281,6 +281,7 @@ struct _mmc_csd {
#define EXT_CSD_EXP_EVENTS_CTRL 56 /* R/W, 2 bytes */
#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
+#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
#define EXT_CSD_HPI_MGMT 161 /* R/W */
@@ -351,6 +352,7 @@ struct _mmc_csd {
#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3)
#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
+#define EXT_CSD_PART_SETTING_COMPLETED (0x1)
#define EXT_CSD_PART_SUPPORT_PART_EN (0x1)
#define EXT_CSD_CMD_SET_NORMAL (1<<0)
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index 0fdff063287..714ae21c9e9 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -101,7 +101,6 @@ struct sdhci_host {
#define SDHCI_QUIRK2_NO_1_8_V (1<<2)
#define SDHCI_QUIRK2_PRESET_VALUE_BROKEN (1<<3)
#define SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON (1<<4)
-#define SDHCI_QUIRK2_NOSTD_TIMEOUT_COUNTER (1<<5)
/* Controller has a non-standard host control register */
#define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5)
/* Controller does not support HS200 */
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 13412ab158e..5f2ce73096c 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -625,7 +625,8 @@ struct snd_soc_dapm_context {
enum snd_soc_bias_level suspend_bias_level;
struct delayed_work delayed_work;
unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
-
+ /* Go to BIAS_OFF in suspend if the DAPM context is idle */
+ unsigned int suspend_bias_off:1;
void (*seq_notifier)(struct snd_soc_dapm_context *,
enum snd_soc_dapm_type, int);
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 59a47851f5c..91a9efd80b1 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -774,6 +774,7 @@ struct snd_soc_codec_driver {
int (*set_bias_level)(struct snd_soc_codec *,
enum snd_soc_bias_level level);
bool idle_bias_off;
+ bool suspend_bias_off;
void (*seq_notifier)(struct snd_soc_dapm_context *,
enum snd_soc_dapm_type, int);
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 871536109e3..50079fa8b10 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -1122,7 +1122,7 @@ static int wm8960_probe(struct snd_soc_codec *codec)
static struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
.probe = wm8960_probe,
.set_bias_level = wm8960_set_bias_level,
- .idle_bias_off = true,
+ .suspend_bias_off = true,
};
static const struct regmap_config wm8960_regmap = {
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 8f5fe19669d..21667fd69fb 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -1782,8 +1782,11 @@ SND_SOC_BYTES("HD Bass Coefficients", WM8962_HDBASS_AI_1, 30),
SOC_DOUBLE("ALC Switch", WM8962_ALC1, WM8962_ALCL_ENA_SHIFT,
WM8962_ALCR_ENA_SHIFT, 1, 0),
-SND_SOC_BYTES_MASK("ALC Coefficients", WM8962_ALC1, 4,
+SND_SOC_BYTES_MASK("ALC1", WM8962_ALC1, 1,
WM8962_ALCL_ENA_MASK | WM8962_ALCR_ENA_MASK),
+SND_SOC_BYTES("ALC2", WM8962_ALC2, 1),
+SND_SOC_BYTES("ALC3", WM8962_ALC3, 1),
+SND_SOC_BYTES("Noise Gate", WM8962_NOISE_GATE, 1),
};
static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = {
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 56a21e726b6..e00ce586994 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -4375,6 +4375,7 @@ int snd_soc_register_codec(struct device *dev,
codec->dapm.codec = codec;
codec->dapm.seq_notifier = codec_drv->seq_notifier;
codec->dapm.stream_event = codec_drv->stream_event;
+ codec->dapm.suspend_bias_off = codec_drv->suspend_bias_off;
codec->dev = dev;
codec->driver = codec_drv;
codec->num_dai = num_dai;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index f504fae027a..331a4403a64 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1807,6 +1807,22 @@ static void dapm_power_one_widget(struct snd_soc_dapm_widget *w,
}
}
+static bool dapm_idle_bias_off(struct snd_soc_dapm_context *dapm)
+{
+ if (dapm->idle_bias_off)
+ return true;
+
+ switch (snd_power_get_state(dapm->card->snd_card)) {
+ case SNDRV_CTL_POWER_D3hot:
+ case SNDRV_CTL_POWER_D3cold:
+ return dapm->suspend_bias_off;
+ default:
+ break;
+ }
+
+ return false;
+}
+
/*
* Scan each dapm widget for complete audio path.
* A complete path is a route that has valid endpoints i.e.:-
@@ -1828,7 +1844,7 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
trace_snd_soc_dapm_start(card);
list_for_each_entry(d, &card->dapm_list, list) {
- if (d->idle_bias_off)
+ if (dapm_idle_bias_off(d))
d->target_bias_level = SND_SOC_BIAS_OFF;
else
d->target_bias_level = SND_SOC_BIAS_STANDBY;
@@ -1894,7 +1910,7 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
if (d->target_bias_level > bias)
bias = d->target_bias_level;
list_for_each_entry(d, &card->dapm_list, list)
- if (!d->idle_bias_off)
+ if (!dapm_idle_bias_off(d))
d->target_bias_level = bias;
trace_snd_soc_dapm_walk_done(card);