summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml69
-rw-r--r--Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt1
-rw-r--r--arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts31
-rw-r--r--arch/arm/boot/dts/imx6q-apalis-eval.dts136
-rw-r--r--arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts22
-rw-r--r--arch/arm/boot/dts/imx6q-apalis-ixora.dts22
-rw-r--r--arch/arm/boot/dts/imx6qdl-apalis.dtsi52
-rw-r--r--arch/arm/boot/dts/imx6ul.dtsi8
-rw-r--r--arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi7
-rw-r--r--arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi32
-rw-r--r--arch/arm/boot/dts/imx7-colibri.dtsi1
-rw-r--r--arch/arm/boot/dts/imx7s.dtsi8
-rw-r--r--arch/arm/boot/dts/tegra30-colibri-eval-v3.dts5
-rw-r--r--drivers/firmware/psci/psci.c17
-rw-r--r--drivers/gpu/drm/bridge/dumb-vga-dac.c22
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.c15
-rw-r--r--drivers/gpu/drm/imx/parallel-display.c3
-rw-r--r--drivers/gpu/drm/panel/panel-lvds.c46
-rw-r--r--drivers/i2c/busses/i2c-imx.c128
-rw-r--r--drivers/net/phy/micrel.c2
-rw-r--r--drivers/pci/controller/dwc/pci-imx6.c102
-rw-r--r--drivers/spi/spidev.c1
-rw-r--r--drivers/tty/serial/imx.c17
-rw-r--r--mm/cma.c2
-rw-r--r--sound/soc/soc-core.c4
25 files changed, 667 insertions, 86 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 000000000000..c0d0de1dab5b
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,69 @@
+image: $CI_IMAGE
+
+variables:
+# uncomment for the pipeline debug purpose
+# CI_DEBUG_TRACE: "true"
+
+# Please choose possible 32/64 builder image and appropriate compiler
+ CI_IMAGE: gitlab.int.toradex.com:4567/yuiry.erofeev/linux-toradex/ci-kernel-builder:latest
+ #CI_IMAGE: gitlab.int.toradex.com:4567/yuiry.erofeev/linux-toradex/ci-kernel-builder:aarch64
+ #CI_IMAGE: gitlab.int.toradex.com:4567/yuiry.erofeev/linux-toradex/ci-kernel-builder:aarch64-linaro
+ DOCKER_HOST: tcp://docker:2375
+ DOCKER_DRIVER: overlay2
+ DOCKER_TLS_CERTDIR: ""
+
+# Kernel Configuration Section
+# Supplementary Tool Section
+ # Artifacts configuring section
+ KERNEL_CONFIG_BUILD_LOG_FILE_NAME: build_config.log
+ KERNEL_BUILD_LOG_FILE_NAME: build.log
+ KERNEL_CONFIGURATION_FILE: .config
+# Defining temporary build folder to do outside of the box builds. Absolute path
+ TEMP_BUILD_FOLDER: /builds/temp-builds
+
+stages:
+ - build-product
+
+.build_base:
+ stage: build-product
+ variables:
+ GIT_STRATEGY: fetch
+# To run just on merge request
+# only:
+# - merge_requests
+# when: manual
+ script: |
+ #set -o xtrace
+ cd $CI_PROJECT_DIR
+ echo -e "Compiler used to build binaries is"
+ which ${CROSS_COMPILE}gcc
+ ${CROSS_COMPILE}gcc --version
+ echo -e "Arch is \e[36m$ARCH\e[39m"
+ # due to specific of the kernel build we need to use the latest configuration from the nightly builds. We are getting $Version dynamically , as a variable , based on parsing URL page with Nightly builds ID
+ rm -f index.html
+ wget http://10.1.8.33:83/image-oe-torizon-master-matrix/Nightly/artifacts/
+ version=$( cat index.html| grep ^"<a" | sed -e 's/[<>="//]/ /g' | awk '{ print $3}' | sort -nrk1,1 | head -1)
+ wget http://10.1.8.33:83/image-oe-torizon-master-matrix/Nightly/artifacts/$version/$KERNEL_FILE_PATH/images/kernel-config
+ mkdir -p $TEMP_BUILD_FOLDER
+ cp kernel-config $TEMP_BUILD_FOLDER/$KERNEL_CONFIGURATION_FILE
+ #####
+ make O=$TEMP_BUILD_FOLDER -j3 2>&1 | tee $KERNEL_BUILD_LOG_FILE_NAME
+ artifacts:
+ when: always
+ name: "$CI_COMMIT_REF_NAME"
+ paths:
+ - $KERNEL_BUILD_LOG_FILE_NAME
+ #As we do not generate config for 5.x and use generated one, we have just kernel config and kernel build log
+ - kernel-config
+ allow_failure: true
+ after_script:
+ - set -o xtrace
+ - rm -rf $TEMP_BUILD_FOLDER
+
+ # If you need additional products build just copy-paste build_******_product section with new config name
+build_default_defconfig :
+ extends: .build_base
+ variables:
+ # Defining the path, which we will use to take a config file to build a kernel
+ KERNEL_FILE_PATH: colibri-imx7_torizon-core-docker
+ stage: build-product \ No newline at end of file
diff --git a/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt b/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
index 164cbb15f04c..adbd2ca0af2f 100644
--- a/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
+++ b/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
@@ -18,6 +18,7 @@ graph bindings specified in Documentation/devicetree/bindings/graph.txt.
Optional properties:
- vdd-supply: Power supply for DAC
+- de-active: data-enable pulse is active low/high/ignored
Example
-------
diff --git a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
index 9a5d6c94cca4..e59b5cbfdc52 100644
--- a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
@@ -99,7 +99,6 @@
compatible = "fsl,imx-parallel-display";
#address-cells = <1>;
#size-cells = <0>;
- interface-pix-fmt = "bgr666";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ipu1_lcdif>;
status = "okay";
@@ -121,13 +120,25 @@
};
};
- panel: panel {
- /*
- * edt,et057090dhu: EDT 5.7" LCD TFT
- * edt,et070080dh6: EDT 7.0" LCD TFT
- */
- compatible = "edt,et057090dhu";
+ panel_dpi: panel-dpi {
+ compatible = "panel-dpi";
backlight = <&backlight>;
+ width-mm = <115>;
+ height-mm = <86>;
+
+ data-mapping = "bgr666";
+
+ panel-timing {
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ vactive = <480>;
+ hsync-len = <30>;
+ hfront-porch = <16>;
+ hback-porch = <114>;
+ vsync-len = <3>;
+ vfront-porch = <10>;
+ vback-porch = <32>;
+ };
port {
lcd_panel_in: endpoint {
@@ -154,6 +165,12 @@
interrupt-parent = <&gpio3>;
interrupts = <27 0x2>;
spi-max-frequency = <10000000>;
+ status = "disabled";
+ };
+ spidev0: spidev@1 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <23000000>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/imx6q-apalis-eval.dts b/arch/arm/boot/dts/imx6q-apalis-eval.dts
index 0edd3043d9c1..6174f9f36d20 100644
--- a/arch/arm/boot/dts/imx6q-apalis-eval.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-eval.dts
@@ -84,10 +84,9 @@
compatible = "fsl,imx-parallel-display";
#address-cells = <1>;
#size-cells = <0>;
- interface-pix-fmt = "rgb24";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ipu1_lcdif>;
- status = "okay";
+ status = "disabled";
port@0 {
reg = <0>;
@@ -106,14 +105,28 @@
};
};
- panel: panel {
- /*
- * edt,et057090dhu: EDT 5.7" LCD TFT
- * edt,et070080dh6: EDT 7.0" LCD TFT
- */
- compatible = "edt,et057090dhu";
+ panel_dpi: panel-dpi {
+ compatible = "panel-dpi";
+
backlight = <&backlight>;
- power-supply = <&reg_3v3_sw>;
+
+ width-mm = <115>;
+ height-mm = <86>;
+
+ data-mapping = "rgb24";
+ status = "disabled";
+
+ panel-timing {
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ vactive = <480>;
+ hsync-len = <30>;
+ hfront-porch = <16>;
+ hback-porch = <114>;
+ vsync-len = <3>;
+ vfront-porch = <10>;
+ vback-porch = <32>;
+ };
port {
lcd_panel_in: endpoint {
@@ -122,6 +135,39 @@
};
};
+ panel_lvds: panel-lvds {
+ compatible = "panel-lvds";
+
+ backlight = <&backlight>;
+
+ width-mm = <218>;
+ height-mm = <137>;
+
+ data-mapping = "vesa-24";
+ status = "disabled";
+
+ panel-timing {
+ clock-frequency = <68930000>;
+ hactive = <1280>;
+ vactive = <800>;
+ hback-porch = <64>;
+ hfront-porch = <64>;
+ vback-porch = <5>;
+ vfront-porch = <5>;
+ hsync-len = <40>;
+ vsync-len = <6>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pixelclk-active = <0>;
+ };
+
+ port {
+ lvds_panel_in: endpoint {
+ remote-endpoint = <&lvds_out>;
+ };
+ };
+ };
+
reg_pcie_switch: regulator-pcie-switch {
compatible = "regulator-fixed";
regulator-name = "pcie_switch";
@@ -140,6 +186,16 @@
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
+
+ vga {
+ compatible = "vga-connector";
+
+ port {
+ vga_con_in: endpoint {
+ remote-endpoint = <&vga_bridge_out>;
+ };
+ };
+ };
};
&backlight {
@@ -159,6 +215,35 @@
status = "okay";
};
+/* Apalis SPI1 */
+&ecspi1 {
+ status = "okay";
+
+ spidev0: spidev@1 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <18000000>;
+ };
+};
+
+/* Apalis SPI2 */
+&ecspi2 {
+ status = "okay";
+
+ spidev1: spidev@2 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <18000000>;
+ };
+};
+
+&clks {
+ assigned-clocks = <&clks IMX6QDL_CLK_IPU1_DI1_PRE_SEL>,
+ <&clks IMX6QDL_CLK_IPU2_DI0_PRE_SEL>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_PLL2_PFD2_396M>,
+ <&clks IMX6QDL_CLK_PLL2_PFD2_396M>;
+};
+
&hdmi {
status = "okay";
};
@@ -192,7 +277,20 @@
};
&ldb {
- status = "okay";
+ status = "disabled";
+
+ lvds-channel@0 {
+ status = "okay";
+ primary;
+
+ port@4 {
+ reg = <4>;
+
+ lvds_out: endpoint {
+ remote-endpoint = <&lvds_panel_in>;
+ };
+ };
+ };
};
&pcie {
@@ -283,6 +381,24 @@
status = "okay";
};
+&vgabridge {
+ status = "okay";
+
+ ports {
+ port@1 {
+ reg = <1>;
+
+ vga_bridge_out: endpoint {
+ remote-endpoint = <&vga_con_in>;
+ };
+ };
+ };
+};
+
+&vgadisplay {
+ status = "okay";
+};
+
&iomuxc {
/*
* Mux the Apalis GPIOs
diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts
index b94bb687be6b..dc75a88b37a0 100644
--- a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts
@@ -164,6 +164,28 @@
status = "okay";
};
+/* Apalis SPI1 */
+&ecspi1 {
+ status = "okay";
+
+ spidev0: spidev@1 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <18000000>;
+ };
+};
+
+/* Apalis SPI2 */
+&ecspi2 {
+ status = "okay";
+
+ spidev1: spidev@2 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <18000000>;
+ };
+};
+
&hdmi {
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
index 302fd6adc8a7..db29c25abafc 100644
--- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
@@ -163,6 +163,28 @@
status = "okay";
};
+/* Apalis SPI1 */
+&ecspi1 {
+ status = "okay";
+
+ spidev0: spidev@1 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <18000000>;
+ };
+};
+
+/* Apalis SPI2 */
+&ecspi2 {
+ status = "okay";
+
+ spidev1: spidev@2 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <18000000>;
+ };
+};
+
&hdmi {
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
index 7c4ad541c3f5..4b6b8b60ea19 100644
--- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi
@@ -139,6 +139,54 @@
spdif-out;
status = "disabled";
};
+
+ vgabridge: bridge {
+ compatible = "dumb-vga-dac";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ de-active = <0>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ vga_bridge_in: endpoint {
+ remote-endpoint = <&vga_display_out>;
+ };
+ };
+ };
+ };
+
+ vgadisplay: display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interface-pix-fmt = "rgb565";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu2_vdac>;
+ status = "disabled";
+
+ port@0 {
+ reg = <0>;
+
+ vga_display_in: endpoint {
+ remote-endpoint = <&ipu2_di0_disp0>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ vga_display_out: endpoint {
+ remote-endpoint = <&vga_bridge_in>;
+ };
+ };
+ };
+
};
&audmux {
@@ -380,6 +428,10 @@
status = "disabled";
};
+&ipu2_di0_disp0 {
+ remote-endpoint = <&vga_display_in>;
+};
+
&pwm1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1>;
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 81d4b4925127..33d3468c0222 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -227,6 +227,8 @@
clocks = <&clks IMX6UL_CLK_ECSPI1>,
<&clks IMX6UL_CLK_ECSPI1>;
clock-names = "ipg", "per";
+ dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -239,6 +241,8 @@
clocks = <&clks IMX6UL_CLK_ECSPI2>,
<&clks IMX6UL_CLK_ECSPI2>;
clock-names = "ipg", "per";
+ dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -251,6 +255,8 @@
clocks = <&clks IMX6UL_CLK_ECSPI3>,
<&clks IMX6UL_CLK_ECSPI3>;
clock-names = "ipg", "per";
+ dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -263,6 +269,8 @@
clocks = <&clks IMX6UL_CLK_ECSPI4>,
<&clks IMX6UL_CLK_ECSPI4>;
clock-names = "ipg", "per";
+ dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
index b6147c76d159..aeb5d3011d4f 100644
--- a/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/imx6ull-colibri-eval-v3.dtsi
@@ -79,6 +79,13 @@
spi-max-frequency = <10000000>;
vdd-supply = <&reg_3v3>;
xceiver-supply = <&reg_5v0>;
+ status = "disabled";
+ };
+
+ spidev0: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <23000000>;
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
index 3f2746169181..57eab2866ac8 100644
--- a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
@@ -52,13 +52,30 @@
clock-frequency = <16000000>;
};
- panel: panel {
- compatible = "edt,et057090dhu";
+ panel_dpi: panel-dpi {
+ compatible = "panel-dpi";
backlight = <&bl>;
power-supply = <&reg_3v3>;
+ width-mm = <115>;
+ height-mm = <86>;
+
+ data-mapping = "bgr666";
+
+ panel-timing {
+ clock-frequency = <25175000>;
+ hactive = <640>;
+ vactive = <480>;
+ hsync-len = <30>;
+ hfront-porch = <16>;
+ hback-porch = <114>;
+ vsync-len = <3>;
+ vfront-porch = <10>;
+ vback-porch = <32>;
+ };
+
port {
- panel_in: endpoint {
+ lcd_panel_in: endpoint {
remote-endpoint = <&lcdif_out>;
};
};
@@ -120,6 +137,13 @@
spi-max-frequency = <10000000>;
vdd-supply = <&reg_3v3>;
xceiver-supply = <&reg_5v0>;
+ status = "disabled";
+ };
+
+ spidev0: spidev@0 {
+ compatible = "toradex,evalspi";
+ reg = <0>;
+ spi-max-frequency = <23000000>;
status = "okay";
};
};
@@ -143,7 +167,7 @@
port {
lcdif_out: endpoint {
- remote-endpoint = <&panel_in>;
+ remote-endpoint = <&lcd_panel_in>;
};
};
};
diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index c1ed83131b49..37aeba999be3 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -319,7 +319,6 @@
assigned-clock-rates = <400000000>;
bus-width = <8>;
fsl,tuning-step = <2>;
- max-frequency = <100000000>;
vmmc-supply = <&reg_module_3v3>;
vqmmc-supply = <&reg_DCDC3>;
non-removable;
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 6323a9462afa..6a093a1e7567 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -698,6 +698,8 @@
clocks = <&clks IMX7D_ECSPI4_ROOT_CLK>,
<&clks IMX7D_ECSPI4_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 6 7 1>, <&sdma 7 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -825,6 +827,8 @@
clocks = <&clks IMX7D_ECSPI1_ROOT_CLK>,
<&clks IMX7D_ECSPI1_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 0 7 1>, <&sdma 1 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -837,6 +841,8 @@
clocks = <&clks IMX7D_ECSPI2_ROOT_CLK>,
<&clks IMX7D_ECSPI2_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 2 7 1>, <&sdma 3 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
@@ -849,6 +855,8 @@
clocks = <&clks IMX7D_ECSPI3_ROOT_CLK>,
<&clks IMX7D_ECSPI3_ROOT_CLK>;
clock-names = "ipg", "per";
+ dmas = <&sdma 4 7 1>, <&sdma 5 7 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
index 5965150ecdd2..bfc6faaff99a 100644
--- a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
@@ -95,6 +95,11 @@
vdd-supply = <&reg_3v3>;
xceiver-supply = <&reg_5v0>;
};
+ spidev0: spi@1 {
+ compatible = "spidev";
+ reg = <1>;
+ spi-max-frequency = <25000000>;
+ };
};
/* SD/MMC */
diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
index f82ccd39a913..a7e2deab930a 100644
--- a/drivers/firmware/psci/psci.c
+++ b/drivers/firmware/psci/psci.c
@@ -82,6 +82,7 @@ static u32 psci_function_id[PSCI_FN_MAX];
static u32 psci_cpu_suspend_feature;
static bool psci_system_reset2_supported;
+static struct notifier_block psci_restart_handler;
static inline bool psci_has_ext_power_state(void)
{
@@ -250,7 +251,8 @@ static int get_set_conduit_method(struct device_node *np)
return 0;
}
-static void psci_sys_reset(enum reboot_mode reboot_mode, const char *cmd)
+static int psci_sys_reset(struct notifier_block *this,
+ unsigned long reboot_mode, void *cmd)
{
if ((reboot_mode == REBOOT_WARM || reboot_mode == REBOOT_SOFT) &&
psci_system_reset2_supported) {
@@ -263,6 +265,8 @@ static void psci_sys_reset(enum reboot_mode reboot_mode, const char *cmd)
} else {
invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
}
+
+ return NOTIFY_DONE;
}
static void psci_sys_poweroff(void)
@@ -562,6 +566,8 @@ static void __init psci_init_smccc(void)
static void __init psci_0_2_set_functions(void)
{
+ int ret;
+
pr_info("Using standard PSCI v0.2 function IDs\n");
psci_ops.get_version = psci_get_version;
@@ -582,7 +588,14 @@ static void __init psci_0_2_set_functions(void)
psci_ops.migrate_info_type = psci_migrate_info_type;
- arm_pm_restart = psci_sys_reset;
+ psci_restart_handler.notifier_call = psci_sys_reset;
+ psci_restart_handler.priority = 160;
+
+ ret = register_restart_handler(&psci_restart_handler);
+ if (ret) {
+ pr_err("Cannot register restart handler, %d\n", ret);
+ return;
+ }
pm_power_off = psci_sys_poweroff;
}
diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c b/drivers/gpu/drm/bridge/dumb-vga-dac.c
index d32885b906ae..751c4000870e 100644
--- a/drivers/gpu/drm/bridge/dumb-vga-dac.c
+++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c
@@ -175,6 +175,7 @@ static struct i2c_adapter *dumb_vga_retrieve_ddc(struct device *dev)
static int dumb_vga_probe(struct platform_device *pdev)
{
struct dumb_vga *vga;
+ u32 de;
vga = devm_kzalloc(&pdev->dev, sizeof(*vga), GFP_KERNEL);
if (!vga)
@@ -190,6 +191,23 @@ static int dumb_vga_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "No vdd regulator found: %d\n", ret);
}
+ vga->bridge.funcs = &dumb_vga_bridge_funcs;
+ vga->bridge.of_node = pdev->dev.of_node;
+ vga->bridge.timings = of_device_get_match_data(&pdev->dev);
+
+ if (!vga->bridge.timings &&
+ !of_property_read_u32(pdev->dev.of_node, "de-active", &de)) {
+ struct drm_bridge_timings *timings;
+
+ timings = devm_kzalloc(&pdev->dev, sizeof(*timings), GFP_KERNEL);
+ if (!timings)
+ return -ENOMEM;
+
+ timings->input_bus_flags = de ? DRM_BUS_FLAG_DE_HIGH :
+ DRM_BUS_FLAG_DE_LOW;
+ vga->bridge.timings = timings;
+ }
+
vga->ddc = dumb_vga_retrieve_ddc(&pdev->dev);
if (IS_ERR(vga->ddc)) {
if (PTR_ERR(vga->ddc) == -ENODEV) {
@@ -201,10 +219,6 @@ static int dumb_vga_probe(struct platform_device *pdev)
}
}
- vga->bridge.funcs = &dumb_vga_bridge_funcs;
- vga->bridge.of_node = pdev->dev.of_node;
- vga->bridge.timings = of_device_get_match_data(&pdev->dev);
-
drm_bridge_add(&vga->bridge);
return 0;
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index 5418a1a87b2c..8453fc05dcf2 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -4,7 +4,9 @@
*/
#include <linux/clk.h>
+#include <linux/cma.h>
#include <linux/component.h>
+#include <linux/dma-contiguous.h>
#include <linux/dma-fence.h>
#include <linux/moduleparam.h>
#include <linux/of_device.h>
@@ -724,11 +726,18 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
*/
if (!(gpu->identity.features & chipFeatures_PIPE_3D) ||
(gpu->identity.minor_features0 & chipMinorFeatures0_MC20)) {
- u32 dma_mask = (u32)dma_get_required_mask(gpu->dev);
- if (dma_mask < PHYS_OFFSET + SZ_2G)
+ struct cma *cma = dev_get_cma_area(gpu->dev);
+ phys_addr_t end_mask;
+
+ if (cma)
+ end_mask = cma_get_base(cma) - 1 + cma_get_size(cma);
+ else
+ end_mask = dma_get_required_mask(gpu->dev);
+
+ if (end_mask < PHYS_OFFSET + SZ_2G)
gpu->memory_base = PHYS_OFFSET;
else
- gpu->memory_base = dma_mask - SZ_2G + 1;
+ gpu->memory_base = end_mask - SZ_2G + 1;
} else if (PHYS_OFFSET >= SZ_2G) {
dev_info(gpu->dev, "Need to move linear window on MC1.0, disabling TS\n");
gpu->memory_base = PHYS_OFFSET;
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index 1a76de1e8e7b..5e8ea973bc71 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -231,6 +231,9 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
if (ret && ret != -ENODEV)
return ret;
+ if (imxpd->bridge && imxpd->bridge->timings)
+ imxpd->bus_flags = imxpd->bridge->timings->input_bus_flags;
+
imxpd->dev = dev;
ret = imx_pd_register(drm, imxpd);
diff --git a/drivers/gpu/drm/panel/panel-lvds.c b/drivers/gpu/drm/panel/panel-lvds.c
index 1ec57d0806a8..200c6169daa5 100644
--- a/drivers/gpu/drm/panel/panel-lvds.c
+++ b/drivers/gpu/drm/panel/panel-lvds.c
@@ -23,6 +23,11 @@
#include <drm/drm_crtc.h>
#include <drm/drm_panel.h>
+enum panel_type {
+ PANEL_LVDS,
+ PANEL_DPI
+};
+
struct panel_lvds {
struct drm_panel panel;
struct device *dev;
@@ -124,7 +129,9 @@ static int panel_lvds_get_modes(struct drm_panel *panel)
connector->display_info.height_mm = lvds->height;
drm_display_info_set_bus_formats(&connector->display_info,
&lvds->bus_format, 1);
- connector->display_info.bus_flags = lvds->data_mirror
+ drm_bus_flags_from_videomode(&lvds->video_mode,
+ &connector->display_info.bus_flags);
+ connector->display_info.bus_flags |= lvds->data_mirror
? DRM_BUS_FLAG_DATA_LSB_TO_MSB
: DRM_BUS_FLAG_DATA_MSB_TO_LSB;
@@ -145,6 +152,7 @@ static int panel_lvds_parse_dt(struct panel_lvds *lvds)
struct display_timing timing;
const char *mapping;
int ret;
+ enum panel_type type;
ret = of_get_display_timing(np, "panel-timing", &timing);
if (ret < 0)
@@ -174,13 +182,30 @@ static int panel_lvds_parse_dt(struct panel_lvds *lvds)
return -ENODEV;
}
- if (!strcmp(mapping, "jeida-18")) {
- lvds->bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG;
- } else if (!strcmp(mapping, "jeida-24")) {
- lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA;
- } else if (!strcmp(mapping, "vesa-24")) {
- lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG;
- } else {
+ type = (enum panel_type)of_device_get_match_data(lvds->dev);
+ switch (type) {
+ case PANEL_LVDS:
+ if (!strcmp(mapping, "jeida-18")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG;
+ } else if (!strcmp(mapping, "jeida-24")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA;
+ } else if (!strcmp(mapping, "vesa-24")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG;
+ }
+ break;
+ case PANEL_DPI:
+ if (!strcmp(mapping, "rgb24")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ } else if (!strcmp(mapping, "rgb565")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB565_1X16;
+ } else if (!strcmp(mapping, "bgr666")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB666_1X18;
+ } else if (!strcmp(mapping, "lvds666")) {
+ lvds->bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI;
+ }
+ };
+
+ if (!lvds->bus_format) {
dev_err(lvds->dev, "%pOF: invalid or missing %s DT property\n",
np, "data-mapping");
return -EINVAL;
@@ -288,7 +313,8 @@ static int panel_lvds_remove(struct platform_device *pdev)
}
static const struct of_device_id panel_lvds_of_table[] = {
- { .compatible = "panel-lvds", },
+ { .compatible = "panel-lvds", .data = (void *)PANEL_LVDS },
+ { .compatible = "panel-dpi", .data = (void *)PANEL_DPI },
{ /* Sentinel */ },
};
@@ -298,7 +324,7 @@ static struct platform_driver panel_lvds_driver = {
.probe = panel_lvds_probe,
.remove = panel_lvds_remove,
.driver = {
- .name = "panel-lvds",
+ .name = "panel-generic",
.of_match_table = panel_lvds_of_table,
},
};
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 15f6cde6452f..0f8f8b1267b0 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -407,7 +407,7 @@ static void i2c_imx_dma_free(struct imx_i2c_struct *i2c_imx)
dma->chan_using = NULL;
}
-static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
+static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy, bool atomic)
{
unsigned long orig_jiffies = jiffies;
unsigned int temp;
@@ -437,15 +437,39 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
"<%s> I2C bus is busy\n", __func__);
return -ETIMEDOUT;
}
- schedule();
+ if (!atomic)
+ schedule();
+ else
+ udelay(100);
}
return 0;
}
-static int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx)
+static int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx, bool atomic)
{
- wait_event_timeout(i2c_imx->queue, i2c_imx->i2csr & I2SR_IIF, HZ / 10);
+ if (!atomic) {
+ wait_event_timeout(i2c_imx->queue, i2c_imx->i2csr & I2SR_IIF, HZ / 10);
+ } else {
+ int counter = 0;
+
+ while (1) {
+ unsigned int reg;
+
+ reg = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
+ i2c_imx->i2csr = reg;
+ if (reg & I2SR_IIF)
+ break;
+
+ if (counter > 1000) {
+ dev_err(&i2c_imx->adapter.dev, "<%s> TXR timeout\n", __func__);
+ return -EIO;
+ }
+ udelay(100);
+ counter++;
+ }
+ imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2SR);
+ }
if (unlikely(!(i2c_imx->i2csr & I2SR_IIF))) {
dev_dbg(&i2c_imx->adapter.dev, "<%s> Timeout\n", __func__);
@@ -523,7 +547,7 @@ static int i2c_imx_clk_notifier_call(struct notifier_block *nb,
return NOTIFY_OK;
}
-static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
+static int i2c_imx_start(struct imx_i2c_struct *i2c_imx, bool atomic)
{
unsigned int temp = 0;
int result;
@@ -536,23 +560,32 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode, i2c_imx, IMX_I2C_I2CR);
/* Wait controller to be stable */
- usleep_range(50, 150);
+ if (!atomic)
+ usleep_range(50, 150);
+ else
+ udelay(50);
/* Start I2C transaction */
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
temp |= I2CR_MSTA;
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
- result = i2c_imx_bus_busy(i2c_imx, 1);
+ result = i2c_imx_bus_busy(i2c_imx, 1, atomic);
if (result)
return result;
- temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK;
+ if (!atomic) {
+ temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK;
+ } else {
+ temp |= I2CR_MTX | I2CR_TXAK;
+ temp &= ~I2CR_IIEN; /* Disable interrupt */
+ }
+
temp &= ~I2CR_DMAEN;
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
return result;
}
-static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
+static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx, bool atomic)
{
unsigned int temp = 0;
@@ -574,7 +607,7 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
}
if (!i2c_imx->stopped)
- i2c_imx_bus_busy(i2c_imx, 0);
+ i2c_imx_bus_busy(i2c_imx, 0, atomic);
/* Disable I2C controller */
temp = i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN,
@@ -655,7 +688,7 @@ static int i2c_imx_dma_write(struct imx_i2c_struct *i2c_imx,
/* The last data byte must be transferred by the CPU. */
imx_i2c_write_reg(msgs->buf[msgs->len-1],
i2c_imx, IMX_I2C_I2DR);
- result = i2c_imx_trx_complete(i2c_imx);
+ result = i2c_imx_trx_complete(i2c_imx, false);
if (result)
return result;
@@ -714,7 +747,7 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx,
msgs->buf[msgs->len-2] = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
/* read n byte data */
- result = i2c_imx_trx_complete(i2c_imx);
+ result = i2c_imx_trx_complete(i2c_imx, false);
if (result)
return result;
@@ -727,7 +760,7 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx,
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
temp &= ~(I2CR_MSTA | I2CR_MTX);
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
- i2c_imx_bus_busy(i2c_imx, 0);
+ i2c_imx_bus_busy(i2c_imx, 0, false);
} else {
/*
* For i2c master receiver repeat restart operation like:
@@ -745,7 +778,7 @@ static int i2c_imx_dma_read(struct imx_i2c_struct *i2c_imx,
return 0;
}
-static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
+static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bool atomic)
{
int i, result;
@@ -754,7 +787,7 @@ static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
/* write slave address */
imx_i2c_write_reg(i2c_8bit_addr_from_msg(msgs), i2c_imx, IMX_I2C_I2DR);
- result = i2c_imx_trx_complete(i2c_imx);
+ result = i2c_imx_trx_complete(i2c_imx, atomic);
if (result)
return result;
result = i2c_imx_acked(i2c_imx);
@@ -768,7 +801,7 @@ static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
"<%s> write byte: B%d=0x%X\n",
__func__, i, msgs->buf[i]);
imx_i2c_write_reg(msgs->buf[i], i2c_imx, IMX_I2C_I2DR);
- result = i2c_imx_trx_complete(i2c_imx);
+ result = i2c_imx_trx_complete(i2c_imx, atomic);
if (result)
return result;
result = i2c_imx_acked(i2c_imx);
@@ -778,7 +811,7 @@ static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
return 0;
}
-static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bool is_lastmsg)
+static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bool is_lastmsg, bool atomic)
{
int i, result;
unsigned int temp;
@@ -791,7 +824,7 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo
/* write slave address */
imx_i2c_write_reg(i2c_8bit_addr_from_msg(msgs), i2c_imx, IMX_I2C_I2DR);
- result = i2c_imx_trx_complete(i2c_imx);
+ result = i2c_imx_trx_complete(i2c_imx, atomic);
if (result)
return result;
result = i2c_imx_acked(i2c_imx);
@@ -824,7 +857,7 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo
for (i = 0; i < msgs->len; i++) {
u8 len = 0;
- result = i2c_imx_trx_complete(i2c_imx);
+ result = i2c_imx_trx_complete(i2c_imx, atomic);
if (result)
return result;
/*
@@ -852,7 +885,7 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
temp &= ~(I2CR_MSTA | I2CR_MTX);
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
- i2c_imx_bus_busy(i2c_imx, 0);
+ i2c_imx_bus_busy(i2c_imx, 0, atomic);
} else {
/*
* For i2c master receiver repeat restart operation like:
@@ -883,8 +916,8 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, bo
return 0;
}
-static int i2c_imx_xfer(struct i2c_adapter *adapter,
- struct i2c_msg *msgs, int num)
+static int i2c_imx_xfer_common(struct i2c_adapter *adapter,
+ struct i2c_msg *msgs, int num, bool atomic)
{
unsigned int i, temp;
int result;
@@ -898,11 +931,11 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
goto out;
/* Start I2C transfer */
- result = i2c_imx_start(i2c_imx);
+ result = i2c_imx_start(i2c_imx, atomic);
if (result) {
if (i2c_imx->adapter.bus_recovery_info) {
i2c_recover_bus(&i2c_imx->adapter);
- result = i2c_imx_start(i2c_imx);
+ result = i2c_imx_start(i2c_imx, atomic);
}
}
@@ -920,7 +953,7 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
temp |= I2CR_RSTA;
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
- result = i2c_imx_bus_busy(i2c_imx, 1);
+ result = i2c_imx_bus_busy(i2c_imx, 1, atomic);
if (result)
goto fail0;
}
@@ -944,13 +977,17 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
(temp & I2SR_SRW ? 1 : 0), (temp & I2SR_IIF ? 1 : 0),
(temp & I2SR_RXAK ? 1 : 0));
#endif
- if (msgs[i].flags & I2C_M_RD)
- result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg);
- else {
- if (i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD)
- result = i2c_imx_dma_write(i2c_imx, &msgs[i]);
- else
- result = i2c_imx_write(i2c_imx, &msgs[i]);
+ if (msgs[i].flags & I2C_M_RD) {
+ result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg, atomic);
+ } else {
+ if (!atomic) {
+ if (i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD)
+ result = i2c_imx_dma_write(i2c_imx, &msgs[i]);
+ else
+ result = i2c_imx_write(i2c_imx, &msgs[i], atomic);
+ } else {
+ result = i2c_imx_write(i2c_imx, &msgs[i], atomic);
+ }
}
if (result)
goto fail0;
@@ -958,7 +995,7 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
fail0:
/* Stop I2C transfer */
- i2c_imx_stop(i2c_imx);
+ i2c_imx_stop(i2c_imx, atomic);
pm_runtime_mark_last_busy(i2c_imx->adapter.dev.parent);
pm_runtime_put_autosuspend(i2c_imx->adapter.dev.parent);
@@ -970,6 +1007,18 @@ out:
return (result < 0) ? result : num;
}
+static int i2c_imx_xfer(struct i2c_adapter *adapter,
+ struct i2c_msg *msgs, int num)
+{
+ return i2c_imx_xfer_common(adapter, msgs, num, false);
+}
+
+static int i2c_imx_xfer_atomic(struct i2c_adapter *adapter,
+ struct i2c_msg *msgs, int num)
+{
+ return i2c_imx_xfer_common(adapter, msgs, num, true);
+}
+
static void i2c_imx_prepare_recovery(struct i2c_adapter *adap)
{
struct imx_i2c_struct *i2c_imx;
@@ -1042,8 +1091,9 @@ static u32 i2c_imx_func(struct i2c_adapter *adapter)
}
static const struct i2c_algorithm i2c_imx_algo = {
- .master_xfer = i2c_imx_xfer,
- .functionality = i2c_imx_func,
+ .master_xfer = i2c_imx_xfer,
+ .master_xfer_atomic = i2c_imx_xfer_atomic,
+ .functionality = i2c_imx_func,
};
static int i2c_imx_probe(struct platform_device *pdev)
@@ -1121,6 +1171,14 @@ static int i2c_imx_probe(struct platform_device *pdev)
/* Set up platform driver data */
platform_set_drvdata(pdev, i2c_imx);
+ /*
+ * Driver's PM callbacks are safe to be called in atomic contexts.
+ * Providing this information to the PM subsystem is required for the
+ * 'master_xfer_atomic' implementation that calls PM routines in IRQ
+ * less/atomic contexts.
+ */
+ pm_runtime_irq_safe(&pdev->dev);
+
pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 63dedec0433d..e17054fdd9e0 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -1033,8 +1033,6 @@ static struct phy_driver ksphy_driver[] = {
.get_sset_count = kszphy_get_sset_count,
.get_strings = kszphy_get_strings,
.get_stats = kszphy_get_stats,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
}, {
.phy_id = PHY_ID_KSZ8041RNLI,
.phy_id_mask = MICREL_PHY_ID_MASK,
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index aabf22eaa6b9..b201ad54463f 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -31,6 +31,7 @@
#include <linux/reset.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
+#include <asm/opcodes.h>
#include "pcie-designware.h"
@@ -57,6 +58,7 @@ enum imx6_pcie_variants {
struct imx6_pcie_drvdata {
enum imx6_pcie_variants variant;
u32 flags;
+ int dbi_length;
};
struct imx6_pcie {
@@ -303,8 +305,14 @@ static int imx6q_pcie_abort_handler(unsigned long addr,
unsigned int fsr, struct pt_regs *regs)
{
unsigned long pc = instruction_pointer(regs);
- unsigned long instr = *(unsigned long *)pc;
- int reg = (instr >> 12) & 15;
+ unsigned long instr;
+ int reg;
+
+ if (user_mode(regs))
+ return 1;
+
+ instr = *(unsigned long *)pc;
+ reg = (instr >> 12) & 15;
/*
* If the instruction being executed was a read,
@@ -373,6 +381,59 @@ static int imx6_pcie_attach_pd(struct device *dev)
return 0;
}
+static int imx6q_pcie_abort_handler_thumb2(unsigned long addr,
+ unsigned int fsr, struct pt_regs *regs)
+{
+ unsigned long pc = instruction_pointer(regs);
+ unsigned long instr;
+
+ if (user_mode(regs))
+ return 1;
+
+ instr = __mem_to_opcode_thumb32(*(unsigned long *)pc);
+
+ if (__opcode_is_thumb32(instr)) {
+ /* Load word/byte and halfword immediate offset */
+ if ((instr & 0xff100000UL) == 0xf8100000UL) {
+ int reg = (instr >> 12) & 0xf;
+ unsigned long val;
+
+ if ((instr & 0x00700000UL) == 0x00100000UL)
+ val = 0xff;
+ else if ((instr & 0x00700000UL) == 0x00300000UL)
+ val = 0xffff;
+ else
+ val = 0xffffffffUL;
+
+ regs->uregs[reg] = val;
+ regs->ARM_pc += 4;
+ return 0;
+ }
+ } else {
+ instr = __mem_to_opcode_thumb16(*(unsigned long *)pc);
+
+ /* Load word/byte and halfword immediate offset */
+ if (((instr & 0xe800) == 0x6800) ||
+ ((instr & 0xf800) == 0x8800)) {
+ int reg = instr & 0x7;
+ unsigned long val;
+
+ if (instr & 0x1000)
+ val = 0xff;
+ else if (instr & 0x8000)
+ val = 0xffff;
+ else
+ val = 0xffffffffUL;
+
+ regs->uregs[reg] = val;
+ regs->ARM_pc += 2;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
{
struct device *dev = imx6_pcie->pci->dev;
@@ -1212,6 +1273,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
.variant = IMX6Q,
.flags = IMX6_PCIE_FLAG_IMX6_PHY |
IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE,
+ .dbi_length = 0x200,
},
[IMX6SX] = {
.variant = IMX6SX,
@@ -1254,9 +1316,42 @@ static struct platform_driver imx6_pcie_driver = {
.shutdown = imx6_pcie_shutdown,
};
+static void imx6_pcie_quirk(struct pci_dev *dev)
+{
+ struct pci_bus *bus = dev->bus;
+ struct pcie_port *pp = bus->sysdata;
+
+ /* Bus parent is the PCI bridge, its parent is this platform driver */
+ if (!bus->dev.parent || !bus->dev.parent->parent)
+ return;
+
+ /* Make sure we only quirk devices associated with this driver */
+ if (bus->dev.parent->parent->driver != &imx6_pcie_driver.driver)
+ return;
+
+ if (bus->number == pp->root_bus_nr) {
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
+
+ /*
+ * Limit config length to avoid the kernel reading beyond
+ * the register set and causing an abort on i.MX 6Quad
+ */
+ if (imx6_pcie->drvdata->dbi_length) {
+ dev->cfg_size = imx6_pcie->drvdata->dbi_length;
+ dev_info(&dev->dev, "Limiting cfg_size to %d\n",
+ dev->cfg_size);
+ }
+ }
+}
+DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_SYNOPSYS, 0xabcd,
+ PCI_CLASS_BRIDGE_PCI, 8, imx6_pcie_quirk);
+
static int __init imx6_pcie_init(void)
{
#ifdef CONFIG_ARM
+ bool thumb2 = IS_ENABLED(CONFIG_THUMB2_KERNEL);
+
/*
* Since probe() can be deferred we need to make sure that
* hook_fault_code is not called after __init memory is freed
@@ -1264,7 +1359,8 @@ static int __init imx6_pcie_init(void)
* we can install the handler here without risking it
* accessing some uninitialized driver state.
*/
- hook_fault_code(8, imx6q_pcie_abort_handler, SIGBUS, 0,
+ hook_fault_code(8, thumb2 ? imx6q_pcie_abort_handler_thumb2 :
+ imx6q_pcie_abort_handler, SIGBUS, 0,
"external abort on non-linefetch");
#endif
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index 255786f2e844..c43ad883548a 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -665,6 +665,7 @@ static const struct of_device_id spidev_dt_ids[] = {
{ .compatible = "lwn,bk4" },
{ .compatible = "dh,dhcom-board" },
{ .compatible = "menlo,m53cpld" },
+ { .compatible = "toradex,evalspi" },
{},
};
MODULE_DEVICE_TABLE(of, spidev_dt_ids);
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 57d6e6ba556e..49c622bf2fd3 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1957,7 +1957,7 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
* If the port was already initialised (eg, by a boot loader),
* try to determine the current setup.
*/
-static void __init
+static void
imx_uart_console_get_options(struct imx_port *sport, int *baud,
int *parity, int *bits)
{
@@ -2016,7 +2016,7 @@ imx_uart_console_get_options(struct imx_port *sport, int *baud,
}
}
-static int __init
+static int
imx_uart_console_setup(struct console *co, char *options)
{
struct imx_port *sport;
@@ -2076,7 +2076,7 @@ static struct console imx_uart_console = {
.data = &imx_uart_uart_driver,
};
-#define IMX_CONSOLE &imx_uart_console
+#define IMX_CONSOLE (&imx_uart_console)
#ifdef CONFIG_OF
static void imx_uart_console_early_putchar(struct uart_port *port, int ch)
@@ -2369,8 +2369,17 @@ static int imx_uart_probe(struct platform_device *pdev)
static int imx_uart_remove(struct platform_device *pdev)
{
struct imx_port *sport = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = uart_remove_one_port(&imx_uart_uart_driver, &sport->port);
- return uart_remove_one_port(&imx_uart_uart_driver, &sport->port);
+ if (IS_ENABLED(CONFIG_SERIAL_IMX_CONSOLE) && IMX_CONSOLE->index >= 0) {
+ clk_unprepare(sport->clk_ipg);
+ clk_unprepare(sport->clk_per);
+ IMX_CONSOLE->index = -1;
+ }
+
+ return ret;
}
static void imx_uart_restore_context(struct imx_port *sport)
diff --git a/mm/cma.c b/mm/cma.c
index 7fe0b8356775..58d6d64a7f2f 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -44,11 +44,13 @@ phys_addr_t cma_get_base(const struct cma *cma)
{
return PFN_PHYS(cma->base_pfn);
}
+EXPORT_SYMBOL_GPL(cma_get_base);
unsigned long cma_get_size(const struct cma *cma)
{
return cma->count << PAGE_SHIFT;
}
+EXPORT_SYMBOL_GPL(cma_get_size);
const char *cma_get_name(const struct cma *cma)
{
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 44f899b970c2..77768d325060 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1988,9 +1988,11 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
mutex_lock(&client_mutex);
for_each_card_prelinks(card, i, dai_link) {
ret = soc_init_dai_link(card, dai_link);
- if (ret) {
+ if (ret && ret != -EPROBE_DEFER) {
dev_err(card->dev, "ASoC: failed to init link %s: %d\n",
dai_link->name, ret);
+ }
+ if (ret) {
mutex_unlock(&client_mutex);
return ret;
}